From f7ac4fe49b4eb0e02516da23b2882c0fc4d012e4 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 1 Dec 2025 00:13:08 +0000
Subject: [PATCH 1/4] Initial plan


From 5e5cec2ddcaba4e03a53ea01b2dcee826cc58177 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 1 Dec 2025 00:19:36 +0000
Subject: [PATCH 2/4] Initial plan for log parser limits and lightweight
 summary

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
---
 .../daily-performance-summary.lock.yml        | 174 +++++++++---------
 .github/workflows/daily-team-status.lock.yml  |  52 ++++++
 .github/workflows/dev.lock.yml                |  23 +--
 3 files changed, 146 insertions(+), 103 deletions(-)

diff --git a/.github/workflows/daily-performance-summary.lock.yml b/.github/workflows/daily-performance-summary.lock.yml
index a2497923a7c..cc8f029fd76 100644
--- a/.github/workflows/daily-performance-summary.lock.yml
+++ b/.github/workflows/daily-performance-summary.lock.yml
@@ -2360,19 +2360,22 @@ jobs:
             function registerTool(name, description, inputSchema, handler) {
               tools[name] = { name, description, inputSchema, handler };
             }
-            registerTool("github-discussion-query", "Query GitHub discussions with jq filtering support. Without --jq, returns schema and data size info. Use --jq '.' to get all data, or specific jq expressions to filter.", {"properties":{"jq":{"description":"jq filter expression to apply to output. If not provided, returns schema info instead of full data.","type":"string"},"limit":{"description":"Maximum number of discussions to fetch (default: 30)","type":"number"},"repo":{"description":"Repository in owner/repo format (defaults to current repository)","type":"string"}},"type":"object"}, async (args) => {
+            registerTool("github-pr-query", "Query GitHub pull requests with jq filtering support. Without --jq, returns schema and data size info. Use --jq '.' to get all data, or specific jq expressions to filter.", {"properties":{"jq":{"description":"jq filter expression to apply to output. If not provided, returns schema info instead of full data.","type":"string"},"limit":{"description":"Maximum number of PRs to fetch (default: 30)","type":"number"},"repo":{"description":"Repository in owner/repo format (defaults to current repository)","type":"string"},"state":{"description":"PR state: open, closed, merged, all (default: open)","type":"string"}},"type":"object"}, async (args) => {
               try {
                 const env = { ...process.env };
+                if (args && args["jq"] !== undefined) {
+                  env["INPUT_JQ"] = typeof args["jq"] === "object" ? JSON.stringify(args["jq"]) : String(args["jq"]);
+                }
                 if (args && args["limit"] !== undefined) {
                   env["INPUT_LIMIT"] = typeof args["limit"] === "object" ? JSON.stringify(args["limit"]) : String(args["limit"]);
                 }
                 if (args && args["repo"] !== undefined) {
                   env["INPUT_REPO"] = typeof args["repo"] === "object" ? JSON.stringify(args["repo"]) : String(args["repo"]);
                 }
-                if (args && args["jq"] !== undefined) {
-                  env["INPUT_JQ"] = typeof args["jq"] === "object" ? JSON.stringify(args["jq"]) : String(args["jq"]);
+                if (args && args["state"] !== undefined) {
+                  env["INPUT_STATE"] = typeof args["state"] === "object" ? JSON.stringify(args["state"]) : String(args["state"]);
                 }
-                const scriptPath = path.join(__dirname, "github-discussion-query.sh");
+                const scriptPath = path.join(__dirname, "github-pr-query.sh");
                 const { stdout, stderr } = await execFileAsync("bash", [scriptPath], { env });
                 const output = stdout + (stderr ? "\nStderr: " + stderr : "");
                 return { content: [{ type: "text", text: output }] };
@@ -2380,22 +2383,19 @@ jobs:
                 return { content: [{ type: "text", text: "Error: " + (error instanceof Error ? error.message : String(error)) }], isError: true };
               }
             });
-            registerTool("github-issue-query", "Query GitHub issues with jq filtering support. Without --jq, returns schema and data size info. Use --jq '.' to get all data, or specific jq expressions to filter.", {"properties":{"jq":{"description":"jq filter expression to apply to output. If not provided, returns schema info instead of full data.","type":"string"},"limit":{"description":"Maximum number of issues to fetch (default: 30)","type":"number"},"repo":{"description":"Repository in owner/repo format (defaults to current repository)","type":"string"},"state":{"description":"Issue state: open, closed, all (default: open)","type":"string"}},"type":"object"}, async (args) => {
+            registerTool("github-discussion-query", "Query GitHub discussions with jq filtering support. Without --jq, returns schema and data size info. Use --jq '.' to get all data, or specific jq expressions to filter.", {"properties":{"jq":{"description":"jq filter expression to apply to output. If not provided, returns schema info instead of full data.","type":"string"},"limit":{"description":"Maximum number of discussions to fetch (default: 30)","type":"number"},"repo":{"description":"Repository in owner/repo format (defaults to current repository)","type":"string"}},"type":"object"}, async (args) => {
               try {
                 const env = { ...process.env };
-                if (args && args["jq"] !== undefined) {
-                  env["INPUT_JQ"] = typeof args["jq"] === "object" ? JSON.stringify(args["jq"]) : String(args["jq"]);
-                }
                 if (args && args["limit"] !== undefined) {
                   env["INPUT_LIMIT"] = typeof args["limit"] === "object" ? JSON.stringify(args["limit"]) : String(args["limit"]);
                 }
                 if (args && args["repo"] !== undefined) {
                   env["INPUT_REPO"] = typeof args["repo"] === "object" ? JSON.stringify(args["repo"]) : String(args["repo"]);
                 }
-                if (args && args["state"] !== undefined) {
-                  env["INPUT_STATE"] = typeof args["state"] === "object" ? JSON.stringify(args["state"]) : String(args["state"]);
+                if (args && args["jq"] !== undefined) {
+                  env["INPUT_JQ"] = typeof args["jq"] === "object" ? JSON.stringify(args["jq"]) : String(args["jq"]);
                 }
-                const scriptPath = path.join(__dirname, "github-issue-query.sh");
+                const scriptPath = path.join(__dirname, "github-discussion-query.sh");
                 const { stdout, stderr } = await execFileAsync("bash", [scriptPath], { env });
                 const output = stdout + (stderr ? "\nStderr: " + stderr : "");
                 return { content: [{ type: "text", text: output }] };
@@ -2403,7 +2403,7 @@ jobs:
                 return { content: [{ type: "text", text: "Error: " + (error instanceof Error ? error.message : String(error)) }], isError: true };
               }
             });
-            registerTool("github-pr-query", "Query GitHub pull requests with jq filtering support. Without --jq, returns schema and data size info. Use --jq '.' to get all data, or specific jq expressions to filter.", {"properties":{"jq":{"description":"jq filter expression to apply to output. If not provided, returns schema info instead of full data.","type":"string"},"limit":{"description":"Maximum number of PRs to fetch (default: 30)","type":"number"},"repo":{"description":"Repository in owner/repo format (defaults to current repository)","type":"string"},"state":{"description":"PR state: open, closed, merged, all (default: open)","type":"string"}},"type":"object"}, async (args) => {
+            registerTool("github-issue-query", "Query GitHub issues with jq filtering support. Without --jq, returns schema and data size info. Use --jq '.' to get all data, or specific jq expressions to filter.", {"properties":{"jq":{"description":"jq filter expression to apply to output. If not provided, returns schema info instead of full data.","type":"string"},"limit":{"description":"Maximum number of issues to fetch (default: 30)","type":"number"},"repo":{"description":"Repository in owner/repo format (defaults to current repository)","type":"string"},"state":{"description":"Issue state: open, closed, all (default: open)","type":"string"}},"type":"object"}, async (args) => {
               try {
                 const env = { ...process.env };
                 if (args && args["repo"] !== undefined) {
@@ -2418,7 +2418,7 @@ jobs:
                 if (args && args["limit"] !== undefined) {
                   env["INPUT_LIMIT"] = typeof args["limit"] === "object" ? JSON.stringify(args["limit"]) : String(args["limit"]);
                 }
-                const scriptPath = path.join(__dirname, "github-pr-query.sh");
+                const scriptPath = path.join(__dirname, "github-issue-query.sh");
                 const { stdout, stderr } = await execFileAsync("bash", [scriptPath], { env });
                 const output = stdout + (stderr ? "\nStderr: " + stderr : "");
                 return { content: [{ type: "text", text: output }] };
@@ -2534,10 +2534,10 @@ jobs:
             });
           EOFSI
           chmod +x /tmp/gh-aw/safe-inputs/mcp-server.cjs
-          cat > /tmp/gh-aw/safe-inputs/github-discussion-query.sh << 'EOFSH_github-discussion-query'
+          cat > /tmp/gh-aw/safe-inputs/github-pr-query.sh << 'EOFSH_github-pr-query'
           #!/bin/bash
-          # Auto-generated safe-input tool: github-discussion-query
-          # Query GitHub discussions with jq filtering support. Without --jq, returns schema and data size info. Use --jq '.' to get all data, or specific jq expressions to filter.
+          # Auto-generated safe-input tool: github-pr-query
+          # Query GitHub pull requests with jq filtering support. Without --jq, returns schema and data size info. Use --jq '.' to get all data, or specific jq expressions to filter.
           
           set -euo pipefail
           
@@ -2545,17 +2545,18 @@ jobs:
           
           # Default values
           REPO="${INPUT_REPO:-}"
+          STATE="${INPUT_STATE:-open}"
           LIMIT="${INPUT_LIMIT:-30}"
           JQ_FILTER="${INPUT_JQ:-}"
           
           # JSON fields to fetch
-          JSON_FIELDS="number,title,author,createdAt,updatedAt,body,category,labels,comments,answer,url"
+          JSON_FIELDS="number,title,state,author,createdAt,updatedAt,mergedAt,closedAt,headRefName,baseRefName,isDraft,reviewDecision,additions,deletions,changedFiles,labels,assignees,reviewRequests,url"
           
           # Build and execute gh command
           if [[ -n "$REPO" ]]; then
-            OUTPUT=$(gh discussion list --limit "$LIMIT" --json "$JSON_FIELDS" --repo "$REPO")
+            OUTPUT=$(gh pr list --state "$STATE" --limit "$LIMIT" --json "$JSON_FIELDS" --repo "$REPO")
           else
-            OUTPUT=$(gh discussion list --limit "$LIMIT" --json "$JSON_FIELDS")
+            OUTPUT=$(gh pr list --state "$STATE" --limit "$LIMIT" --json "$JSON_FIELDS")
           fi
           
           # Apply jq filter if specified
@@ -2581,40 +2582,49 @@ jobs:
             "data_size_bytes": $DATA_SIZE,
             "schema": {
               "type": "array",
-              "description": "Array of discussion objects",
+              "description": "Array of pull request objects",
               "item_fields": {
-                "number": "integer - Discussion number",
-                "title": "string - Discussion title",
+                "number": "integer - PR number",
+                "title": "string - PR title",
+                "state": "string - PR state (OPEN, CLOSED, MERGED)",
                 "author": "object - Author info with login field",
                 "createdAt": "string - ISO timestamp of creation",
                 "updatedAt": "string - ISO timestamp of last update",
-                "body": "string - Discussion body content",
-                "category": "object - Category info with name field",
+                "mergedAt": "string|null - ISO timestamp of merge",
+                "closedAt": "string|null - ISO timestamp of close",
+                "headRefName": "string - Source branch name",
+                "baseRefName": "string - Target branch name",
+                "isDraft": "boolean - Whether PR is a draft",
+                "reviewDecision": "string|null - Review decision (APPROVED, CHANGES_REQUESTED, REVIEW_REQUIRED)",
+                "additions": "integer - Lines added",
+                "deletions": "integer - Lines deleted",
+                "changedFiles": "integer - Number of files changed",
                 "labels": "array - Array of label objects with name field",
-                "comments": "object - Comments info with totalCount field",
-                "answer": "object|null - Accepted answer if exists",
-                "url": "string - Discussion URL"
+                "assignees": "array - Array of assignee objects with login field",
+                "reviewRequests": "array - Array of review request objects",
+                "url": "string - PR URL"
               }
             },
             "suggested_queries": [
               {"description": "Get all data", "query": "."},
-              {"description": "Get discussion numbers and titles", "query": ".[] | {number, title}"},
-              {"description": "Get discussions by author", "query": ".[] | select(.author.login == \"USERNAME\")"},
-              {"description": "Get discussions in category", "query": ".[] | select(.category.name == \"Ideas\")"},
-              {"description": "Get answered discussions", "query": ".[] | select(.answer != null)"},
-              {"description": "Get unanswered discussions", "query": ".[] | select(.answer == null) | {number, title, category: .category.name}"},
-              {"description": "Count by category", "query": "group_by(.category.name) | map({category: .[0].category.name, count: length})"}
+              {"description": "Get PR numbers and titles", "query": ".[] | {number, title}"},
+              {"description": "Get open PRs only", "query": ".[] | select(.state == \"OPEN\")"},
+              {"description": "Get merged PRs", "query": ".[] | select(.mergedAt != null)"},
+              {"description": "Get PRs by author", "query": ".[] | select(.author.login == \"USERNAME\")"},
+              {"description": "Get large PRs", "query": ".[] | select(.changedFiles > 10) | {number, title, changedFiles}"},
+              {"description": "Count by state", "query": "group_by(.state) | map({state: .[0].state, count: length})"}
             ]
           }
           EOF
           fi
           
-          EOFSH_github-discussion-query
-          chmod +x /tmp/gh-aw/safe-inputs/github-discussion-query.sh
-          cat > /tmp/gh-aw/safe-inputs/github-issue-query.sh << 'EOFSH_github-issue-query'
+          
+          EOFSH_github-pr-query
+          chmod +x /tmp/gh-aw/safe-inputs/github-pr-query.sh
+          cat > /tmp/gh-aw/safe-inputs/github-discussion-query.sh << 'EOFSH_github-discussion-query'
           #!/bin/bash
-          # Auto-generated safe-input tool: github-issue-query
-          # Query GitHub issues with jq filtering support. Without --jq, returns schema and data size info. Use --jq '.' to get all data, or specific jq expressions to filter.
+          # Auto-generated safe-input tool: github-discussion-query
+          # Query GitHub discussions with jq filtering support. Without --jq, returns schema and data size info. Use --jq '.' to get all data, or specific jq expressions to filter.
           
           set -euo pipefail
           
@@ -2622,18 +2632,17 @@ jobs:
           
           # Default values
           REPO="${INPUT_REPO:-}"
-          STATE="${INPUT_STATE:-open}"
           LIMIT="${INPUT_LIMIT:-30}"
           JQ_FILTER="${INPUT_JQ:-}"
           
           # JSON fields to fetch
-          JSON_FIELDS="number,title,state,author,createdAt,updatedAt,closedAt,body,labels,assignees,comments,milestone,url"
+          JSON_FIELDS="number,title,author,createdAt,updatedAt,body,category,labels,comments,answer,url"
           
           # Build and execute gh command
           if [[ -n "$REPO" ]]; then
-            OUTPUT=$(gh issue list --state "$STATE" --limit "$LIMIT" --json "$JSON_FIELDS" --repo "$REPO")
+            OUTPUT=$(gh discussion list --limit "$LIMIT" --json "$JSON_FIELDS" --repo "$REPO")
           else
-            OUTPUT=$(gh issue list --state "$STATE" --limit "$LIMIT" --json "$JSON_FIELDS")
+            OUTPUT=$(gh discussion list --limit "$LIMIT" --json "$JSON_FIELDS")
           fi
           
           # Apply jq filter if specified
@@ -2659,43 +2668,40 @@ jobs:
             "data_size_bytes": $DATA_SIZE,
             "schema": {
               "type": "array",
-              "description": "Array of issue objects",
+              "description": "Array of discussion objects",
               "item_fields": {
-                "number": "integer - Issue number",
-                "title": "string - Issue title",
-                "state": "string - Issue state (OPEN, CLOSED)",
+                "number": "integer - Discussion number",
+                "title": "string - Discussion title",
                 "author": "object - Author info with login field",
                 "createdAt": "string - ISO timestamp of creation",
                 "updatedAt": "string - ISO timestamp of last update",
-                "closedAt": "string|null - ISO timestamp of close",
-                "body": "string - Issue body content",
+                "body": "string - Discussion body content",
+                "category": "object - Category info with name field",
                 "labels": "array - Array of label objects with name field",
-                "assignees": "array - Array of assignee objects with login field",
                 "comments": "object - Comments info with totalCount field",
-                "milestone": "object|null - Milestone info with title field",
-                "url": "string - Issue URL"
+                "answer": "object|null - Accepted answer if exists",
+                "url": "string - Discussion URL"
               }
             },
             "suggested_queries": [
               {"description": "Get all data", "query": "."},
-              {"description": "Get issue numbers and titles", "query": ".[] | {number, title}"},
-              {"description": "Get open issues only", "query": ".[] | select(.state == \"OPEN\")"},
-              {"description": "Get issues by author", "query": ".[] | select(.author.login == \"USERNAME\")"},
-              {"description": "Get issues with label", "query": ".[] | select(.labels | map(.name) | index(\"bug\"))"},
-              {"description": "Get issues with many comments", "query": ".[] | select(.comments.totalCount > 5) | {number, title, comments: .comments.totalCount}"},
-              {"description": "Count by state", "query": "group_by(.state) | map({state: .[0].state, count: length})"}
+              {"description": "Get discussion numbers and titles", "query": ".[] | {number, title}"},
+              {"description": "Get discussions by author", "query": ".[] | select(.author.login == \"USERNAME\")"},
+              {"description": "Get discussions in category", "query": ".[] | select(.category.name == \"Ideas\")"},
+              {"description": "Get answered discussions", "query": ".[] | select(.answer != null)"},
+              {"description": "Get unanswered discussions", "query": ".[] | select(.answer == null) | {number, title, category: .category.name}"},
+              {"description": "Count by category", "query": "group_by(.category.name) | map({category: .[0].category.name, count: length})"}
             ]
           }
           EOF
           fi
           
-          
-          EOFSH_github-issue-query
-          chmod +x /tmp/gh-aw/safe-inputs/github-issue-query.sh
-          cat > /tmp/gh-aw/safe-inputs/github-pr-query.sh << 'EOFSH_github-pr-query'
+          EOFSH_github-discussion-query
+          chmod +x /tmp/gh-aw/safe-inputs/github-discussion-query.sh
+          cat > /tmp/gh-aw/safe-inputs/github-issue-query.sh << 'EOFSH_github-issue-query'
           #!/bin/bash
-          # Auto-generated safe-input tool: github-pr-query
-          # Query GitHub pull requests with jq filtering support. Without --jq, returns schema and data size info. Use --jq '.' to get all data, or specific jq expressions to filter.
+          # Auto-generated safe-input tool: github-issue-query
+          # Query GitHub issues with jq filtering support. Without --jq, returns schema and data size info. Use --jq '.' to get all data, or specific jq expressions to filter.
           
           set -euo pipefail
           
@@ -2708,13 +2714,13 @@ jobs:
           JQ_FILTER="${INPUT_JQ:-}"
           
           # JSON fields to fetch
-          JSON_FIELDS="number,title,state,author,createdAt,updatedAt,mergedAt,closedAt,headRefName,baseRefName,isDraft,reviewDecision,additions,deletions,changedFiles,labels,assignees,reviewRequests,url"
+          JSON_FIELDS="number,title,state,author,createdAt,updatedAt,closedAt,body,labels,assignees,comments,milestone,url"
           
           # Build and execute gh command
           if [[ -n "$REPO" ]]; then
-            OUTPUT=$(gh pr list --state "$STATE" --limit "$LIMIT" --json "$JSON_FIELDS" --repo "$REPO")
+            OUTPUT=$(gh issue list --state "$STATE" --limit "$LIMIT" --json "$JSON_FIELDS" --repo "$REPO")
           else
-            OUTPUT=$(gh pr list --state "$STATE" --limit "$LIMIT" --json "$JSON_FIELDS")
+            OUTPUT=$(gh issue list --state "$STATE" --limit "$LIMIT" --json "$JSON_FIELDS")
           fi
           
           # Apply jq filter if specified
@@ -2740,36 +2746,30 @@ jobs:
             "data_size_bytes": $DATA_SIZE,
             "schema": {
               "type": "array",
-              "description": "Array of pull request objects",
+              "description": "Array of issue objects",
               "item_fields": {
-                "number": "integer - PR number",
-                "title": "string - PR title",
-                "state": "string - PR state (OPEN, CLOSED, MERGED)",
+                "number": "integer - Issue number",
+                "title": "string - Issue title",
+                "state": "string - Issue state (OPEN, CLOSED)",
                 "author": "object - Author info with login field",
                 "createdAt": "string - ISO timestamp of creation",
                 "updatedAt": "string - ISO timestamp of last update",
-                "mergedAt": "string|null - ISO timestamp of merge",
                 "closedAt": "string|null - ISO timestamp of close",
-                "headRefName": "string - Source branch name",
-                "baseRefName": "string - Target branch name",
-                "isDraft": "boolean - Whether PR is a draft",
-                "reviewDecision": "string|null - Review decision (APPROVED, CHANGES_REQUESTED, REVIEW_REQUIRED)",
-                "additions": "integer - Lines added",
-                "deletions": "integer - Lines deleted",
-                "changedFiles": "integer - Number of files changed",
+                "body": "string - Issue body content",
                 "labels": "array - Array of label objects with name field",
                 "assignees": "array - Array of assignee objects with login field",
-                "reviewRequests": "array - Array of review request objects",
-                "url": "string - PR URL"
+                "comments": "object - Comments info with totalCount field",
+                "milestone": "object|null - Milestone info with title field",
+                "url": "string - Issue URL"
               }
             },
             "suggested_queries": [
               {"description": "Get all data", "query": "."},
-              {"description": "Get PR numbers and titles", "query": ".[] | {number, title}"},
-              {"description": "Get open PRs only", "query": ".[] | select(.state == \"OPEN\")"},
-              {"description": "Get merged PRs", "query": ".[] | select(.mergedAt != null)"},
-              {"description": "Get PRs by author", "query": ".[] | select(.author.login == \"USERNAME\")"},
-              {"description": "Get large PRs", "query": ".[] | select(.changedFiles > 10) | {number, title, changedFiles}"},
+              {"description": "Get issue numbers and titles", "query": ".[] | {number, title}"},
+              {"description": "Get open issues only", "query": ".[] | select(.state == \"OPEN\")"},
+              {"description": "Get issues by author", "query": ".[] | select(.author.login == \"USERNAME\")"},
+              {"description": "Get issues with label", "query": ".[] | select(.labels | map(.name) | index(\"bug\"))"},
+              {"description": "Get issues with many comments", "query": ".[] | select(.comments.totalCount > 5) | {number, title, comments: .comments.totalCount}"},
               {"description": "Count by state", "query": "group_by(.state) | map({state: .[0].state, count: length})"}
             ]
           }
@@ -2777,8 +2777,8 @@ jobs:
           fi
           
           
-          EOFSH_github-pr-query
-          chmod +x /tmp/gh-aw/safe-inputs/github-pr-query.sh
+          EOFSH_github-issue-query
+          chmod +x /tmp/gh-aw/safe-inputs/github-issue-query.sh
           
       - name: Setup MCPs
         env:
diff --git a/.github/workflows/daily-team-status.lock.yml b/.github/workflows/daily-team-status.lock.yml
index 3d79cd3561c..422d7349572 100644
--- a/.github/workflows/daily-team-status.lock.yml
+++ b/.github/workflows/daily-team-status.lock.yml
@@ -3165,6 +3165,24 @@ jobs:
               }
               return toolName;
             }
+            function isLikelyCustomAgent(toolName) {
+              if (!toolName || typeof toolName !== "string") {
+                return false;
+              }
+              if (!toolName.includes("-")) {
+                return false;
+              }
+              if (toolName.includes("__")) {
+                return false;
+              }
+              if (toolName.toLowerCase().startsWith("safe")) {
+                return false;
+              }
+              if (!/^[a-z0-9]+(-[a-z0-9]+)+$/.test(toolName)) {
+                return false;
+              }
+              return true;
+            }
             function generateConversationMarkdown(logEntries, options) {
               const { formatToolCallback, formatInitCallback, summaryTracker } = options;
               const toolUsePairs = new Map(); 
@@ -3379,19 +3397,53 @@ jobs:
                 const categories = {
                   Core: [],
                   "File Operations": [],
+                  Builtin: [],
+                  "Safe Outputs": [],
+                  "Safe Inputs": [],
                   "Git/GitHub": [],
                   MCP: [],
+                  "Custom Agents": [],
                   Other: [],
                 };
+                const builtinTools = [
+                  "bash",
+                  "write_bash",
+                  "read_bash",
+                  "stop_bash",
+                  "list_bash",
+                  "grep",
+                  "glob",
+                  "view",
+                  "create",
+                  "edit",
+                  "store_memory",
+                  "code_review",
+                  "codeql_checker",
+                  "report_progress",
+                  "report_intent",
+                  "gh-advisory-database",
+                ];
+                const internalTools = ["fetch_copilot_cli_documentation"];
                 for (const tool of initEntry.tools) {
+                  const toolLower = tool.toLowerCase();
                   if (["Task", "Bash", "BashOutput", "KillBash", "ExitPlanMode"].includes(tool)) {
                     categories["Core"].push(tool);
                   } else if (["Read", "Edit", "MultiEdit", "Write", "LS", "Grep", "Glob", "NotebookEdit"].includes(tool)) {
                     categories["File Operations"].push(tool);
+                  } else if (builtinTools.includes(toolLower) || internalTools.includes(toolLower)) {
+                    categories["Builtin"].push(tool);
+                  } else if (tool.startsWith("safeoutputs-") || tool.startsWith("safe_outputs-")) {
+                    const toolName = tool.replace(/^safeoutputs-|^safe_outputs-/, "");
+                    categories["Safe Outputs"].push(toolName);
+                  } else if (tool.startsWith("safeinputs-") || tool.startsWith("safe_inputs-")) {
+                    const toolName = tool.replace(/^safeinputs-|^safe_inputs-/, "");
+                    categories["Safe Inputs"].push(toolName);
                   } else if (tool.startsWith("mcp__github__")) {
                     categories["Git/GitHub"].push(formatMcpName(tool));
                   } else if (tool.startsWith("mcp__") || ["ListMcpResourcesTool", "ReadMcpResourceTool"].includes(tool)) {
                     categories["MCP"].push(tool.startsWith("mcp__") ? formatMcpName(tool) : tool);
+                  } else if (isLikelyCustomAgent(tool)) {
+                    categories["Custom Agents"].push(tool);
                   } else {
                     categories["Other"].push(tool);
                   }
diff --git a/.github/workflows/dev.lock.yml b/.github/workflows/dev.lock.yml
index 8960c770799..b7f0888b72a 100644
--- a/.github/workflows/dev.lock.yml
+++ b/.github/workflows/dev.lock.yml
@@ -1480,18 +1480,18 @@ jobs:
             function registerTool(name, description, inputSchema, handler) {
               tools[name] = { name, description, inputSchema, handler };
             }
-            registerTool("test-js-string", "Test JavaScript string operations", {"properties":{"text":{"description":"Input text","type":"string"}},"required":["text"],"type":"object"}, async (args) => {
+            registerTool("test-js-math", "Test JavaScript math operations", {"properties":{"a":{"description":"First number","type":"number"},"b":{"description":"Second number","type":"number"}},"required":["a","b"],"type":"object"}, async (args) => {
               try {
-                const toolModule = require("./test-js-string.cjs");
+                const toolModule = require("./test-js-math.cjs");
                 const result = await toolModule.execute(args || {});
                 return { content: [{ type: "text", text: typeof result === "string" ? result : JSON.stringify(result, null, 2) }] };
               } catch (error) {
                 return { content: [{ type: "text", text: "Error: " + (error instanceof Error ? error.message : String(error)) }], isError: true };
               }
             });
-            registerTool("test-js-math", "Test JavaScript math operations", {"properties":{"a":{"description":"First number","type":"number"},"b":{"description":"Second number","type":"number"}},"required":["a","b"],"type":"object"}, async (args) => {
+            registerTool("test-js-string", "Test JavaScript string operations", {"properties":{"text":{"description":"Input text","type":"string"}},"required":["text"],"type":"object"}, async (args) => {
               try {
-                const toolModule = require("./test-js-math.cjs");
+                const toolModule = require("./test-js-string.cjs");
                 const result = await toolModule.execute(args || {});
                 return { content: [{ type: "text", text: typeof result === "string" ? result : JSON.stringify(result, null, 2) }] };
               } catch (error) {
@@ -1501,6 +1501,9 @@ jobs:
             registerTool("fetch-pr-data", "Fetches pull request data from GitHub using gh CLI. Returns JSON array of PRs with fields: number, title, author, headRefName, createdAt, state, url, body, labels, updatedAt, closedAt, mergedAt", {"properties":{"days":{"default":30,"description":"Number of days to look back (default: 30)","type":"number"},"limit":{"default":100,"description":"Maximum number of PRs to fetch (default: 100)","type":"number"},"repo":{"description":"Repository in owner/repo format (defaults to current repository)","type":"string"},"search":{"description":"Search query for filtering PRs (e.g., 'head:copilot/' for Copilot PRs)","type":"string"},"state":{"default":"all","description":"PR state filter: open, closed, merged, or all (default: all)","type":"string"}},"type":"object"}, async (args) => {
               try {
                 const env = { ...process.env };
+                if (args && args["state"] !== undefined) {
+                  env["INPUT_STATE"] = typeof args["state"] === "object" ? JSON.stringify(args["state"]) : String(args["state"]);
+                }
                 if (args && args["days"] !== undefined) {
                   env["INPUT_DAYS"] = typeof args["days"] === "object" ? JSON.stringify(args["days"]) : String(args["days"]);
                 }
@@ -1513,9 +1516,6 @@ jobs:
                 if (args && args["search"] !== undefined) {
                   env["INPUT_SEARCH"] = typeof args["search"] === "object" ? JSON.stringify(args["search"]) : String(args["search"]);
                 }
-                if (args && args["state"] !== undefined) {
-                  env["INPUT_STATE"] = typeof args["state"] === "object" ? JSON.stringify(args["state"]) : String(args["state"]);
-                }
                 const scriptPath = path.join(__dirname, "fetch-pr-data.sh");
                 const { stdout, stderr } = await execFileAsync("bash", [scriptPath], { env });
                 const output = stdout + (stderr ? "\nStderr: " + stderr : "");
@@ -1652,15 +1652,6 @@ jobs:
             }
             module.exports = { execute };
           EOFJS_test-js-string
-          cat > /tmp/gh-aw/safe-inputs/test-js-math.cjs << 'EOFJS_test-js-math'
-            async function execute(inputs) {
-              const { a, b } = inputs || {};
-              const sum = a + b;
-              const product = a * b;
-              return { sum, product, inputs: { a, b } };
-            }
-            module.exports = { execute };
-          EOFJS_test-js-math
           cat > /tmp/gh-aw/safe-inputs/fetch-pr-data.sh << 'EOFSH_fetch-pr-data'
           #!/bin/bash
           # Auto-generated safe-input tool: fetch-pr-data

From 3900272a254fa3a3ebd74e175b124dcdd816c2ec Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 1 Dec 2025 00:57:21 +0000
Subject: [PATCH 3/4] Implement log parser limits and lightweight summary
 generation

- Update MAX_STEP_SUMMARY_SIZE from 8MB to 1000KB (1,024,000 bytes)
- Update MAX_TOOL_OUTPUT_LENGTH from 500 to 256 characters
- Add generatePlainTextSummary function for lightweight console output
- Update log parser bootstrap to generate plain text summary for core.info
- Update Copilot and Claude parsers to return logEntries with result
- Update tests for new constant values and return types
- Fix TestNeutralToolsIntegration to use YAML key patterns instead of broad string match

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
---
 .github/workflows/ai-triage-campaign.lock.yml | 257 +++++++----
 .github/workflows/archie.lock.yml             | 257 +++++++----
 .github/workflows/artifacts-summary.lock.yml  | 257 +++++++----
 .github/workflows/audit-workflows.lock.yml    | 252 +++++++---
 .github/workflows/blog-auditor.lock.yml       | 252 +++++++---
 .github/workflows/brave.lock.yml              | 257 +++++++----
 .../breaking-change-checker.lock.yml          | 257 +++++++----
 .github/workflows/changeset.lock.yml          | 248 +++++++---
 .github/workflows/ci-doctor.lock.yml          | 257 +++++++----
 .../cli-consistency-checker.lock.yml          | 257 +++++++----
 .../workflows/cli-version-checker.lock.yml    | 257 +++++++----
 .github/workflows/cloclo.lock.yml             | 252 +++++++---
 .../workflows/close-old-discussions.lock.yml  | 248 +++++++---
 .../commit-changes-analyzer.lock.yml          | 252 +++++++---
 .../workflows/copilot-agent-analysis.lock.yml | 252 +++++++---
 .../copilot-pr-nlp-analysis.lock.yml          | 257 +++++++----
 .../copilot-pr-prompt-analysis.lock.yml       | 257 +++++++----
 .../copilot-session-insights.lock.yml         | 252 +++++++---
 .github/workflows/craft.lock.yml              | 257 +++++++----
 .github/workflows/daily-code-metrics.lock.yml | 252 +++++++---
 .github/workflows/daily-doc-updater.lock.yml  | 252 +++++++---
 .github/workflows/daily-fact.lock.yml         | 248 +++++++---
 .github/workflows/daily-file-diet.lock.yml    | 248 +++++++---
 .../workflows/daily-firewall-report.lock.yml  | 257 +++++++----
 .../workflows/daily-issues-report.lock.yml    | 248 +++++++---
 .../daily-malicious-code-scan.lock.yml        | 257 +++++++----
 .../daily-multi-device-docs-tester.lock.yml   | 252 +++++++---
 .github/workflows/daily-news.lock.yml         | 257 +++++++----
 .../daily-performance-summary.lock.yml        | 432 +++++++++++-------
 .../workflows/daily-repo-chronicle.lock.yml   | 257 +++++++----
 .github/workflows/daily-team-status.lock.yml  | 257 +++++++----
 .github/workflows/deep-report.lock.yml        | 248 +++++++---
 .../workflows/dependabot-go-checker.lock.yml  | 257 +++++++----
 .github/workflows/dev-hawk.lock.yml           | 257 +++++++----
 .github/workflows/dev.lock.yml                | 284 ++++++++----
 .../developer-docs-consolidator.lock.yml      | 252 +++++++---
 .github/workflows/dictation-prompt.lock.yml   | 257 +++++++----
 .github/workflows/docs-noob-tester.lock.yml   | 257 +++++++----
 .../duplicate-code-detector.lock.yml          | 248 +++++++---
 .../example-permissions-warning.lock.yml      | 257 +++++++----
 .../example-workflow-analyzer.lock.yml        | 252 +++++++---
 .github/workflows/firewall.lock.yml           | 257 +++++++----
 .../github-mcp-structural-analysis.lock.yml   | 252 +++++++---
 .../github-mcp-tools-report.lock.yml          | 252 +++++++---
 .../workflows/glossary-maintainer.lock.yml    | 257 +++++++----
 .github/workflows/go-fan.lock.yml             | 252 +++++++---
 .github/workflows/go-logger.lock.yml          | 252 +++++++---
 .../workflows/go-pattern-detector.lock.yml    | 252 +++++++---
 .github/workflows/grumpy-reviewer.lock.yml    | 257 +++++++----
 .../workflows/instructions-janitor.lock.yml   | 252 +++++++---
 .github/workflows/issue-arborist.lock.yml     | 248 +++++++---
 .github/workflows/issue-monster.lock.yml      | 257 +++++++----
 .github/workflows/issue-triage-agent.lock.yml | 257 +++++++----
 .github/workflows/lockfile-stats.lock.yml     | 252 +++++++---
 .github/workflows/mcp-inspector.lock.yml      | 257 +++++++----
 .github/workflows/mergefest.lock.yml          | 257 +++++++----
 .../workflows/notion-issue-summary.lock.yml   | 257 +++++++----
 .github/workflows/pdf-summary.lock.yml        | 257 +++++++----
 .github/workflows/plan.lock.yml               | 257 +++++++----
 .github/workflows/poem-bot.lock.yml           | 257 +++++++----
 .../workflows/pr-nitpick-reviewer.lock.yml    | 257 +++++++----
 .../prompt-clustering-analysis.lock.yml       | 252 +++++++---
 .github/workflows/python-data-charts.lock.yml | 257 +++++++----
 .github/workflows/q.lock.yml                  | 257 +++++++----
 .github/workflows/release.lock.yml            | 257 +++++++----
 .github/workflows/repo-tree-map.lock.yml      | 257 +++++++----
 .../repository-quality-improver.lock.yml      | 257 +++++++----
 .github/workflows/research.lock.yml           | 257 +++++++----
 .github/workflows/safe-output-health.lock.yml | 252 +++++++---
 .../schema-consistency-checker.lock.yml       | 252 +++++++---
 .github/workflows/scout.lock.yml              | 252 +++++++---
 .github/workflows/security-fix-pr.lock.yml    | 252 +++++++---
 .../semantic-function-refactor.lock.yml       | 252 +++++++---
 .github/workflows/smoke-claude.lock.yml       | 252 +++++++---
 .github/workflows/smoke-codex.lock.yml        | 248 +++++++---
 .../smoke-copilot-no-firewall.lock.yml        | 257 +++++++----
 .github/workflows/smoke-copilot.lock.yml      | 257 +++++++----
 .github/workflows/smoke-detector.lock.yml     | 252 +++++++---
 .../smoke-srt-custom-config.lock.yml          | 257 +++++++----
 .github/workflows/smoke-srt.lock.yml          | 257 +++++++----
 .../workflows/static-analysis-report.lock.yml | 252 +++++++---
 .github/workflows/super-linter.lock.yml       | 257 +++++++----
 .../workflows/technical-doc-writer.lock.yml   | 257 +++++++----
 .../workflows/test-firewall-escape.lock.yml   | 257 +++++++----
 .github/workflows/tidy.lock.yml               | 257 +++++++----
 .github/workflows/typist.lock.yml             | 252 +++++++---
 .github/workflows/unbloat-docs.lock.yml       | 252 +++++++---
 .github/workflows/video-analyzer.lock.yml     | 257 +++++++----
 .../workflows/weekly-issue-summary.lock.yml   | 257 +++++++----
 docs/src/content/docs/labs.mdx                |   4 +-
 pkg/workflow/js/log_parser_bootstrap.cjs      |  25 +-
 pkg/workflow/js/log_parser_bootstrap.test.cjs |  43 +-
 pkg/workflow/js/log_parser_shared.cjs         | 136 +++++-
 pkg/workflow/js/log_parser_shared.test.cjs    | 153 ++++++-
 pkg/workflow/js/parse_claude_log.cjs          |   6 +-
 pkg/workflow/js/parse_claude_log.test.cjs     |   6 +-
 pkg/workflow/js/parse_copilot_log.cjs         |   9 +-
 pkg/workflow/js/parse_copilot_log.test.cjs    | 214 ++++-----
 .../neutral_tools_integration_test.go         |  11 +-
 .../test_data/expected_claude_baseline.md     |  16 +-
 100 files changed, 16356 insertions(+), 7116 deletions(-)

diff --git a/.github/workflows/ai-triage-campaign.lock.yml b/.github/workflows/ai-triage-campaign.lock.yml
index a64d293d696..808e2dd01d6 100644
--- a/.github/workflows/ai-triage-campaign.lock.yml
+++ b/.github/workflows/ai-triage-campaign.lock.yml
@@ -2949,81 +2949,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/.agent/logs/
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -3596,6 +3523,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCopilotLog,
@@ -3637,7 +3735,7 @@ jobs:
                   }
                 }
                 if (!logEntries) {
-                  return "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n";
+                  return { markdown: "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n", logEntries: [] };
                 }
                 const conversationResult = generateConversationMarkdown(logEntries, {
                   formatToolCallback: (toolUse, toolResult) => formatToolUse(toolUse, toolResult, { includeDetailedParameters: true }),
@@ -3689,10 +3787,13 @@ jobs:
                     return "";
                   },
                 });
-                return markdown;
+                return { markdown, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
-                return `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`;
+                return {
+                  markdown: `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
+                  logEntries: [],
+                };
               }
             }
             function scanForToolErrors(logContent) {
diff --git a/.github/workflows/archie.lock.yml b/.github/workflows/archie.lock.yml
index c5948c89a86..35e5aaf794e 100644
--- a/.github/workflows/archie.lock.yml
+++ b/.github/workflows/archie.lock.yml
@@ -4590,81 +4590,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/.agent/logs/
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5237,6 +5164,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCopilotLog,
@@ -5278,7 +5376,7 @@ jobs:
                   }
                 }
                 if (!logEntries) {
-                  return "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n";
+                  return { markdown: "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n", logEntries: [] };
                 }
                 const conversationResult = generateConversationMarkdown(logEntries, {
                   formatToolCallback: (toolUse, toolResult) => formatToolUse(toolUse, toolResult, { includeDetailedParameters: true }),
@@ -5330,10 +5428,13 @@ jobs:
                     return "";
                   },
                 });
-                return markdown;
+                return { markdown, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
-                return `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`;
+                return {
+                  markdown: `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
+                  logEntries: [],
+                };
               }
             }
             function scanForToolErrors(logContent) {
diff --git a/.github/workflows/artifacts-summary.lock.yml b/.github/workflows/artifacts-summary.lock.yml
index 50ce81b8411..2b95f800d88 100644
--- a/.github/workflows/artifacts-summary.lock.yml
+++ b/.github/workflows/artifacts-summary.lock.yml
@@ -3119,81 +3119,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/.agent/logs/
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -3766,6 +3693,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCopilotLog,
@@ -3807,7 +3905,7 @@ jobs:
                   }
                 }
                 if (!logEntries) {
-                  return "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n";
+                  return { markdown: "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n", logEntries: [] };
                 }
                 const conversationResult = generateConversationMarkdown(logEntries, {
                   formatToolCallback: (toolUse, toolResult) => formatToolUse(toolUse, toolResult, { includeDetailedParameters: true }),
@@ -3859,10 +3957,13 @@ jobs:
                     return "";
                   },
                 });
-                return markdown;
+                return { markdown, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
-                return `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`;
+                return {
+                  markdown: `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
+                  logEntries: [],
+                };
               }
             }
             function scanForToolErrors(logContent) {
diff --git a/.github/workflows/audit-workflows.lock.yml b/.github/workflows/audit-workflows.lock.yml
index 5092a7d8fd1..674bf7cf235 100644
--- a/.github/workflows/audit-workflows.lock.yml
+++ b/.github/workflows/audit-workflows.lock.yml
@@ -4592,81 +4592,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/agent-stdio.log
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5239,6 +5166,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseClaudeLog,
@@ -5254,6 +5352,7 @@ jobs:
                     markdown: "## Agent Log Summary\n\nLog format not recognized as Claude JSON array or JSONL.\n",
                     mcpFailures: [],
                     maxTurnsHit: false,
+                    logEntries: [],
                   };
                 }
                 const mcpFailures = [];
@@ -5307,13 +5406,14 @@ jobs:
                     maxTurnsHit = true;
                   }
                 }
-                return { markdown, mcpFailures, maxTurnsHit };
+                return { markdown, mcpFailures, maxTurnsHit, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
                 return {
                   markdown: `## Agent Log Summary\n\nError parsing Claude log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
                   mcpFailures: [],
                   maxTurnsHit: false,
+                  logEntries: [],
                 };
               }
             }
diff --git a/.github/workflows/blog-auditor.lock.yml b/.github/workflows/blog-auditor.lock.yml
index 3dcf7d4caa6..136f3f507b4 100644
--- a/.github/workflows/blog-auditor.lock.yml
+++ b/.github/workflows/blog-auditor.lock.yml
@@ -3716,81 +3716,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/agent-stdio.log
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4363,6 +4290,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseClaudeLog,
@@ -4378,6 +4476,7 @@ jobs:
                     markdown: "## Agent Log Summary\n\nLog format not recognized as Claude JSON array or JSONL.\n",
                     mcpFailures: [],
                     maxTurnsHit: false,
+                    logEntries: [],
                   };
                 }
                 const mcpFailures = [];
@@ -4431,13 +4530,14 @@ jobs:
                     maxTurnsHit = true;
                   }
                 }
-                return { markdown, mcpFailures, maxTurnsHit };
+                return { markdown, mcpFailures, maxTurnsHit, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
                 return {
                   markdown: `## Agent Log Summary\n\nError parsing Claude log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
                   mcpFailures: [],
                   maxTurnsHit: false,
+                  logEntries: [],
                 };
               }
             }
diff --git a/.github/workflows/brave.lock.yml b/.github/workflows/brave.lock.yml
index b3c67f2d7e8..2d21cb78880 100644
--- a/.github/workflows/brave.lock.yml
+++ b/.github/workflows/brave.lock.yml
@@ -4381,81 +4381,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/.agent/logs/
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5028,6 +4955,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCopilotLog,
@@ -5069,7 +5167,7 @@ jobs:
                   }
                 }
                 if (!logEntries) {
-                  return "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n";
+                  return { markdown: "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n", logEntries: [] };
                 }
                 const conversationResult = generateConversationMarkdown(logEntries, {
                   formatToolCallback: (toolUse, toolResult) => formatToolUse(toolUse, toolResult, { includeDetailedParameters: true }),
@@ -5121,10 +5219,13 @@ jobs:
                     return "";
                   },
                 });
-                return markdown;
+                return { markdown, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
-                return `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`;
+                return {
+                  markdown: `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
+                  logEntries: [],
+                };
               }
             }
             function scanForToolErrors(logContent) {
diff --git a/.github/workflows/breaking-change-checker.lock.yml b/.github/workflows/breaking-change-checker.lock.yml
index af2e3d0e498..085e94cd7a5 100644
--- a/.github/workflows/breaking-change-checker.lock.yml
+++ b/.github/workflows/breaking-change-checker.lock.yml
@@ -3185,81 +3185,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/.agent/logs/
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -3832,6 +3759,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCopilotLog,
@@ -3873,7 +3971,7 @@ jobs:
                   }
                 }
                 if (!logEntries) {
-                  return "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n";
+                  return { markdown: "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n", logEntries: [] };
                 }
                 const conversationResult = generateConversationMarkdown(logEntries, {
                   formatToolCallback: (toolUse, toolResult) => formatToolUse(toolUse, toolResult, { includeDetailedParameters: true }),
@@ -3925,10 +4023,13 @@ jobs:
                     return "";
                   },
                 });
-                return markdown;
+                return { markdown, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
-                return `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`;
+                return {
+                  markdown: `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
+                  logEntries: [],
+                };
               }
             }
             function scanForToolErrors(logContent) {
diff --git a/.github/workflows/changeset.lock.yml b/.github/workflows/changeset.lock.yml
index 0a861a68383..6a30840ec6e 100644
--- a/.github/workflows/changeset.lock.yml
+++ b/.github/workflows/changeset.lock.yml
@@ -4089,81 +4089,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/agent-stdio.log
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4736,6 +4663,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCodexLog,
diff --git a/.github/workflows/ci-doctor.lock.yml b/.github/workflows/ci-doctor.lock.yml
index 05b65a1d5b9..ba75567993b 100644
--- a/.github/workflows/ci-doctor.lock.yml
+++ b/.github/workflows/ci-doctor.lock.yml
@@ -3855,81 +3855,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/.agent/logs/
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4502,6 +4429,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCopilotLog,
@@ -4543,7 +4641,7 @@ jobs:
                   }
                 }
                 if (!logEntries) {
-                  return "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n";
+                  return { markdown: "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n", logEntries: [] };
                 }
                 const conversationResult = generateConversationMarkdown(logEntries, {
                   formatToolCallback: (toolUse, toolResult) => formatToolUse(toolUse, toolResult, { includeDetailedParameters: true }),
@@ -4595,10 +4693,13 @@ jobs:
                     return "";
                   },
                 });
-                return markdown;
+                return { markdown, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
-                return `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`;
+                return {
+                  markdown: `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
+                  logEntries: [],
+                };
               }
             }
             function scanForToolErrors(logContent) {
diff --git a/.github/workflows/cli-consistency-checker.lock.yml b/.github/workflows/cli-consistency-checker.lock.yml
index 8136db1348f..752186da19d 100644
--- a/.github/workflows/cli-consistency-checker.lock.yml
+++ b/.github/workflows/cli-consistency-checker.lock.yml
@@ -3199,81 +3199,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/.agent/logs/
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -3846,6 +3773,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCopilotLog,
@@ -3887,7 +3985,7 @@ jobs:
                   }
                 }
                 if (!logEntries) {
-                  return "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n";
+                  return { markdown: "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n", logEntries: [] };
                 }
                 const conversationResult = generateConversationMarkdown(logEntries, {
                   formatToolCallback: (toolUse, toolResult) => formatToolUse(toolUse, toolResult, { includeDetailedParameters: true }),
@@ -3939,10 +4037,13 @@ jobs:
                     return "";
                   },
                 });
-                return markdown;
+                return { markdown, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
-                return `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`;
+                return {
+                  markdown: `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
+                  logEntries: [],
+                };
               }
             }
             function scanForToolErrors(logContent) {
diff --git a/.github/workflows/cli-version-checker.lock.yml b/.github/workflows/cli-version-checker.lock.yml
index 75d09afea0d..310910ce1b2 100644
--- a/.github/workflows/cli-version-checker.lock.yml
+++ b/.github/workflows/cli-version-checker.lock.yml
@@ -3528,81 +3528,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/.agent/logs/
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4175,6 +4102,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCopilotLog,
@@ -4216,7 +4314,7 @@ jobs:
                   }
                 }
                 if (!logEntries) {
-                  return "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n";
+                  return { markdown: "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n", logEntries: [] };
                 }
                 const conversationResult = generateConversationMarkdown(logEntries, {
                   formatToolCallback: (toolUse, toolResult) => formatToolUse(toolUse, toolResult, { includeDetailedParameters: true }),
@@ -4268,10 +4366,13 @@ jobs:
                     return "";
                   },
                 });
-                return markdown;
+                return { markdown, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
-                return `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`;
+                return {
+                  markdown: `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
+                  logEntries: [],
+                };
               }
             }
             function scanForToolErrors(logContent) {
diff --git a/.github/workflows/cloclo.lock.yml b/.github/workflows/cloclo.lock.yml
index b93c3201e07..2c36c1f00da 100644
--- a/.github/workflows/cloclo.lock.yml
+++ b/.github/workflows/cloclo.lock.yml
@@ -5164,81 +5164,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/agent-stdio.log
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5811,6 +5738,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseClaudeLog,
@@ -5826,6 +5924,7 @@ jobs:
                     markdown: "## Agent Log Summary\n\nLog format not recognized as Claude JSON array or JSONL.\n",
                     mcpFailures: [],
                     maxTurnsHit: false,
+                    logEntries: [],
                   };
                 }
                 const mcpFailures = [];
@@ -5879,13 +5978,14 @@ jobs:
                     maxTurnsHit = true;
                   }
                 }
-                return { markdown, mcpFailures, maxTurnsHit };
+                return { markdown, mcpFailures, maxTurnsHit, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
                 return {
                   markdown: `## Agent Log Summary\n\nError parsing Claude log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
                   mcpFailures: [],
                   maxTurnsHit: false,
+                  logEntries: [],
                 };
               }
             }
diff --git a/.github/workflows/close-old-discussions.lock.yml b/.github/workflows/close-old-discussions.lock.yml
index e4fb79db0f6..8a949b06294 100644
--- a/.github/workflows/close-old-discussions.lock.yml
+++ b/.github/workflows/close-old-discussions.lock.yml
@@ -3358,81 +3358,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/agent-stdio.log
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4005,6 +3932,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCodexLog,
diff --git a/.github/workflows/commit-changes-analyzer.lock.yml b/.github/workflows/commit-changes-analyzer.lock.yml
index ada41b0e860..f79eeb22b9b 100644
--- a/.github/workflows/commit-changes-analyzer.lock.yml
+++ b/.github/workflows/commit-changes-analyzer.lock.yml
@@ -3598,81 +3598,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/agent-stdio.log
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4245,6 +4172,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseClaudeLog,
@@ -4260,6 +4358,7 @@ jobs:
                     markdown: "## Agent Log Summary\n\nLog format not recognized as Claude JSON array or JSONL.\n",
                     mcpFailures: [],
                     maxTurnsHit: false,
+                    logEntries: [],
                   };
                 }
                 const mcpFailures = [];
@@ -4313,13 +4412,14 @@ jobs:
                     maxTurnsHit = true;
                   }
                 }
-                return { markdown, mcpFailures, maxTurnsHit };
+                return { markdown, mcpFailures, maxTurnsHit, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
                 return {
                   markdown: `## Agent Log Summary\n\nError parsing Claude log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
                   mcpFailures: [],
                   maxTurnsHit: false,
+                  logEntries: [],
                 };
               }
             }
diff --git a/.github/workflows/copilot-agent-analysis.lock.yml b/.github/workflows/copilot-agent-analysis.lock.yml
index 2a5c45a798d..9588b7c522f 100644
--- a/.github/workflows/copilot-agent-analysis.lock.yml
+++ b/.github/workflows/copilot-agent-analysis.lock.yml
@@ -4279,81 +4279,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/agent-stdio.log
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4926,6 +4853,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseClaudeLog,
@@ -4941,6 +5039,7 @@ jobs:
                     markdown: "## Agent Log Summary\n\nLog format not recognized as Claude JSON array or JSONL.\n",
                     mcpFailures: [],
                     maxTurnsHit: false,
+                    logEntries: [],
                   };
                 }
                 const mcpFailures = [];
@@ -4994,13 +5093,14 @@ jobs:
                     maxTurnsHit = true;
                   }
                 }
-                return { markdown, mcpFailures, maxTurnsHit };
+                return { markdown, mcpFailures, maxTurnsHit, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
                 return {
                   markdown: `## Agent Log Summary\n\nError parsing Claude log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
                   mcpFailures: [],
                   maxTurnsHit: false,
+                  logEntries: [],
                 };
               }
             }
diff --git a/.github/workflows/copilot-pr-nlp-analysis.lock.yml b/.github/workflows/copilot-pr-nlp-analysis.lock.yml
index 5f7c1423dce..0d46fb68e41 100644
--- a/.github/workflows/copilot-pr-nlp-analysis.lock.yml
+++ b/.github/workflows/copilot-pr-nlp-analysis.lock.yml
@@ -4670,81 +4670,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/.agent/logs/
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5317,6 +5244,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCopilotLog,
@@ -5358,7 +5456,7 @@ jobs:
                   }
                 }
                 if (!logEntries) {
-                  return "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n";
+                  return { markdown: "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n", logEntries: [] };
                 }
                 const conversationResult = generateConversationMarkdown(logEntries, {
                   formatToolCallback: (toolUse, toolResult) => formatToolUse(toolUse, toolResult, { includeDetailedParameters: true }),
@@ -5410,10 +5508,13 @@ jobs:
                     return "";
                   },
                 });
-                return markdown;
+                return { markdown, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
-                return `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`;
+                return {
+                  markdown: `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
+                  logEntries: [],
+                };
               }
             }
             function scanForToolErrors(logContent) {
diff --git a/.github/workflows/copilot-pr-prompt-analysis.lock.yml b/.github/workflows/copilot-pr-prompt-analysis.lock.yml
index fc528386358..fb25f3589d4 100644
--- a/.github/workflows/copilot-pr-prompt-analysis.lock.yml
+++ b/.github/workflows/copilot-pr-prompt-analysis.lock.yml
@@ -3759,81 +3759,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/.agent/logs/
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4406,6 +4333,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCopilotLog,
@@ -4447,7 +4545,7 @@ jobs:
                   }
                 }
                 if (!logEntries) {
-                  return "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n";
+                  return { markdown: "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n", logEntries: [] };
                 }
                 const conversationResult = generateConversationMarkdown(logEntries, {
                   formatToolCallback: (toolUse, toolResult) => formatToolUse(toolUse, toolResult, { includeDetailedParameters: true }),
@@ -4499,10 +4597,13 @@ jobs:
                     return "";
                   },
                 });
-                return markdown;
+                return { markdown, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
-                return `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`;
+                return {
+                  markdown: `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
+                  logEntries: [],
+                };
               }
             }
             function scanForToolErrors(logContent) {
diff --git a/.github/workflows/copilot-session-insights.lock.yml b/.github/workflows/copilot-session-insights.lock.yml
index 7a3cc680677..c130b86c664 100644
--- a/.github/workflows/copilot-session-insights.lock.yml
+++ b/.github/workflows/copilot-session-insights.lock.yml
@@ -6219,81 +6219,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/agent-stdio.log
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -6866,6 +6793,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseClaudeLog,
@@ -6881,6 +6979,7 @@ jobs:
                     markdown: "## Agent Log Summary\n\nLog format not recognized as Claude JSON array or JSONL.\n",
                     mcpFailures: [],
                     maxTurnsHit: false,
+                    logEntries: [],
                   };
                 }
                 const mcpFailures = [];
@@ -6934,13 +7033,14 @@ jobs:
                     maxTurnsHit = true;
                   }
                 }
-                return { markdown, mcpFailures, maxTurnsHit };
+                return { markdown, mcpFailures, maxTurnsHit, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
                 return {
                   markdown: `## Agent Log Summary\n\nError parsing Claude log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
                   mcpFailures: [],
                   maxTurnsHit: false,
+                  logEntries: [],
                 };
               }
             }
diff --git a/.github/workflows/craft.lock.yml b/.github/workflows/craft.lock.yml
index a06420c9232..4120d4045d3 100644
--- a/.github/workflows/craft.lock.yml
+++ b/.github/workflows/craft.lock.yml
@@ -4727,81 +4727,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/.agent/logs/
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5374,6 +5301,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCopilotLog,
@@ -5415,7 +5513,7 @@ jobs:
                   }
                 }
                 if (!logEntries) {
-                  return "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n";
+                  return { markdown: "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n", logEntries: [] };
                 }
                 const conversationResult = generateConversationMarkdown(logEntries, {
                   formatToolCallback: (toolUse, toolResult) => formatToolUse(toolUse, toolResult, { includeDetailedParameters: true }),
@@ -5467,10 +5565,13 @@ jobs:
                     return "";
                   },
                 });
-                return markdown;
+                return { markdown, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
-                return `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`;
+                return {
+                  markdown: `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
+                  logEntries: [],
+                };
               }
             }
             function scanForToolErrors(logContent) {
diff --git a/.github/workflows/daily-code-metrics.lock.yml b/.github/workflows/daily-code-metrics.lock.yml
index e21afb6a7cb..cb036317054 100644
--- a/.github/workflows/daily-code-metrics.lock.yml
+++ b/.github/workflows/daily-code-metrics.lock.yml
@@ -4729,81 +4729,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/agent-stdio.log
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5376,6 +5303,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseClaudeLog,
@@ -5391,6 +5489,7 @@ jobs:
                     markdown: "## Agent Log Summary\n\nLog format not recognized as Claude JSON array or JSONL.\n",
                     mcpFailures: [],
                     maxTurnsHit: false,
+                    logEntries: [],
                   };
                 }
                 const mcpFailures = [];
@@ -5444,13 +5543,14 @@ jobs:
                     maxTurnsHit = true;
                   }
                 }
-                return { markdown, mcpFailures, maxTurnsHit };
+                return { markdown, mcpFailures, maxTurnsHit, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
                 return {
                   markdown: `## Agent Log Summary\n\nError parsing Claude log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
                   mcpFailures: [],
                   maxTurnsHit: false,
+                  logEntries: [],
                 };
               }
             }
diff --git a/.github/workflows/daily-doc-updater.lock.yml b/.github/workflows/daily-doc-updater.lock.yml
index 3d2cc1a979e..c258aafcdc1 100644
--- a/.github/workflows/daily-doc-updater.lock.yml
+++ b/.github/workflows/daily-doc-updater.lock.yml
@@ -3396,81 +3396,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/agent-stdio.log
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4043,6 +3970,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseClaudeLog,
@@ -4058,6 +4156,7 @@ jobs:
                     markdown: "## Agent Log Summary\n\nLog format not recognized as Claude JSON array or JSONL.\n",
                     mcpFailures: [],
                     maxTurnsHit: false,
+                    logEntries: [],
                   };
                 }
                 const mcpFailures = [];
@@ -4111,13 +4210,14 @@ jobs:
                     maxTurnsHit = true;
                   }
                 }
-                return { markdown, mcpFailures, maxTurnsHit };
+                return { markdown, mcpFailures, maxTurnsHit, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
                 return {
                   markdown: `## Agent Log Summary\n\nError parsing Claude log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
                   mcpFailures: [],
                   maxTurnsHit: false,
+                  logEntries: [],
                 };
               }
             }
diff --git a/.github/workflows/daily-fact.lock.yml b/.github/workflows/daily-fact.lock.yml
index 3af34599f1f..91eb0d308ef 100644
--- a/.github/workflows/daily-fact.lock.yml
+++ b/.github/workflows/daily-fact.lock.yml
@@ -3474,81 +3474,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/agent-stdio.log
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4121,6 +4048,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCodexLog,
diff --git a/.github/workflows/daily-file-diet.lock.yml b/.github/workflows/daily-file-diet.lock.yml
index 6041fde5b67..3b8fe350aa0 100644
--- a/.github/workflows/daily-file-diet.lock.yml
+++ b/.github/workflows/daily-file-diet.lock.yml
@@ -3439,81 +3439,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/agent-stdio.log
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4086,6 +4013,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCodexLog,
diff --git a/.github/workflows/daily-firewall-report.lock.yml b/.github/workflows/daily-firewall-report.lock.yml
index f9e3e9cc46e..9e3ca2a4743 100644
--- a/.github/workflows/daily-firewall-report.lock.yml
+++ b/.github/workflows/daily-firewall-report.lock.yml
@@ -4172,81 +4172,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/.agent/logs/
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4819,6 +4746,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCopilotLog,
@@ -4860,7 +4958,7 @@ jobs:
                   }
                 }
                 if (!logEntries) {
-                  return "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n";
+                  return { markdown: "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n", logEntries: [] };
                 }
                 const conversationResult = generateConversationMarkdown(logEntries, {
                   formatToolCallback: (toolUse, toolResult) => formatToolUse(toolUse, toolResult, { includeDetailedParameters: true }),
@@ -4912,10 +5010,13 @@ jobs:
                     return "";
                   },
                 });
-                return markdown;
+                return { markdown, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
-                return `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`;
+                return {
+                  markdown: `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
+                  logEntries: [],
+                };
               }
             }
             function scanForToolErrors(logContent) {
diff --git a/.github/workflows/daily-issues-report.lock.yml b/.github/workflows/daily-issues-report.lock.yml
index 0844eafb31f..30661d6c803 100644
--- a/.github/workflows/daily-issues-report.lock.yml
+++ b/.github/workflows/daily-issues-report.lock.yml
@@ -4952,81 +4952,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/agent-stdio.log
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5599,6 +5526,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCodexLog,
diff --git a/.github/workflows/daily-malicious-code-scan.lock.yml b/.github/workflows/daily-malicious-code-scan.lock.yml
index cc2c5af3f37..513413cee8f 100644
--- a/.github/workflows/daily-malicious-code-scan.lock.yml
+++ b/.github/workflows/daily-malicious-code-scan.lock.yml
@@ -3424,81 +3424,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/.agent/logs/
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4071,6 +3998,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCopilotLog,
@@ -4112,7 +4210,7 @@ jobs:
                   }
                 }
                 if (!logEntries) {
-                  return "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n";
+                  return { markdown: "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n", logEntries: [] };
                 }
                 const conversationResult = generateConversationMarkdown(logEntries, {
                   formatToolCallback: (toolUse, toolResult) => formatToolUse(toolUse, toolResult, { includeDetailedParameters: true }),
@@ -4164,10 +4262,13 @@ jobs:
                     return "";
                   },
                 });
-                return markdown;
+                return { markdown, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
-                return `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`;
+                return {
+                  markdown: `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
+                  logEntries: [],
+                };
               }
             }
             function scanForToolErrors(logContent) {
diff --git a/.github/workflows/daily-multi-device-docs-tester.lock.yml b/.github/workflows/daily-multi-device-docs-tester.lock.yml
index 56f5171cdb6..64a5a26693b 100644
--- a/.github/workflows/daily-multi-device-docs-tester.lock.yml
+++ b/.github/workflows/daily-multi-device-docs-tester.lock.yml
@@ -3298,81 +3298,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/agent-stdio.log
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -3945,6 +3872,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseClaudeLog,
@@ -3960,6 +4058,7 @@ jobs:
                     markdown: "## Agent Log Summary\n\nLog format not recognized as Claude JSON array or JSONL.\n",
                     mcpFailures: [],
                     maxTurnsHit: false,
+                    logEntries: [],
                   };
                 }
                 const mcpFailures = [];
@@ -4013,13 +4112,14 @@ jobs:
                     maxTurnsHit = true;
                   }
                 }
-                return { markdown, mcpFailures, maxTurnsHit };
+                return { markdown, mcpFailures, maxTurnsHit, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
                 return {
                   markdown: `## Agent Log Summary\n\nError parsing Claude log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
                   mcpFailures: [],
                   maxTurnsHit: false,
+                  logEntries: [],
                 };
               }
             }
diff --git a/.github/workflows/daily-news.lock.yml b/.github/workflows/daily-news.lock.yml
index 8970372b478..879de379dc5 100644
--- a/.github/workflows/daily-news.lock.yml
+++ b/.github/workflows/daily-news.lock.yml
@@ -4727,81 +4727,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/.agent/logs/
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5374,6 +5301,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCopilotLog,
@@ -5415,7 +5513,7 @@ jobs:
                   }
                 }
                 if (!logEntries) {
-                  return "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n";
+                  return { markdown: "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n", logEntries: [] };
                 }
                 const conversationResult = generateConversationMarkdown(logEntries, {
                   formatToolCallback: (toolUse, toolResult) => formatToolUse(toolUse, toolResult, { includeDetailedParameters: true }),
@@ -5467,10 +5565,13 @@ jobs:
                     return "";
                   },
                 });
-                return markdown;
+                return { markdown, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
-                return `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`;
+                return {
+                  markdown: `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
+                  logEntries: [],
+                };
               }
             }
             function scanForToolErrors(logContent) {
diff --git a/.github/workflows/daily-performance-summary.lock.yml b/.github/workflows/daily-performance-summary.lock.yml
index cc8f029fd76..c155695f7cd 100644
--- a/.github/workflows/daily-performance-summary.lock.yml
+++ b/.github/workflows/daily-performance-summary.lock.yml
@@ -2360,7 +2360,7 @@ jobs:
             function registerTool(name, description, inputSchema, handler) {
               tools[name] = { name, description, inputSchema, handler };
             }
-            registerTool("github-pr-query", "Query GitHub pull requests with jq filtering support. Without --jq, returns schema and data size info. Use --jq '.' to get all data, or specific jq expressions to filter.", {"properties":{"jq":{"description":"jq filter expression to apply to output. If not provided, returns schema info instead of full data.","type":"string"},"limit":{"description":"Maximum number of PRs to fetch (default: 30)","type":"number"},"repo":{"description":"Repository in owner/repo format (defaults to current repository)","type":"string"},"state":{"description":"PR state: open, closed, merged, all (default: open)","type":"string"}},"type":"object"}, async (args) => {
+            registerTool("github-discussion-query", "Query GitHub discussions with jq filtering support. Without --jq, returns schema and data size info. Use --jq '.' to get all data, or specific jq expressions to filter.", {"properties":{"jq":{"description":"jq filter expression to apply to output. If not provided, returns schema info instead of full data.","type":"string"},"limit":{"description":"Maximum number of discussions to fetch (default: 30)","type":"number"},"repo":{"description":"Repository in owner/repo format (defaults to current repository)","type":"string"}},"type":"object"}, async (args) => {
               try {
                 const env = { ...process.env };
                 if (args && args["jq"] !== undefined) {
@@ -2372,10 +2372,7 @@ jobs:
                 if (args && args["repo"] !== undefined) {
                   env["INPUT_REPO"] = typeof args["repo"] === "object" ? JSON.stringify(args["repo"]) : String(args["repo"]);
                 }
-                if (args && args["state"] !== undefined) {
-                  env["INPUT_STATE"] = typeof args["state"] === "object" ? JSON.stringify(args["state"]) : String(args["state"]);
-                }
-                const scriptPath = path.join(__dirname, "github-pr-query.sh");
+                const scriptPath = path.join(__dirname, "github-discussion-query.sh");
                 const { stdout, stderr } = await execFileAsync("bash", [scriptPath], { env });
                 const output = stdout + (stderr ? "\nStderr: " + stderr : "");
                 return { content: [{ type: "text", text: output }] };
@@ -2383,19 +2380,22 @@ jobs:
                 return { content: [{ type: "text", text: "Error: " + (error instanceof Error ? error.message : String(error)) }], isError: true };
               }
             });
-            registerTool("github-discussion-query", "Query GitHub discussions with jq filtering support. Without --jq, returns schema and data size info. Use --jq '.' to get all data, or specific jq expressions to filter.", {"properties":{"jq":{"description":"jq filter expression to apply to output. If not provided, returns schema info instead of full data.","type":"string"},"limit":{"description":"Maximum number of discussions to fetch (default: 30)","type":"number"},"repo":{"description":"Repository in owner/repo format (defaults to current repository)","type":"string"}},"type":"object"}, async (args) => {
+            registerTool("github-issue-query", "Query GitHub issues with jq filtering support. Without --jq, returns schema and data size info. Use --jq '.' to get all data, or specific jq expressions to filter.", {"properties":{"jq":{"description":"jq filter expression to apply to output. If not provided, returns schema info instead of full data.","type":"string"},"limit":{"description":"Maximum number of issues to fetch (default: 30)","type":"number"},"repo":{"description":"Repository in owner/repo format (defaults to current repository)","type":"string"},"state":{"description":"Issue state: open, closed, all (default: open)","type":"string"}},"type":"object"}, async (args) => {
               try {
                 const env = { ...process.env };
-                if (args && args["limit"] !== undefined) {
-                  env["INPUT_LIMIT"] = typeof args["limit"] === "object" ? JSON.stringify(args["limit"]) : String(args["limit"]);
-                }
                 if (args && args["repo"] !== undefined) {
                   env["INPUT_REPO"] = typeof args["repo"] === "object" ? JSON.stringify(args["repo"]) : String(args["repo"]);
                 }
+                if (args && args["state"] !== undefined) {
+                  env["INPUT_STATE"] = typeof args["state"] === "object" ? JSON.stringify(args["state"]) : String(args["state"]);
+                }
                 if (args && args["jq"] !== undefined) {
                   env["INPUT_JQ"] = typeof args["jq"] === "object" ? JSON.stringify(args["jq"]) : String(args["jq"]);
                 }
-                const scriptPath = path.join(__dirname, "github-discussion-query.sh");
+                if (args && args["limit"] !== undefined) {
+                  env["INPUT_LIMIT"] = typeof args["limit"] === "object" ? JSON.stringify(args["limit"]) : String(args["limit"]);
+                }
+                const scriptPath = path.join(__dirname, "github-issue-query.sh");
                 const { stdout, stderr } = await execFileAsync("bash", [scriptPath], { env });
                 const output = stdout + (stderr ? "\nStderr: " + stderr : "");
                 return { content: [{ type: "text", text: output }] };
@@ -2403,22 +2403,22 @@ jobs:
                 return { content: [{ type: "text", text: "Error: " + (error instanceof Error ? error.message : String(error)) }], isError: true };
               }
             });
-            registerTool("github-issue-query", "Query GitHub issues with jq filtering support. Without --jq, returns schema and data size info. Use --jq '.' to get all data, or specific jq expressions to filter.", {"properties":{"jq":{"description":"jq filter expression to apply to output. If not provided, returns schema info instead of full data.","type":"string"},"limit":{"description":"Maximum number of issues to fetch (default: 30)","type":"number"},"repo":{"description":"Repository in owner/repo format (defaults to current repository)","type":"string"},"state":{"description":"Issue state: open, closed, all (default: open)","type":"string"}},"type":"object"}, async (args) => {
+            registerTool("github-pr-query", "Query GitHub pull requests with jq filtering support. Without --jq, returns schema and data size info. Use --jq '.' to get all data, or specific jq expressions to filter.", {"properties":{"jq":{"description":"jq filter expression to apply to output. If not provided, returns schema info instead of full data.","type":"string"},"limit":{"description":"Maximum number of PRs to fetch (default: 30)","type":"number"},"repo":{"description":"Repository in owner/repo format (defaults to current repository)","type":"string"},"state":{"description":"PR state: open, closed, merged, all (default: open)","type":"string"}},"type":"object"}, async (args) => {
               try {
                 const env = { ...process.env };
-                if (args && args["repo"] !== undefined) {
-                  env["INPUT_REPO"] = typeof args["repo"] === "object" ? JSON.stringify(args["repo"]) : String(args["repo"]);
-                }
-                if (args && args["state"] !== undefined) {
-                  env["INPUT_STATE"] = typeof args["state"] === "object" ? JSON.stringify(args["state"]) : String(args["state"]);
-                }
                 if (args && args["jq"] !== undefined) {
                   env["INPUT_JQ"] = typeof args["jq"] === "object" ? JSON.stringify(args["jq"]) : String(args["jq"]);
                 }
                 if (args && args["limit"] !== undefined) {
                   env["INPUT_LIMIT"] = typeof args["limit"] === "object" ? JSON.stringify(args["limit"]) : String(args["limit"]);
                 }
-                const scriptPath = path.join(__dirname, "github-issue-query.sh");
+                if (args && args["repo"] !== undefined) {
+                  env["INPUT_REPO"] = typeof args["repo"] === "object" ? JSON.stringify(args["repo"]) : String(args["repo"]);
+                }
+                if (args && args["state"] !== undefined) {
+                  env["INPUT_STATE"] = typeof args["state"] === "object" ? JSON.stringify(args["state"]) : String(args["state"]);
+                }
+                const scriptPath = path.join(__dirname, "github-pr-query.sh");
                 const { stdout, stderr } = await execFileAsync("bash", [scriptPath], { env });
                 const output = stdout + (stderr ? "\nStderr: " + stderr : "");
                 return { content: [{ type: "text", text: output }] };
@@ -2534,10 +2534,10 @@ jobs:
             });
           EOFSI
           chmod +x /tmp/gh-aw/safe-inputs/mcp-server.cjs
-          cat > /tmp/gh-aw/safe-inputs/github-pr-query.sh << 'EOFSH_github-pr-query'
+          cat > /tmp/gh-aw/safe-inputs/github-discussion-query.sh << 'EOFSH_github-discussion-query'
           #!/bin/bash
-          # Auto-generated safe-input tool: github-pr-query
-          # Query GitHub pull requests with jq filtering support. Without --jq, returns schema and data size info. Use --jq '.' to get all data, or specific jq expressions to filter.
+          # Auto-generated safe-input tool: github-discussion-query
+          # Query GitHub discussions with jq filtering support. Without --jq, returns schema and data size info. Use --jq '.' to get all data, or specific jq expressions to filter.
           
           set -euo pipefail
           
@@ -2545,18 +2545,17 @@ jobs:
           
           # Default values
           REPO="${INPUT_REPO:-}"
-          STATE="${INPUT_STATE:-open}"
           LIMIT="${INPUT_LIMIT:-30}"
           JQ_FILTER="${INPUT_JQ:-}"
           
           # JSON fields to fetch
-          JSON_FIELDS="number,title,state,author,createdAt,updatedAt,mergedAt,closedAt,headRefName,baseRefName,isDraft,reviewDecision,additions,deletions,changedFiles,labels,assignees,reviewRequests,url"
+          JSON_FIELDS="number,title,author,createdAt,updatedAt,body,category,labels,comments,answer,url"
           
           # Build and execute gh command
           if [[ -n "$REPO" ]]; then
-            OUTPUT=$(gh pr list --state "$STATE" --limit "$LIMIT" --json "$JSON_FIELDS" --repo "$REPO")
+            OUTPUT=$(gh discussion list --limit "$LIMIT" --json "$JSON_FIELDS" --repo "$REPO")
           else
-            OUTPUT=$(gh pr list --state "$STATE" --limit "$LIMIT" --json "$JSON_FIELDS")
+            OUTPUT=$(gh discussion list --limit "$LIMIT" --json "$JSON_FIELDS")
           fi
           
           # Apply jq filter if specified
@@ -2582,49 +2581,40 @@ jobs:
             "data_size_bytes": $DATA_SIZE,
             "schema": {
               "type": "array",
-              "description": "Array of pull request objects",
+              "description": "Array of discussion objects",
               "item_fields": {
-                "number": "integer - PR number",
-                "title": "string - PR title",
-                "state": "string - PR state (OPEN, CLOSED, MERGED)",
+                "number": "integer - Discussion number",
+                "title": "string - Discussion title",
                 "author": "object - Author info with login field",
                 "createdAt": "string - ISO timestamp of creation",
                 "updatedAt": "string - ISO timestamp of last update",
-                "mergedAt": "string|null - ISO timestamp of merge",
-                "closedAt": "string|null - ISO timestamp of close",
-                "headRefName": "string - Source branch name",
-                "baseRefName": "string - Target branch name",
-                "isDraft": "boolean - Whether PR is a draft",
-                "reviewDecision": "string|null - Review decision (APPROVED, CHANGES_REQUESTED, REVIEW_REQUIRED)",
-                "additions": "integer - Lines added",
-                "deletions": "integer - Lines deleted",
-                "changedFiles": "integer - Number of files changed",
+                "body": "string - Discussion body content",
+                "category": "object - Category info with name field",
                 "labels": "array - Array of label objects with name field",
-                "assignees": "array - Array of assignee objects with login field",
-                "reviewRequests": "array - Array of review request objects",
-                "url": "string - PR URL"
+                "comments": "object - Comments info with totalCount field",
+                "answer": "object|null - Accepted answer if exists",
+                "url": "string - Discussion URL"
               }
             },
             "suggested_queries": [
               {"description": "Get all data", "query": "."},
-              {"description": "Get PR numbers and titles", "query": ".[] | {number, title}"},
-              {"description": "Get open PRs only", "query": ".[] | select(.state == \"OPEN\")"},
-              {"description": "Get merged PRs", "query": ".[] | select(.mergedAt != null)"},
-              {"description": "Get PRs by author", "query": ".[] | select(.author.login == \"USERNAME\")"},
-              {"description": "Get large PRs", "query": ".[] | select(.changedFiles > 10) | {number, title, changedFiles}"},
-              {"description": "Count by state", "query": "group_by(.state) | map({state: .[0].state, count: length})"}
+              {"description": "Get discussion numbers and titles", "query": ".[] | {number, title}"},
+              {"description": "Get discussions by author", "query": ".[] | select(.author.login == \"USERNAME\")"},
+              {"description": "Get discussions in category", "query": ".[] | select(.category.name == \"Ideas\")"},
+              {"description": "Get answered discussions", "query": ".[] | select(.answer != null)"},
+              {"description": "Get unanswered discussions", "query": ".[] | select(.answer == null) | {number, title, category: .category.name}"},
+              {"description": "Count by category", "query": "group_by(.category.name) | map({category: .[0].category.name, count: length})"}
             ]
           }
           EOF
           fi
           
-          
-          EOFSH_github-pr-query
-          chmod +x /tmp/gh-aw/safe-inputs/github-pr-query.sh
-          cat > /tmp/gh-aw/safe-inputs/github-discussion-query.sh << 'EOFSH_github-discussion-query'
+          EOFSH_github-discussion-query
+          chmod +x /tmp/gh-aw/safe-inputs/github-discussion-query.sh
+          cat > /tmp/gh-aw/safe-inputs/github-issue-query.sh << 'EOFSH_github-issue-query'
           #!/bin/bash
-          # Auto-generated safe-input tool: github-discussion-query
-          # Query GitHub discussions with jq filtering support. Without --jq, returns schema and data size info. Use --jq '.' to get all data, or specific jq expressions to filter.
+          # Auto-generated safe-input tool: github-issue-query
+          # Query GitHub issues with jq filtering support. Without --jq, returns schema and data size info. Use --jq '.' to get all data, or specific jq expressions to filter.
           
           set -euo pipefail
           
@@ -2632,17 +2622,18 @@ jobs:
           
           # Default values
           REPO="${INPUT_REPO:-}"
+          STATE="${INPUT_STATE:-open}"
           LIMIT="${INPUT_LIMIT:-30}"
           JQ_FILTER="${INPUT_JQ:-}"
           
           # JSON fields to fetch
-          JSON_FIELDS="number,title,author,createdAt,updatedAt,body,category,labels,comments,answer,url"
+          JSON_FIELDS="number,title,state,author,createdAt,updatedAt,closedAt,body,labels,assignees,comments,milestone,url"
           
           # Build and execute gh command
           if [[ -n "$REPO" ]]; then
-            OUTPUT=$(gh discussion list --limit "$LIMIT" --json "$JSON_FIELDS" --repo "$REPO")
+            OUTPUT=$(gh issue list --state "$STATE" --limit "$LIMIT" --json "$JSON_FIELDS" --repo "$REPO")
           else
-            OUTPUT=$(gh discussion list --limit "$LIMIT" --json "$JSON_FIELDS")
+            OUTPUT=$(gh issue list --state "$STATE" --limit "$LIMIT" --json "$JSON_FIELDS")
           fi
           
           # Apply jq filter if specified
@@ -2668,40 +2659,43 @@ jobs:
             "data_size_bytes": $DATA_SIZE,
             "schema": {
               "type": "array",
-              "description": "Array of discussion objects",
+              "description": "Array of issue objects",
               "item_fields": {
-                "number": "integer - Discussion number",
-                "title": "string - Discussion title",
+                "number": "integer - Issue number",
+                "title": "string - Issue title",
+                "state": "string - Issue state (OPEN, CLOSED)",
                 "author": "object - Author info with login field",
                 "createdAt": "string - ISO timestamp of creation",
                 "updatedAt": "string - ISO timestamp of last update",
-                "body": "string - Discussion body content",
-                "category": "object - Category info with name field",
+                "closedAt": "string|null - ISO timestamp of close",
+                "body": "string - Issue body content",
                 "labels": "array - Array of label objects with name field",
+                "assignees": "array - Array of assignee objects with login field",
                 "comments": "object - Comments info with totalCount field",
-                "answer": "object|null - Accepted answer if exists",
-                "url": "string - Discussion URL"
+                "milestone": "object|null - Milestone info with title field",
+                "url": "string - Issue URL"
               }
             },
             "suggested_queries": [
               {"description": "Get all data", "query": "."},
-              {"description": "Get discussion numbers and titles", "query": ".[] | {number, title}"},
-              {"description": "Get discussions by author", "query": ".[] | select(.author.login == \"USERNAME\")"},
-              {"description": "Get discussions in category", "query": ".[] | select(.category.name == \"Ideas\")"},
-              {"description": "Get answered discussions", "query": ".[] | select(.answer != null)"},
-              {"description": "Get unanswered discussions", "query": ".[] | select(.answer == null) | {number, title, category: .category.name}"},
-              {"description": "Count by category", "query": "group_by(.category.name) | map({category: .[0].category.name, count: length})"}
+              {"description": "Get issue numbers and titles", "query": ".[] | {number, title}"},
+              {"description": "Get open issues only", "query": ".[] | select(.state == \"OPEN\")"},
+              {"description": "Get issues by author", "query": ".[] | select(.author.login == \"USERNAME\")"},
+              {"description": "Get issues with label", "query": ".[] | select(.labels | map(.name) | index(\"bug\"))"},
+              {"description": "Get issues with many comments", "query": ".[] | select(.comments.totalCount > 5) | {number, title, comments: .comments.totalCount}"},
+              {"description": "Count by state", "query": "group_by(.state) | map({state: .[0].state, count: length})"}
             ]
           }
           EOF
           fi
           
-          EOFSH_github-discussion-query
-          chmod +x /tmp/gh-aw/safe-inputs/github-discussion-query.sh
-          cat > /tmp/gh-aw/safe-inputs/github-issue-query.sh << 'EOFSH_github-issue-query'
+          
+          EOFSH_github-issue-query
+          chmod +x /tmp/gh-aw/safe-inputs/github-issue-query.sh
+          cat > /tmp/gh-aw/safe-inputs/github-pr-query.sh << 'EOFSH_github-pr-query'
           #!/bin/bash
-          # Auto-generated safe-input tool: github-issue-query
-          # Query GitHub issues with jq filtering support. Without --jq, returns schema and data size info. Use --jq '.' to get all data, or specific jq expressions to filter.
+          # Auto-generated safe-input tool: github-pr-query
+          # Query GitHub pull requests with jq filtering support. Without --jq, returns schema and data size info. Use --jq '.' to get all data, or specific jq expressions to filter.
           
           set -euo pipefail
           
@@ -2714,13 +2708,13 @@ jobs:
           JQ_FILTER="${INPUT_JQ:-}"
           
           # JSON fields to fetch
-          JSON_FIELDS="number,title,state,author,createdAt,updatedAt,closedAt,body,labels,assignees,comments,milestone,url"
+          JSON_FIELDS="number,title,state,author,createdAt,updatedAt,mergedAt,closedAt,headRefName,baseRefName,isDraft,reviewDecision,additions,deletions,changedFiles,labels,assignees,reviewRequests,url"
           
           # Build and execute gh command
           if [[ -n "$REPO" ]]; then
-            OUTPUT=$(gh issue list --state "$STATE" --limit "$LIMIT" --json "$JSON_FIELDS" --repo "$REPO")
+            OUTPUT=$(gh pr list --state "$STATE" --limit "$LIMIT" --json "$JSON_FIELDS" --repo "$REPO")
           else
-            OUTPUT=$(gh issue list --state "$STATE" --limit "$LIMIT" --json "$JSON_FIELDS")
+            OUTPUT=$(gh pr list --state "$STATE" --limit "$LIMIT" --json "$JSON_FIELDS")
           fi
           
           # Apply jq filter if specified
@@ -2746,30 +2740,36 @@ jobs:
             "data_size_bytes": $DATA_SIZE,
             "schema": {
               "type": "array",
-              "description": "Array of issue objects",
+              "description": "Array of pull request objects",
               "item_fields": {
-                "number": "integer - Issue number",
-                "title": "string - Issue title",
-                "state": "string - Issue state (OPEN, CLOSED)",
+                "number": "integer - PR number",
+                "title": "string - PR title",
+                "state": "string - PR state (OPEN, CLOSED, MERGED)",
                 "author": "object - Author info with login field",
                 "createdAt": "string - ISO timestamp of creation",
                 "updatedAt": "string - ISO timestamp of last update",
+                "mergedAt": "string|null - ISO timestamp of merge",
                 "closedAt": "string|null - ISO timestamp of close",
-                "body": "string - Issue body content",
+                "headRefName": "string - Source branch name",
+                "baseRefName": "string - Target branch name",
+                "isDraft": "boolean - Whether PR is a draft",
+                "reviewDecision": "string|null - Review decision (APPROVED, CHANGES_REQUESTED, REVIEW_REQUIRED)",
+                "additions": "integer - Lines added",
+                "deletions": "integer - Lines deleted",
+                "changedFiles": "integer - Number of files changed",
                 "labels": "array - Array of label objects with name field",
                 "assignees": "array - Array of assignee objects with login field",
-                "comments": "object - Comments info with totalCount field",
-                "milestone": "object|null - Milestone info with title field",
-                "url": "string - Issue URL"
+                "reviewRequests": "array - Array of review request objects",
+                "url": "string - PR URL"
               }
             },
             "suggested_queries": [
               {"description": "Get all data", "query": "."},
-              {"description": "Get issue numbers and titles", "query": ".[] | {number, title}"},
-              {"description": "Get open issues only", "query": ".[] | select(.state == \"OPEN\")"},
-              {"description": "Get issues by author", "query": ".[] | select(.author.login == \"USERNAME\")"},
-              {"description": "Get issues with label", "query": ".[] | select(.labels | map(.name) | index(\"bug\"))"},
-              {"description": "Get issues with many comments", "query": ".[] | select(.comments.totalCount > 5) | {number, title, comments: .comments.totalCount}"},
+              {"description": "Get PR numbers and titles", "query": ".[] | {number, title}"},
+              {"description": "Get open PRs only", "query": ".[] | select(.state == \"OPEN\")"},
+              {"description": "Get merged PRs", "query": ".[] | select(.mergedAt != null)"},
+              {"description": "Get PRs by author", "query": ".[] | select(.author.login == \"USERNAME\")"},
+              {"description": "Get large PRs", "query": ".[] | select(.changedFiles > 10) | {number, title, changedFiles}"},
               {"description": "Count by state", "query": "group_by(.state) | map({state: .[0].state, count: length})"}
             ]
           }
@@ -2777,8 +2777,8 @@ jobs:
           fi
           
           
-          EOFSH_github-issue-query
-          chmod +x /tmp/gh-aw/safe-inputs/github-issue-query.sh
+          EOFSH_github-pr-query
+          chmod +x /tmp/gh-aw/safe-inputs/github-pr-query.sh
           
       - name: Setup MCPs
         env:
@@ -4967,81 +4967,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/agent-stdio.log
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5614,6 +5541,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCodexLog,
diff --git a/.github/workflows/daily-repo-chronicle.lock.yml b/.github/workflows/daily-repo-chronicle.lock.yml
index 0a3640e222e..190be0cd6ae 100644
--- a/.github/workflows/daily-repo-chronicle.lock.yml
+++ b/.github/workflows/daily-repo-chronicle.lock.yml
@@ -4272,81 +4272,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/.agent/logs/
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4919,6 +4846,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCopilotLog,
@@ -4960,7 +5058,7 @@ jobs:
                   }
                 }
                 if (!logEntries) {
-                  return "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n";
+                  return { markdown: "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n", logEntries: [] };
                 }
                 const conversationResult = generateConversationMarkdown(logEntries, {
                   formatToolCallback: (toolUse, toolResult) => formatToolUse(toolUse, toolResult, { includeDetailedParameters: true }),
@@ -5012,10 +5110,13 @@ jobs:
                     return "";
                   },
                 });
-                return markdown;
+                return { markdown, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
-                return `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`;
+                return {
+                  markdown: `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
+                  logEntries: [],
+                };
               }
             }
             function scanForToolErrors(logContent) {
diff --git a/.github/workflows/daily-team-status.lock.yml b/.github/workflows/daily-team-status.lock.yml
index 422d7349572..19ec38f0fc1 100644
--- a/.github/workflows/daily-team-status.lock.yml
+++ b/.github/workflows/daily-team-status.lock.yml
@@ -3012,81 +3012,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/.agent/logs/
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -3659,6 +3586,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCopilotLog,
@@ -3700,7 +3798,7 @@ jobs:
                   }
                 }
                 if (!logEntries) {
-                  return "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n";
+                  return { markdown: "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n", logEntries: [] };
                 }
                 const conversationResult = generateConversationMarkdown(logEntries, {
                   formatToolCallback: (toolUse, toolResult) => formatToolUse(toolUse, toolResult, { includeDetailedParameters: true }),
@@ -3752,10 +3850,13 @@ jobs:
                     return "";
                   },
                 });
-                return markdown;
+                return { markdown, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
-                return `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`;
+                return {
+                  markdown: `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
+                  logEntries: [],
+                };
               }
             }
             function scanForToolErrors(logContent) {
diff --git a/.github/workflows/deep-report.lock.yml b/.github/workflows/deep-report.lock.yml
index bcaa2df126b..8cd2e81c5d1 100644
--- a/.github/workflows/deep-report.lock.yml
+++ b/.github/workflows/deep-report.lock.yml
@@ -3893,81 +3893,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/agent-stdio.log
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4540,6 +4467,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCodexLog,
diff --git a/.github/workflows/dependabot-go-checker.lock.yml b/.github/workflows/dependabot-go-checker.lock.yml
index cd9c48a3ce9..69f6fbb3430 100644
--- a/.github/workflows/dependabot-go-checker.lock.yml
+++ b/.github/workflows/dependabot-go-checker.lock.yml
@@ -3719,81 +3719,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/.agent/logs/
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4366,6 +4293,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCopilotLog,
@@ -4407,7 +4505,7 @@ jobs:
                   }
                 }
                 if (!logEntries) {
-                  return "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n";
+                  return { markdown: "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n", logEntries: [] };
                 }
                 const conversationResult = generateConversationMarkdown(logEntries, {
                   formatToolCallback: (toolUse, toolResult) => formatToolUse(toolUse, toolResult, { includeDetailedParameters: true }),
@@ -4459,10 +4557,13 @@ jobs:
                     return "";
                   },
                 });
-                return markdown;
+                return { markdown, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
-                return `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`;
+                return {
+                  markdown: `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
+                  logEntries: [],
+                };
               }
             }
             function scanForToolErrors(logContent) {
diff --git a/.github/workflows/dev-hawk.lock.yml b/.github/workflows/dev-hawk.lock.yml
index 09631dc698b..5c03e6a1c06 100644
--- a/.github/workflows/dev-hawk.lock.yml
+++ b/.github/workflows/dev-hawk.lock.yml
@@ -3625,81 +3625,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/.agent/logs/
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4272,6 +4199,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCopilotLog,
@@ -4313,7 +4411,7 @@ jobs:
                   }
                 }
                 if (!logEntries) {
-                  return "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n";
+                  return { markdown: "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n", logEntries: [] };
                 }
                 const conversationResult = generateConversationMarkdown(logEntries, {
                   formatToolCallback: (toolUse, toolResult) => formatToolUse(toolUse, toolResult, { includeDetailedParameters: true }),
@@ -4365,10 +4463,13 @@ jobs:
                     return "";
                   },
                 });
-                return markdown;
+                return { markdown, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
-                return `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`;
+                return {
+                  markdown: `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
+                  logEntries: [],
+                };
               }
             }
             function scanForToolErrors(logContent) {
diff --git a/.github/workflows/dev.lock.yml b/.github/workflows/dev.lock.yml
index b7f0888b72a..3c4a651c27e 100644
--- a/.github/workflows/dev.lock.yml
+++ b/.github/workflows/dev.lock.yml
@@ -1480,24 +1480,6 @@ jobs:
             function registerTool(name, description, inputSchema, handler) {
               tools[name] = { name, description, inputSchema, handler };
             }
-            registerTool("test-js-math", "Test JavaScript math operations", {"properties":{"a":{"description":"First number","type":"number"},"b":{"description":"Second number","type":"number"}},"required":["a","b"],"type":"object"}, async (args) => {
-              try {
-                const toolModule = require("./test-js-math.cjs");
-                const result = await toolModule.execute(args || {});
-                return { content: [{ type: "text", text: typeof result === "string" ? result : JSON.stringify(result, null, 2) }] };
-              } catch (error) {
-                return { content: [{ type: "text", text: "Error: " + (error instanceof Error ? error.message : String(error)) }], isError: true };
-              }
-            });
-            registerTool("test-js-string", "Test JavaScript string operations", {"properties":{"text":{"description":"Input text","type":"string"}},"required":["text"],"type":"object"}, async (args) => {
-              try {
-                const toolModule = require("./test-js-string.cjs");
-                const result = await toolModule.execute(args || {});
-                return { content: [{ type: "text", text: typeof result === "string" ? result : JSON.stringify(result, null, 2) }] };
-              } catch (error) {
-                return { content: [{ type: "text", text: "Error: " + (error instanceof Error ? error.message : String(error)) }], isError: true };
-              }
-            });
             registerTool("fetch-pr-data", "Fetches pull request data from GitHub using gh CLI. Returns JSON array of PRs with fields: number, title, author, headRefName, createdAt, state, url, body, labels, updatedAt, closedAt, mergedAt", {"properties":{"days":{"default":30,"description":"Number of days to look back (default: 30)","type":"number"},"limit":{"default":100,"description":"Maximum number of PRs to fetch (default: 100)","type":"number"},"repo":{"description":"Repository in owner/repo format (defaults to current repository)","type":"string"},"search":{"description":"Search query for filtering PRs (e.g., 'head:copilot/' for Copilot PRs)","type":"string"},"state":{"default":"all","description":"PR state filter: open, closed, merged, or all (default: all)","type":"string"}},"type":"object"}, async (args) => {
               try {
                 const env = { ...process.env };
@@ -1524,6 +1506,24 @@ jobs:
                 return { content: [{ type: "text", text: "Error: " + (error instanceof Error ? error.message : String(error)) }], isError: true };
               }
             });
+            registerTool("test-js-math", "Test JavaScript math operations", {"properties":{"a":{"description":"First number","type":"number"},"b":{"description":"Second number","type":"number"}},"required":["a","b"],"type":"object"}, async (args) => {
+              try {
+                const toolModule = require("./test-js-math.cjs");
+                const result = await toolModule.execute(args || {});
+                return { content: [{ type: "text", text: typeof result === "string" ? result : JSON.stringify(result, null, 2) }] };
+              } catch (error) {
+                return { content: [{ type: "text", text: "Error: " + (error instanceof Error ? error.message : String(error)) }], isError: true };
+              }
+            });
+            registerTool("test-js-string", "Test JavaScript string operations", {"properties":{"text":{"description":"Input text","type":"string"}},"required":["text"],"type":"object"}, async (args) => {
+              try {
+                const toolModule = require("./test-js-string.cjs");
+                const result = await toolModule.execute(args || {});
+                return { content: [{ type: "text", text: typeof result === "string" ? result : JSON.stringify(result, null, 2) }] };
+              } catch (error) {
+                return { content: [{ type: "text", text: "Error: " + (error instanceof Error ? error.message : String(error)) }], isError: true };
+              }
+            });
             const LARGE_OUTPUT_THRESHOLD = 500;
             const CALLS_DIR = "/tmp/gh-aw/safe-inputs/calls";
             let callCounter = 0;
@@ -3099,81 +3099,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/agent-stdio.log
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -3746,6 +3673,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCodexLog,
diff --git a/.github/workflows/developer-docs-consolidator.lock.yml b/.github/workflows/developer-docs-consolidator.lock.yml
index 57c04169bf7..47c00d33d8b 100644
--- a/.github/workflows/developer-docs-consolidator.lock.yml
+++ b/.github/workflows/developer-docs-consolidator.lock.yml
@@ -4478,81 +4478,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/agent-stdio.log
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5125,6 +5052,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseClaudeLog,
@@ -5140,6 +5238,7 @@ jobs:
                     markdown: "## Agent Log Summary\n\nLog format not recognized as Claude JSON array or JSONL.\n",
                     mcpFailures: [],
                     maxTurnsHit: false,
+                    logEntries: [],
                   };
                 }
                 const mcpFailures = [];
@@ -5193,13 +5292,14 @@ jobs:
                     maxTurnsHit = true;
                   }
                 }
-                return { markdown, mcpFailures, maxTurnsHit };
+                return { markdown, mcpFailures, maxTurnsHit, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
                 return {
                   markdown: `## Agent Log Summary\n\nError parsing Claude log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
                   mcpFailures: [],
                   maxTurnsHit: false,
+                  logEntries: [],
                 };
               }
             }
diff --git a/.github/workflows/dictation-prompt.lock.yml b/.github/workflows/dictation-prompt.lock.yml
index f93fcb07d63..2197133d411 100644
--- a/.github/workflows/dictation-prompt.lock.yml
+++ b/.github/workflows/dictation-prompt.lock.yml
@@ -3128,81 +3128,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/.agent/logs/
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -3775,6 +3702,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCopilotLog,
@@ -3816,7 +3914,7 @@ jobs:
                   }
                 }
                 if (!logEntries) {
-                  return "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n";
+                  return { markdown: "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n", logEntries: [] };
                 }
                 const conversationResult = generateConversationMarkdown(logEntries, {
                   formatToolCallback: (toolUse, toolResult) => formatToolUse(toolUse, toolResult, { includeDetailedParameters: true }),
@@ -3868,10 +3966,13 @@ jobs:
                     return "";
                   },
                 });
-                return markdown;
+                return { markdown, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
-                return `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`;
+                return {
+                  markdown: `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
+                  logEntries: [],
+                };
               }
             }
             function scanForToolErrors(logContent) {
diff --git a/.github/workflows/docs-noob-tester.lock.yml b/.github/workflows/docs-noob-tester.lock.yml
index d10607465d3..d9ad391920c 100644
--- a/.github/workflows/docs-noob-tester.lock.yml
+++ b/.github/workflows/docs-noob-tester.lock.yml
@@ -3209,81 +3209,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/.agent/logs/
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -3856,6 +3783,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCopilotLog,
@@ -3897,7 +3995,7 @@ jobs:
                   }
                 }
                 if (!logEntries) {
-                  return "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n";
+                  return { markdown: "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n", logEntries: [] };
                 }
                 const conversationResult = generateConversationMarkdown(logEntries, {
                   formatToolCallback: (toolUse, toolResult) => formatToolUse(toolUse, toolResult, { includeDetailedParameters: true }),
@@ -3949,10 +4047,13 @@ jobs:
                     return "";
                   },
                 });
-                return markdown;
+                return { markdown, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
-                return `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`;
+                return {
+                  markdown: `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
+                  logEntries: [],
+                };
               }
             }
             function scanForToolErrors(logContent) {
diff --git a/.github/workflows/duplicate-code-detector.lock.yml b/.github/workflows/duplicate-code-detector.lock.yml
index b504cf87b4d..c5b8ec1704c 100644
--- a/.github/workflows/duplicate-code-detector.lock.yml
+++ b/.github/workflows/duplicate-code-detector.lock.yml
@@ -3270,81 +3270,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/agent-stdio.log
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -3917,6 +3844,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCodexLog,
diff --git a/.github/workflows/example-permissions-warning.lock.yml b/.github/workflows/example-permissions-warning.lock.yml
index 260028be3e8..95f04c59c0d 100644
--- a/.github/workflows/example-permissions-warning.lock.yml
+++ b/.github/workflows/example-permissions-warning.lock.yml
@@ -750,81 +750,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/.agent/logs/
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -1397,6 +1324,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCopilotLog,
@@ -1438,7 +1536,7 @@ jobs:
                   }
                 }
                 if (!logEntries) {
-                  return "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n";
+                  return { markdown: "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n", logEntries: [] };
                 }
                 const conversationResult = generateConversationMarkdown(logEntries, {
                   formatToolCallback: (toolUse, toolResult) => formatToolUse(toolUse, toolResult, { includeDetailedParameters: true }),
@@ -1490,10 +1588,13 @@ jobs:
                     return "";
                   },
                 });
-                return markdown;
+                return { markdown, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
-                return `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`;
+                return {
+                  markdown: `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
+                  logEntries: [],
+                };
               }
             }
             function scanForToolErrors(logContent) {
diff --git a/.github/workflows/example-workflow-analyzer.lock.yml b/.github/workflows/example-workflow-analyzer.lock.yml
index a6888679ab3..73a1c70b925 100644
--- a/.github/workflows/example-workflow-analyzer.lock.yml
+++ b/.github/workflows/example-workflow-analyzer.lock.yml
@@ -3173,81 +3173,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/agent-stdio.log
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -3820,6 +3747,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseClaudeLog,
@@ -3835,6 +3933,7 @@ jobs:
                     markdown: "## Agent Log Summary\n\nLog format not recognized as Claude JSON array or JSONL.\n",
                     mcpFailures: [],
                     maxTurnsHit: false,
+                    logEntries: [],
                   };
                 }
                 const mcpFailures = [];
@@ -3888,13 +3987,14 @@ jobs:
                     maxTurnsHit = true;
                   }
                 }
-                return { markdown, mcpFailures, maxTurnsHit };
+                return { markdown, mcpFailures, maxTurnsHit, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
                 return {
                   markdown: `## Agent Log Summary\n\nError parsing Claude log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
                   mcpFailures: [],
                   maxTurnsHit: false,
+                  logEntries: [],
                 };
               }
             }
diff --git a/.github/workflows/firewall.lock.yml b/.github/workflows/firewall.lock.yml
index 05c088f2c7d..3933cb96695 100644
--- a/.github/workflows/firewall.lock.yml
+++ b/.github/workflows/firewall.lock.yml
@@ -813,81 +813,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/.agent/logs/
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -1460,6 +1387,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCopilotLog,
@@ -1501,7 +1599,7 @@ jobs:
                   }
                 }
                 if (!logEntries) {
-                  return "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n";
+                  return { markdown: "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n", logEntries: [] };
                 }
                 const conversationResult = generateConversationMarkdown(logEntries, {
                   formatToolCallback: (toolUse, toolResult) => formatToolUse(toolUse, toolResult, { includeDetailedParameters: true }),
@@ -1553,10 +1651,13 @@ jobs:
                     return "";
                   },
                 });
-                return markdown;
+                return { markdown, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
-                return `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`;
+                return {
+                  markdown: `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
+                  logEntries: [],
+                };
               }
             }
             function scanForToolErrors(logContent) {
diff --git a/.github/workflows/github-mcp-structural-analysis.lock.yml b/.github/workflows/github-mcp-structural-analysis.lock.yml
index 1aa555e53fa..eb09fd40b02 100644
--- a/.github/workflows/github-mcp-structural-analysis.lock.yml
+++ b/.github/workflows/github-mcp-structural-analysis.lock.yml
@@ -4404,81 +4404,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/agent-stdio.log
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5051,6 +4978,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseClaudeLog,
@@ -5066,6 +5164,7 @@ jobs:
                     markdown: "## Agent Log Summary\n\nLog format not recognized as Claude JSON array or JSONL.\n",
                     mcpFailures: [],
                     maxTurnsHit: false,
+                    logEntries: [],
                   };
                 }
                 const mcpFailures = [];
@@ -5119,13 +5218,14 @@ jobs:
                     maxTurnsHit = true;
                   }
                 }
-                return { markdown, mcpFailures, maxTurnsHit };
+                return { markdown, mcpFailures, maxTurnsHit, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
                 return {
                   markdown: `## Agent Log Summary\n\nError parsing Claude log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
                   mcpFailures: [],
                   maxTurnsHit: false,
+                  logEntries: [],
                 };
               }
             }
diff --git a/.github/workflows/github-mcp-tools-report.lock.yml b/.github/workflows/github-mcp-tools-report.lock.yml
index bc8eb88fc33..8e50aa64b6a 100644
--- a/.github/workflows/github-mcp-tools-report.lock.yml
+++ b/.github/workflows/github-mcp-tools-report.lock.yml
@@ -4184,81 +4184,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/agent-stdio.log
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4831,6 +4758,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseClaudeLog,
@@ -4846,6 +4944,7 @@ jobs:
                     markdown: "## Agent Log Summary\n\nLog format not recognized as Claude JSON array or JSONL.\n",
                     mcpFailures: [],
                     maxTurnsHit: false,
+                    logEntries: [],
                   };
                 }
                 const mcpFailures = [];
@@ -4899,13 +4998,14 @@ jobs:
                     maxTurnsHit = true;
                   }
                 }
-                return { markdown, mcpFailures, maxTurnsHit };
+                return { markdown, mcpFailures, maxTurnsHit, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
                 return {
                   markdown: `## Agent Log Summary\n\nError parsing Claude log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
                   mcpFailures: [],
                   maxTurnsHit: false,
+                  logEntries: [],
                 };
               }
             }
diff --git a/.github/workflows/glossary-maintainer.lock.yml b/.github/workflows/glossary-maintainer.lock.yml
index 36da5942d03..2153585c05e 100644
--- a/.github/workflows/glossary-maintainer.lock.yml
+++ b/.github/workflows/glossary-maintainer.lock.yml
@@ -4179,81 +4179,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/.agent/logs/
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4826,6 +4753,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCopilotLog,
@@ -4867,7 +4965,7 @@ jobs:
                   }
                 }
                 if (!logEntries) {
-                  return "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n";
+                  return { markdown: "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n", logEntries: [] };
                 }
                 const conversationResult = generateConversationMarkdown(logEntries, {
                   formatToolCallback: (toolUse, toolResult) => formatToolUse(toolUse, toolResult, { includeDetailedParameters: true }),
@@ -4919,10 +5017,13 @@ jobs:
                     return "";
                   },
                 });
-                return markdown;
+                return { markdown, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
-                return `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`;
+                return {
+                  markdown: `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
+                  logEntries: [],
+                };
               }
             }
             function scanForToolErrors(logContent) {
diff --git a/.github/workflows/go-fan.lock.yml b/.github/workflows/go-fan.lock.yml
index f74b0aa73ca..daefc143d0c 100644
--- a/.github/workflows/go-fan.lock.yml
+++ b/.github/workflows/go-fan.lock.yml
@@ -3787,81 +3787,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/agent-stdio.log
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4434,6 +4361,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseClaudeLog,
@@ -4449,6 +4547,7 @@ jobs:
                     markdown: "## Agent Log Summary\n\nLog format not recognized as Claude JSON array or JSONL.\n",
                     mcpFailures: [],
                     maxTurnsHit: false,
+                    logEntries: [],
                   };
                 }
                 const mcpFailures = [];
@@ -4502,13 +4601,14 @@ jobs:
                     maxTurnsHit = true;
                   }
                 }
-                return { markdown, mcpFailures, maxTurnsHit };
+                return { markdown, mcpFailures, maxTurnsHit, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
                 return {
                   markdown: `## Agent Log Summary\n\nError parsing Claude log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
                   mcpFailures: [],
                   maxTurnsHit: false,
+                  logEntries: [],
                 };
               }
             }
diff --git a/.github/workflows/go-logger.lock.yml b/.github/workflows/go-logger.lock.yml
index 7028fdbd99d..6d7067cc817 100644
--- a/.github/workflows/go-logger.lock.yml
+++ b/.github/workflows/go-logger.lock.yml
@@ -3624,81 +3624,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/agent-stdio.log
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4271,6 +4198,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseClaudeLog,
@@ -4286,6 +4384,7 @@ jobs:
                     markdown: "## Agent Log Summary\n\nLog format not recognized as Claude JSON array or JSONL.\n",
                     mcpFailures: [],
                     maxTurnsHit: false,
+                    logEntries: [],
                   };
                 }
                 const mcpFailures = [];
@@ -4339,13 +4438,14 @@ jobs:
                     maxTurnsHit = true;
                   }
                 }
-                return { markdown, mcpFailures, maxTurnsHit };
+                return { markdown, mcpFailures, maxTurnsHit, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
                 return {
                   markdown: `## Agent Log Summary\n\nError parsing Claude log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
                   mcpFailures: [],
                   maxTurnsHit: false,
+                  logEntries: [],
                 };
               }
             }
diff --git a/.github/workflows/go-pattern-detector.lock.yml b/.github/workflows/go-pattern-detector.lock.yml
index 2718a9b6b58..e1ff9054414 100644
--- a/.github/workflows/go-pattern-detector.lock.yml
+++ b/.github/workflows/go-pattern-detector.lock.yml
@@ -3312,81 +3312,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/agent-stdio.log
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -3959,6 +3886,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseClaudeLog,
@@ -3974,6 +4072,7 @@ jobs:
                     markdown: "## Agent Log Summary\n\nLog format not recognized as Claude JSON array or JSONL.\n",
                     mcpFailures: [],
                     maxTurnsHit: false,
+                    logEntries: [],
                   };
                 }
                 const mcpFailures = [];
@@ -4027,13 +4126,14 @@ jobs:
                     maxTurnsHit = true;
                   }
                 }
-                return { markdown, mcpFailures, maxTurnsHit };
+                return { markdown, mcpFailures, maxTurnsHit, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
                 return {
                   markdown: `## Agent Log Summary\n\nError parsing Claude log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
                   mcpFailures: [],
                   maxTurnsHit: false,
+                  logEntries: [],
                 };
               }
             }
diff --git a/.github/workflows/grumpy-reviewer.lock.yml b/.github/workflows/grumpy-reviewer.lock.yml
index b14bc4f4660..a55d60cbb3e 100644
--- a/.github/workflows/grumpy-reviewer.lock.yml
+++ b/.github/workflows/grumpy-reviewer.lock.yml
@@ -4532,81 +4532,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/.agent/logs/
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5179,6 +5106,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCopilotLog,
@@ -5220,7 +5318,7 @@ jobs:
                   }
                 }
                 if (!logEntries) {
-                  return "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n";
+                  return { markdown: "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n", logEntries: [] };
                 }
                 const conversationResult = generateConversationMarkdown(logEntries, {
                   formatToolCallback: (toolUse, toolResult) => formatToolUse(toolUse, toolResult, { includeDetailedParameters: true }),
@@ -5272,10 +5370,13 @@ jobs:
                     return "";
                   },
                 });
-                return markdown;
+                return { markdown, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
-                return `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`;
+                return {
+                  markdown: `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
+                  logEntries: [],
+                };
               }
             }
             function scanForToolErrors(logContent) {
diff --git a/.github/workflows/instructions-janitor.lock.yml b/.github/workflows/instructions-janitor.lock.yml
index 6592ad8593c..187a63cc391 100644
--- a/.github/workflows/instructions-janitor.lock.yml
+++ b/.github/workflows/instructions-janitor.lock.yml
@@ -3390,81 +3390,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/agent-stdio.log
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4037,6 +3964,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseClaudeLog,
@@ -4052,6 +4150,7 @@ jobs:
                     markdown: "## Agent Log Summary\n\nLog format not recognized as Claude JSON array or JSONL.\n",
                     mcpFailures: [],
                     maxTurnsHit: false,
+                    logEntries: [],
                   };
                 }
                 const mcpFailures = [];
@@ -4105,13 +4204,14 @@ jobs:
                     maxTurnsHit = true;
                   }
                 }
-                return { markdown, mcpFailures, maxTurnsHit };
+                return { markdown, mcpFailures, maxTurnsHit, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
                 return {
                   markdown: `## Agent Log Summary\n\nError parsing Claude log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
                   mcpFailures: [],
                   maxTurnsHit: false,
+                  logEntries: [],
                 };
               }
             }
diff --git a/.github/workflows/issue-arborist.lock.yml b/.github/workflows/issue-arborist.lock.yml
index 04de0e8ed1f..3f3454bf876 100644
--- a/.github/workflows/issue-arborist.lock.yml
+++ b/.github/workflows/issue-arborist.lock.yml
@@ -3284,81 +3284,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/agent-stdio.log
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -3931,6 +3858,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCodexLog,
diff --git a/.github/workflows/issue-monster.lock.yml b/.github/workflows/issue-monster.lock.yml
index 11122adbc31..62e68e2f793 100644
--- a/.github/workflows/issue-monster.lock.yml
+++ b/.github/workflows/issue-monster.lock.yml
@@ -3641,81 +3641,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/.agent/logs/
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4288,6 +4215,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCopilotLog,
@@ -4329,7 +4427,7 @@ jobs:
                   }
                 }
                 if (!logEntries) {
-                  return "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n";
+                  return { markdown: "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n", logEntries: [] };
                 }
                 const conversationResult = generateConversationMarkdown(logEntries, {
                   formatToolCallback: (toolUse, toolResult) => formatToolUse(toolUse, toolResult, { includeDetailedParameters: true }),
@@ -4381,10 +4479,13 @@ jobs:
                     return "";
                   },
                 });
-                return markdown;
+                return { markdown, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
-                return `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`;
+                return {
+                  markdown: `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
+                  logEntries: [],
+                };
               }
             }
             function scanForToolErrors(logContent) {
diff --git a/.github/workflows/issue-triage-agent.lock.yml b/.github/workflows/issue-triage-agent.lock.yml
index 7a830aa6022..4ea6efe39f3 100644
--- a/.github/workflows/issue-triage-agent.lock.yml
+++ b/.github/workflows/issue-triage-agent.lock.yml
@@ -3295,81 +3295,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/.agent/logs/
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -3942,6 +3869,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCopilotLog,
@@ -3983,7 +4081,7 @@ jobs:
                   }
                 }
                 if (!logEntries) {
-                  return "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n";
+                  return { markdown: "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n", logEntries: [] };
                 }
                 const conversationResult = generateConversationMarkdown(logEntries, {
                   formatToolCallback: (toolUse, toolResult) => formatToolUse(toolUse, toolResult, { includeDetailedParameters: true }),
@@ -4035,10 +4133,13 @@ jobs:
                     return "";
                   },
                 });
-                return markdown;
+                return { markdown, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
-                return `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`;
+                return {
+                  markdown: `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
+                  logEntries: [],
+                };
               }
             }
             function scanForToolErrors(logContent) {
diff --git a/.github/workflows/lockfile-stats.lock.yml b/.github/workflows/lockfile-stats.lock.yml
index e7fb8516399..dda04c266dc 100644
--- a/.github/workflows/lockfile-stats.lock.yml
+++ b/.github/workflows/lockfile-stats.lock.yml
@@ -3832,81 +3832,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/agent-stdio.log
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4479,6 +4406,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseClaudeLog,
@@ -4494,6 +4592,7 @@ jobs:
                     markdown: "## Agent Log Summary\n\nLog format not recognized as Claude JSON array or JSONL.\n",
                     mcpFailures: [],
                     maxTurnsHit: false,
+                    logEntries: [],
                   };
                 }
                 const mcpFailures = [];
@@ -4547,13 +4646,14 @@ jobs:
                     maxTurnsHit = true;
                   }
                 }
-                return { markdown, mcpFailures, maxTurnsHit };
+                return { markdown, mcpFailures, maxTurnsHit, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
                 return {
                   markdown: `## Agent Log Summary\n\nError parsing Claude log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
                   mcpFailures: [],
                   maxTurnsHit: false,
+                  logEntries: [],
                 };
               }
             }
diff --git a/.github/workflows/mcp-inspector.lock.yml b/.github/workflows/mcp-inspector.lock.yml
index 82ed7c521cf..908209e06e9 100644
--- a/.github/workflows/mcp-inspector.lock.yml
+++ b/.github/workflows/mcp-inspector.lock.yml
@@ -3803,81 +3803,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/.agent/logs/
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4450,6 +4377,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCopilotLog,
@@ -4491,7 +4589,7 @@ jobs:
                   }
                 }
                 if (!logEntries) {
-                  return "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n";
+                  return { markdown: "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n", logEntries: [] };
                 }
                 const conversationResult = generateConversationMarkdown(logEntries, {
                   formatToolCallback: (toolUse, toolResult) => formatToolUse(toolUse, toolResult, { includeDetailedParameters: true }),
@@ -4543,10 +4641,13 @@ jobs:
                     return "";
                   },
                 });
-                return markdown;
+                return { markdown, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
-                return `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`;
+                return {
+                  markdown: `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
+                  logEntries: [],
+                };
               }
             }
             function scanForToolErrors(logContent) {
diff --git a/.github/workflows/mergefest.lock.yml b/.github/workflows/mergefest.lock.yml
index c6b65b0f837..3feb71355ac 100644
--- a/.github/workflows/mergefest.lock.yml
+++ b/.github/workflows/mergefest.lock.yml
@@ -3894,81 +3894,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/.agent/logs/
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4541,6 +4468,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCopilotLog,
@@ -4582,7 +4680,7 @@ jobs:
                   }
                 }
                 if (!logEntries) {
-                  return "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n";
+                  return { markdown: "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n", logEntries: [] };
                 }
                 const conversationResult = generateConversationMarkdown(logEntries, {
                   formatToolCallback: (toolUse, toolResult) => formatToolUse(toolUse, toolResult, { includeDetailedParameters: true }),
@@ -4634,10 +4732,13 @@ jobs:
                     return "";
                   },
                 });
-                return markdown;
+                return { markdown, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
-                return `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`;
+                return {
+                  markdown: `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
+                  logEntries: [],
+                };
               }
             }
             function scanForToolErrors(logContent) {
diff --git a/.github/workflows/notion-issue-summary.lock.yml b/.github/workflows/notion-issue-summary.lock.yml
index 05610474899..6cc00ca81a7 100644
--- a/.github/workflows/notion-issue-summary.lock.yml
+++ b/.github/workflows/notion-issue-summary.lock.yml
@@ -2797,81 +2797,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/.agent/logs/
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -3444,6 +3371,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCopilotLog,
@@ -3485,7 +3583,7 @@ jobs:
                   }
                 }
                 if (!logEntries) {
-                  return "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n";
+                  return { markdown: "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n", logEntries: [] };
                 }
                 const conversationResult = generateConversationMarkdown(logEntries, {
                   formatToolCallback: (toolUse, toolResult) => formatToolUse(toolUse, toolResult, { includeDetailedParameters: true }),
@@ -3537,10 +3635,13 @@ jobs:
                     return "";
                   },
                 });
-                return markdown;
+                return { markdown, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
-                return `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`;
+                return {
+                  markdown: `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
+                  logEntries: [],
+                };
               }
             }
             function scanForToolErrors(logContent) {
diff --git a/.github/workflows/pdf-summary.lock.yml b/.github/workflows/pdf-summary.lock.yml
index c8379de4a4b..80cbee8c0c9 100644
--- a/.github/workflows/pdf-summary.lock.yml
+++ b/.github/workflows/pdf-summary.lock.yml
@@ -4551,81 +4551,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/.agent/logs/
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5198,6 +5125,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCopilotLog,
@@ -5239,7 +5337,7 @@ jobs:
                   }
                 }
                 if (!logEntries) {
-                  return "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n";
+                  return { markdown: "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n", logEntries: [] };
                 }
                 const conversationResult = generateConversationMarkdown(logEntries, {
                   formatToolCallback: (toolUse, toolResult) => formatToolUse(toolUse, toolResult, { includeDetailedParameters: true }),
@@ -5291,10 +5389,13 @@ jobs:
                     return "";
                   },
                 });
-                return markdown;
+                return { markdown, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
-                return `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`;
+                return {
+                  markdown: `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
+                  logEntries: [],
+                };
               }
             }
             function scanForToolErrors(logContent) {
diff --git a/.github/workflows/plan.lock.yml b/.github/workflows/plan.lock.yml
index dbf96bb9bca..862fb978b69 100644
--- a/.github/workflows/plan.lock.yml
+++ b/.github/workflows/plan.lock.yml
@@ -3902,81 +3902,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/.agent/logs/
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4549,6 +4476,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCopilotLog,
@@ -4590,7 +4688,7 @@ jobs:
                   }
                 }
                 if (!logEntries) {
-                  return "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n";
+                  return { markdown: "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n", logEntries: [] };
                 }
                 const conversationResult = generateConversationMarkdown(logEntries, {
                   formatToolCallback: (toolUse, toolResult) => formatToolUse(toolUse, toolResult, { includeDetailedParameters: true }),
@@ -4642,10 +4740,13 @@ jobs:
                     return "";
                   },
                 });
-                return markdown;
+                return { markdown, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
-                return `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`;
+                return {
+                  markdown: `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
+                  logEntries: [],
+                };
               }
             }
             function scanForToolErrors(logContent) {
diff --git a/.github/workflows/poem-bot.lock.yml b/.github/workflows/poem-bot.lock.yml
index b1cd00a964b..97c55834eef 100644
--- a/.github/workflows/poem-bot.lock.yml
+++ b/.github/workflows/poem-bot.lock.yml
@@ -5601,81 +5601,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/.agent/logs/
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -6248,6 +6175,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCopilotLog,
@@ -6289,7 +6387,7 @@ jobs:
                   }
                 }
                 if (!logEntries) {
-                  return "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n";
+                  return { markdown: "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n", logEntries: [] };
                 }
                 const conversationResult = generateConversationMarkdown(logEntries, {
                   formatToolCallback: (toolUse, toolResult) => formatToolUse(toolUse, toolResult, { includeDetailedParameters: true }),
@@ -6341,10 +6439,13 @@ jobs:
                     return "";
                   },
                 });
-                return markdown;
+                return { markdown, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
-                return `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`;
+                return {
+                  markdown: `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
+                  logEntries: [],
+                };
               }
             }
             function scanForToolErrors(logContent) {
diff --git a/.github/workflows/pr-nitpick-reviewer.lock.yml b/.github/workflows/pr-nitpick-reviewer.lock.yml
index 4ae7129a244..4a13c12e3b5 100644
--- a/.github/workflows/pr-nitpick-reviewer.lock.yml
+++ b/.github/workflows/pr-nitpick-reviewer.lock.yml
@@ -4871,81 +4871,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/.agent/logs/
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5518,6 +5445,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCopilotLog,
@@ -5559,7 +5657,7 @@ jobs:
                   }
                 }
                 if (!logEntries) {
-                  return "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n";
+                  return { markdown: "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n", logEntries: [] };
                 }
                 const conversationResult = generateConversationMarkdown(logEntries, {
                   formatToolCallback: (toolUse, toolResult) => formatToolUse(toolUse, toolResult, { includeDetailedParameters: true }),
@@ -5611,10 +5709,13 @@ jobs:
                     return "";
                   },
                 });
-                return markdown;
+                return { markdown, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
-                return `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`;
+                return {
+                  markdown: `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
+                  logEntries: [],
+                };
               }
             }
             function scanForToolErrors(logContent) {
diff --git a/.github/workflows/prompt-clustering-analysis.lock.yml b/.github/workflows/prompt-clustering-analysis.lock.yml
index 0cd30bd1ef8..cdce4b5f719 100644
--- a/.github/workflows/prompt-clustering-analysis.lock.yml
+++ b/.github/workflows/prompt-clustering-analysis.lock.yml
@@ -5041,81 +5041,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/agent-stdio.log
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5688,6 +5615,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseClaudeLog,
@@ -5703,6 +5801,7 @@ jobs:
                     markdown: "## Agent Log Summary\n\nLog format not recognized as Claude JSON array or JSONL.\n",
                     mcpFailures: [],
                     maxTurnsHit: false,
+                    logEntries: [],
                   };
                 }
                 const mcpFailures = [];
@@ -5756,13 +5855,14 @@ jobs:
                     maxTurnsHit = true;
                   }
                 }
-                return { markdown, mcpFailures, maxTurnsHit };
+                return { markdown, mcpFailures, maxTurnsHit, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
                 return {
                   markdown: `## Agent Log Summary\n\nError parsing Claude log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
                   mcpFailures: [],
                   maxTurnsHit: false,
+                  logEntries: [],
                 };
               }
             }
diff --git a/.github/workflows/python-data-charts.lock.yml b/.github/workflows/python-data-charts.lock.yml
index 35b3a33bbd7..12b0b5e12df 100644
--- a/.github/workflows/python-data-charts.lock.yml
+++ b/.github/workflows/python-data-charts.lock.yml
@@ -4901,81 +4901,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/.agent/logs/
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5548,6 +5475,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCopilotLog,
@@ -5589,7 +5687,7 @@ jobs:
                   }
                 }
                 if (!logEntries) {
-                  return "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n";
+                  return { markdown: "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n", logEntries: [] };
                 }
                 const conversationResult = generateConversationMarkdown(logEntries, {
                   formatToolCallback: (toolUse, toolResult) => formatToolUse(toolUse, toolResult, { includeDetailedParameters: true }),
@@ -5641,10 +5739,13 @@ jobs:
                     return "";
                   },
                 });
-                return markdown;
+                return { markdown, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
-                return `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`;
+                return {
+                  markdown: `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
+                  logEntries: [],
+                };
               }
             }
             function scanForToolErrors(logContent) {
diff --git a/.github/workflows/q.lock.yml b/.github/workflows/q.lock.yml
index fd359250144..b95a9a1c57d 100644
--- a/.github/workflows/q.lock.yml
+++ b/.github/workflows/q.lock.yml
@@ -5132,81 +5132,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/.agent/logs/
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5779,6 +5706,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCopilotLog,
@@ -5820,7 +5918,7 @@ jobs:
                   }
                 }
                 if (!logEntries) {
-                  return "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n";
+                  return { markdown: "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n", logEntries: [] };
                 }
                 const conversationResult = generateConversationMarkdown(logEntries, {
                   formatToolCallback: (toolUse, toolResult) => formatToolUse(toolUse, toolResult, { includeDetailedParameters: true }),
@@ -5872,10 +5970,13 @@ jobs:
                     return "";
                   },
                 });
-                return markdown;
+                return { markdown, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
-                return `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`;
+                return {
+                  markdown: `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
+                  logEntries: [],
+                };
               }
             }
             function scanForToolErrors(logContent) {
diff --git a/.github/workflows/release.lock.yml b/.github/workflows/release.lock.yml
index d7bd79fe032..11d38349885 100644
--- a/.github/workflows/release.lock.yml
+++ b/.github/workflows/release.lock.yml
@@ -3204,81 +3204,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/.agent/logs/
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -3851,6 +3778,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCopilotLog,
@@ -3892,7 +3990,7 @@ jobs:
                   }
                 }
                 if (!logEntries) {
-                  return "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n";
+                  return { markdown: "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n", logEntries: [] };
                 }
                 const conversationResult = generateConversationMarkdown(logEntries, {
                   formatToolCallback: (toolUse, toolResult) => formatToolUse(toolUse, toolResult, { includeDetailedParameters: true }),
@@ -3944,10 +4042,13 @@ jobs:
                     return "";
                   },
                 });
-                return markdown;
+                return { markdown, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
-                return `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`;
+                return {
+                  markdown: `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
+                  logEntries: [],
+                };
               }
             }
             function scanForToolErrors(logContent) {
diff --git a/.github/workflows/repo-tree-map.lock.yml b/.github/workflows/repo-tree-map.lock.yml
index b451db72c9e..aeb09791607 100644
--- a/.github/workflows/repo-tree-map.lock.yml
+++ b/.github/workflows/repo-tree-map.lock.yml
@@ -3196,81 +3196,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/.agent/logs/
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -3843,6 +3770,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCopilotLog,
@@ -3884,7 +3982,7 @@ jobs:
                   }
                 }
                 if (!logEntries) {
-                  return "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n";
+                  return { markdown: "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n", logEntries: [] };
                 }
                 const conversationResult = generateConversationMarkdown(logEntries, {
                   formatToolCallback: (toolUse, toolResult) => formatToolUse(toolUse, toolResult, { includeDetailedParameters: true }),
@@ -3936,10 +4034,13 @@ jobs:
                     return "";
                   },
                 });
-                return markdown;
+                return { markdown, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
-                return `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`;
+                return {
+                  markdown: `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
+                  logEntries: [],
+                };
               }
             }
             function scanForToolErrors(logContent) {
diff --git a/.github/workflows/repository-quality-improver.lock.yml b/.github/workflows/repository-quality-improver.lock.yml
index 7105329cd4a..18b0118a6c1 100644
--- a/.github/workflows/repository-quality-improver.lock.yml
+++ b/.github/workflows/repository-quality-improver.lock.yml
@@ -4105,81 +4105,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/.agent/logs/
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4752,6 +4679,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCopilotLog,
@@ -4793,7 +4891,7 @@ jobs:
                   }
                 }
                 if (!logEntries) {
-                  return "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n";
+                  return { markdown: "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n", logEntries: [] };
                 }
                 const conversationResult = generateConversationMarkdown(logEntries, {
                   formatToolCallback: (toolUse, toolResult) => formatToolUse(toolUse, toolResult, { includeDetailedParameters: true }),
@@ -4845,10 +4943,13 @@ jobs:
                     return "";
                   },
                 });
-                return markdown;
+                return { markdown, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
-                return `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`;
+                return {
+                  markdown: `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
+                  logEntries: [],
+                };
               }
             }
             function scanForToolErrors(logContent) {
diff --git a/.github/workflows/research.lock.yml b/.github/workflows/research.lock.yml
index 39a8cbac5bc..9a0c7237706 100644
--- a/.github/workflows/research.lock.yml
+++ b/.github/workflows/research.lock.yml
@@ -3058,81 +3058,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/.agent/logs/
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -3705,6 +3632,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCopilotLog,
@@ -3746,7 +3844,7 @@ jobs:
                   }
                 }
                 if (!logEntries) {
-                  return "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n";
+                  return { markdown: "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n", logEntries: [] };
                 }
                 const conversationResult = generateConversationMarkdown(logEntries, {
                   formatToolCallback: (toolUse, toolResult) => formatToolUse(toolUse, toolResult, { includeDetailedParameters: true }),
@@ -3798,10 +3896,13 @@ jobs:
                     return "";
                   },
                 });
-                return markdown;
+                return { markdown, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
-                return `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`;
+                return {
+                  markdown: `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
+                  logEntries: [],
+                };
               }
             }
             function scanForToolErrors(logContent) {
diff --git a/.github/workflows/safe-output-health.lock.yml b/.github/workflows/safe-output-health.lock.yml
index be176969be8..374cfa339f3 100644
--- a/.github/workflows/safe-output-health.lock.yml
+++ b/.github/workflows/safe-output-health.lock.yml
@@ -4064,81 +4064,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/agent-stdio.log
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4711,6 +4638,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseClaudeLog,
@@ -4726,6 +4824,7 @@ jobs:
                     markdown: "## Agent Log Summary\n\nLog format not recognized as Claude JSON array or JSONL.\n",
                     mcpFailures: [],
                     maxTurnsHit: false,
+                    logEntries: [],
                   };
                 }
                 const mcpFailures = [];
@@ -4779,13 +4878,14 @@ jobs:
                     maxTurnsHit = true;
                   }
                 }
-                return { markdown, mcpFailures, maxTurnsHit };
+                return { markdown, mcpFailures, maxTurnsHit, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
                 return {
                   markdown: `## Agent Log Summary\n\nError parsing Claude log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
                   mcpFailures: [],
                   maxTurnsHit: false,
+                  logEntries: [],
                 };
               }
             }
diff --git a/.github/workflows/schema-consistency-checker.lock.yml b/.github/workflows/schema-consistency-checker.lock.yml
index 7fd05822e16..e797b5f4890 100644
--- a/.github/workflows/schema-consistency-checker.lock.yml
+++ b/.github/workflows/schema-consistency-checker.lock.yml
@@ -3842,81 +3842,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/agent-stdio.log
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4489,6 +4416,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseClaudeLog,
@@ -4504,6 +4602,7 @@ jobs:
                     markdown: "## Agent Log Summary\n\nLog format not recognized as Claude JSON array or JSONL.\n",
                     mcpFailures: [],
                     maxTurnsHit: false,
+                    logEntries: [],
                   };
                 }
                 const mcpFailures = [];
@@ -4557,13 +4656,14 @@ jobs:
                     maxTurnsHit = true;
                   }
                 }
-                return { markdown, mcpFailures, maxTurnsHit };
+                return { markdown, mcpFailures, maxTurnsHit, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
                 return {
                   markdown: `## Agent Log Summary\n\nError parsing Claude log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
                   mcpFailures: [],
                   maxTurnsHit: false,
+                  logEntries: [],
                 };
               }
             }
diff --git a/.github/workflows/scout.lock.yml b/.github/workflows/scout.lock.yml
index 3c9a1f0bbe2..e39a261669a 100644
--- a/.github/workflows/scout.lock.yml
+++ b/.github/workflows/scout.lock.yml
@@ -5165,81 +5165,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/agent-stdio.log
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5812,6 +5739,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseClaudeLog,
@@ -5827,6 +5925,7 @@ jobs:
                     markdown: "## Agent Log Summary\n\nLog format not recognized as Claude JSON array or JSONL.\n",
                     mcpFailures: [],
                     maxTurnsHit: false,
+                    logEntries: [],
                   };
                 }
                 const mcpFailures = [];
@@ -5880,13 +5979,14 @@ jobs:
                     maxTurnsHit = true;
                   }
                 }
-                return { markdown, mcpFailures, maxTurnsHit };
+                return { markdown, mcpFailures, maxTurnsHit, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
                 return {
                   markdown: `## Agent Log Summary\n\nError parsing Claude log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
                   mcpFailures: [],
                   maxTurnsHit: false,
+                  logEntries: [],
                 };
               }
             }
diff --git a/.github/workflows/security-fix-pr.lock.yml b/.github/workflows/security-fix-pr.lock.yml
index d01d84e57aa..9ab7599b78d 100644
--- a/.github/workflows/security-fix-pr.lock.yml
+++ b/.github/workflows/security-fix-pr.lock.yml
@@ -3328,81 +3328,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/agent-stdio.log
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -3975,6 +3902,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseClaudeLog,
@@ -3990,6 +4088,7 @@ jobs:
                     markdown: "## Agent Log Summary\n\nLog format not recognized as Claude JSON array or JSONL.\n",
                     mcpFailures: [],
                     maxTurnsHit: false,
+                    logEntries: [],
                   };
                 }
                 const mcpFailures = [];
@@ -4043,13 +4142,14 @@ jobs:
                     maxTurnsHit = true;
                   }
                 }
-                return { markdown, mcpFailures, maxTurnsHit };
+                return { markdown, mcpFailures, maxTurnsHit, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
                 return {
                   markdown: `## Agent Log Summary\n\nError parsing Claude log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
                   mcpFailures: [],
                   maxTurnsHit: false,
+                  logEntries: [],
                 };
               }
             }
diff --git a/.github/workflows/semantic-function-refactor.lock.yml b/.github/workflows/semantic-function-refactor.lock.yml
index 4b7fc416fb1..e1a41b00dbc 100644
--- a/.github/workflows/semantic-function-refactor.lock.yml
+++ b/.github/workflows/semantic-function-refactor.lock.yml
@@ -4098,81 +4098,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/agent-stdio.log
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4745,6 +4672,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseClaudeLog,
@@ -4760,6 +4858,7 @@ jobs:
                     markdown: "## Agent Log Summary\n\nLog format not recognized as Claude JSON array or JSONL.\n",
                     mcpFailures: [],
                     maxTurnsHit: false,
+                    logEntries: [],
                   };
                 }
                 const mcpFailures = [];
@@ -4813,13 +4912,14 @@ jobs:
                     maxTurnsHit = true;
                   }
                 }
-                return { markdown, mcpFailures, maxTurnsHit };
+                return { markdown, mcpFailures, maxTurnsHit, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
                 return {
                   markdown: `## Agent Log Summary\n\nError parsing Claude log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
                   mcpFailures: [],
                   maxTurnsHit: false,
+                  logEntries: [],
                 };
               }
             }
diff --git a/.github/workflows/smoke-claude.lock.yml b/.github/workflows/smoke-claude.lock.yml
index e70f21321fa..410d60da3d4 100644
--- a/.github/workflows/smoke-claude.lock.yml
+++ b/.github/workflows/smoke-claude.lock.yml
@@ -4993,81 +4993,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/agent-stdio.log
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5640,6 +5567,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseClaudeLog,
@@ -5655,6 +5753,7 @@ jobs:
                     markdown: "## Agent Log Summary\n\nLog format not recognized as Claude JSON array or JSONL.\n",
                     mcpFailures: [],
                     maxTurnsHit: false,
+                    logEntries: [],
                   };
                 }
                 const mcpFailures = [];
@@ -5708,13 +5807,14 @@ jobs:
                     maxTurnsHit = true;
                   }
                 }
-                return { markdown, mcpFailures, maxTurnsHit };
+                return { markdown, mcpFailures, maxTurnsHit, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
                 return {
                   markdown: `## Agent Log Summary\n\nError parsing Claude log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
                   mcpFailures: [],
                   maxTurnsHit: false,
+                  logEntries: [],
                 };
               }
             }
diff --git a/.github/workflows/smoke-codex.lock.yml b/.github/workflows/smoke-codex.lock.yml
index f83e00255f8..8747751daeb 100644
--- a/.github/workflows/smoke-codex.lock.yml
+++ b/.github/workflows/smoke-codex.lock.yml
@@ -4559,81 +4559,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/agent-stdio.log
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5206,6 +5133,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCodexLog,
diff --git a/.github/workflows/smoke-copilot-no-firewall.lock.yml b/.github/workflows/smoke-copilot-no-firewall.lock.yml
index b2185c964f7..715c15d6f59 100644
--- a/.github/workflows/smoke-copilot-no-firewall.lock.yml
+++ b/.github/workflows/smoke-copilot-no-firewall.lock.yml
@@ -4643,81 +4643,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/.agent/logs/
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5290,6 +5217,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCopilotLog,
@@ -5331,7 +5429,7 @@ jobs:
                   }
                 }
                 if (!logEntries) {
-                  return "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n";
+                  return { markdown: "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n", logEntries: [] };
                 }
                 const conversationResult = generateConversationMarkdown(logEntries, {
                   formatToolCallback: (toolUse, toolResult) => formatToolUse(toolUse, toolResult, { includeDetailedParameters: true }),
@@ -5383,10 +5481,13 @@ jobs:
                     return "";
                   },
                 });
-                return markdown;
+                return { markdown, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
-                return `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`;
+                return {
+                  markdown: `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
+                  logEntries: [],
+                };
               }
             }
             function scanForToolErrors(logContent) {
diff --git a/.github/workflows/smoke-copilot.lock.yml b/.github/workflows/smoke-copilot.lock.yml
index 7fcb470a6d8..20efdb52986 100644
--- a/.github/workflows/smoke-copilot.lock.yml
+++ b/.github/workflows/smoke-copilot.lock.yml
@@ -4647,81 +4647,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/.agent/logs/
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5294,6 +5221,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCopilotLog,
@@ -5335,7 +5433,7 @@ jobs:
                   }
                 }
                 if (!logEntries) {
-                  return "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n";
+                  return { markdown: "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n", logEntries: [] };
                 }
                 const conversationResult = generateConversationMarkdown(logEntries, {
                   formatToolCallback: (toolUse, toolResult) => formatToolUse(toolUse, toolResult, { includeDetailedParameters: true }),
@@ -5387,10 +5485,13 @@ jobs:
                     return "";
                   },
                 });
-                return markdown;
+                return { markdown, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
-                return `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`;
+                return {
+                  markdown: `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
+                  logEntries: [],
+                };
               }
             }
             function scanForToolErrors(logContent) {
diff --git a/.github/workflows/smoke-detector.lock.yml b/.github/workflows/smoke-detector.lock.yml
index 76f7cbd8979..cd96cd250e2 100644
--- a/.github/workflows/smoke-detector.lock.yml
+++ b/.github/workflows/smoke-detector.lock.yml
@@ -4781,81 +4781,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/agent-stdio.log
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5428,6 +5355,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseClaudeLog,
@@ -5443,6 +5541,7 @@ jobs:
                     markdown: "## Agent Log Summary\n\nLog format not recognized as Claude JSON array or JSONL.\n",
                     mcpFailures: [],
                     maxTurnsHit: false,
+                    logEntries: [],
                   };
                 }
                 const mcpFailures = [];
@@ -5496,13 +5595,14 @@ jobs:
                     maxTurnsHit = true;
                   }
                 }
-                return { markdown, mcpFailures, maxTurnsHit };
+                return { markdown, mcpFailures, maxTurnsHit, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
                 return {
                   markdown: `## Agent Log Summary\n\nError parsing Claude log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
                   mcpFailures: [],
                   maxTurnsHit: false,
+                  logEntries: [],
                 };
               }
             }
diff --git a/.github/workflows/smoke-srt-custom-config.lock.yml b/.github/workflows/smoke-srt-custom-config.lock.yml
index 1e6389c47ad..019f6dd43e4 100644
--- a/.github/workflows/smoke-srt-custom-config.lock.yml
+++ b/.github/workflows/smoke-srt-custom-config.lock.yml
@@ -1063,81 +1063,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/.agent/logs/
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -1710,6 +1637,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCopilotLog,
@@ -1751,7 +1849,7 @@ jobs:
                   }
                 }
                 if (!logEntries) {
-                  return "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n";
+                  return { markdown: "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n", logEntries: [] };
                 }
                 const conversationResult = generateConversationMarkdown(logEntries, {
                   formatToolCallback: (toolUse, toolResult) => formatToolUse(toolUse, toolResult, { includeDetailedParameters: true }),
@@ -1803,10 +1901,13 @@ jobs:
                     return "";
                   },
                 });
-                return markdown;
+                return { markdown, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
-                return `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`;
+                return {
+                  markdown: `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
+                  logEntries: [],
+                };
               }
             }
             function scanForToolErrors(logContent) {
diff --git a/.github/workflows/smoke-srt.lock.yml b/.github/workflows/smoke-srt.lock.yml
index 8c6ab6453bc..9bad9c3e859 100644
--- a/.github/workflows/smoke-srt.lock.yml
+++ b/.github/workflows/smoke-srt.lock.yml
@@ -3081,81 +3081,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/.agent/logs/
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -3728,6 +3655,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCopilotLog,
@@ -3769,7 +3867,7 @@ jobs:
                   }
                 }
                 if (!logEntries) {
-                  return "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n";
+                  return { markdown: "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n", logEntries: [] };
                 }
                 const conversationResult = generateConversationMarkdown(logEntries, {
                   formatToolCallback: (toolUse, toolResult) => formatToolUse(toolUse, toolResult, { includeDetailedParameters: true }),
@@ -3821,10 +3919,13 @@ jobs:
                     return "";
                   },
                 });
-                return markdown;
+                return { markdown, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
-                return `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`;
+                return {
+                  markdown: `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
+                  logEntries: [],
+                };
               }
             }
             function scanForToolErrors(logContent) {
diff --git a/.github/workflows/static-analysis-report.lock.yml b/.github/workflows/static-analysis-report.lock.yml
index 03df89a041a..f462d61caa0 100644
--- a/.github/workflows/static-analysis-report.lock.yml
+++ b/.github/workflows/static-analysis-report.lock.yml
@@ -3868,81 +3868,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/agent-stdio.log
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4515,6 +4442,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseClaudeLog,
@@ -4530,6 +4628,7 @@ jobs:
                     markdown: "## Agent Log Summary\n\nLog format not recognized as Claude JSON array or JSONL.\n",
                     mcpFailures: [],
                     maxTurnsHit: false,
+                    logEntries: [],
                   };
                 }
                 const mcpFailures = [];
@@ -4583,13 +4682,14 @@ jobs:
                     maxTurnsHit = true;
                   }
                 }
-                return { markdown, mcpFailures, maxTurnsHit };
+                return { markdown, mcpFailures, maxTurnsHit, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
                 return {
                   markdown: `## Agent Log Summary\n\nError parsing Claude log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
                   mcpFailures: [],
                   maxTurnsHit: false,
+                  logEntries: [],
                 };
               }
             }
diff --git a/.github/workflows/super-linter.lock.yml b/.github/workflows/super-linter.lock.yml
index e5c2d7bab6a..ad6260dc5a8 100644
--- a/.github/workflows/super-linter.lock.yml
+++ b/.github/workflows/super-linter.lock.yml
@@ -3342,81 +3342,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/.agent/logs/
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -3989,6 +3916,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCopilotLog,
@@ -4030,7 +4128,7 @@ jobs:
                   }
                 }
                 if (!logEntries) {
-                  return "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n";
+                  return { markdown: "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n", logEntries: [] };
                 }
                 const conversationResult = generateConversationMarkdown(logEntries, {
                   formatToolCallback: (toolUse, toolResult) => formatToolUse(toolUse, toolResult, { includeDetailedParameters: true }),
@@ -4082,10 +4180,13 @@ jobs:
                     return "";
                   },
                 });
-                return markdown;
+                return { markdown, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
-                return `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`;
+                return {
+                  markdown: `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
+                  logEntries: [],
+                };
               }
             }
             function scanForToolErrors(logContent) {
diff --git a/.github/workflows/technical-doc-writer.lock.yml b/.github/workflows/technical-doc-writer.lock.yml
index 0ebfc52fee2..1d2fe2de960 100644
--- a/.github/workflows/technical-doc-writer.lock.yml
+++ b/.github/workflows/technical-doc-writer.lock.yml
@@ -4413,81 +4413,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/.agent/logs/
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5060,6 +4987,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCopilotLog,
@@ -5101,7 +5199,7 @@ jobs:
                   }
                 }
                 if (!logEntries) {
-                  return "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n";
+                  return { markdown: "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n", logEntries: [] };
                 }
                 const conversationResult = generateConversationMarkdown(logEntries, {
                   formatToolCallback: (toolUse, toolResult) => formatToolUse(toolUse, toolResult, { includeDetailedParameters: true }),
@@ -5153,10 +5251,13 @@ jobs:
                     return "";
                   },
                 });
-                return markdown;
+                return { markdown, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
-                return `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`;
+                return {
+                  markdown: `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
+                  logEntries: [],
+                };
               }
             }
             function scanForToolErrors(logContent) {
diff --git a/.github/workflows/test-firewall-escape.lock.yml b/.github/workflows/test-firewall-escape.lock.yml
index 424141236ea..462e97b1688 100644
--- a/.github/workflows/test-firewall-escape.lock.yml
+++ b/.github/workflows/test-firewall-escape.lock.yml
@@ -1138,81 +1138,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/.agent/logs/
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -1785,6 +1712,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCopilotLog,
@@ -1826,7 +1924,7 @@ jobs:
                   }
                 }
                 if (!logEntries) {
-                  return "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n";
+                  return { markdown: "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n", logEntries: [] };
                 }
                 const conversationResult = generateConversationMarkdown(logEntries, {
                   formatToolCallback: (toolUse, toolResult) => formatToolUse(toolUse, toolResult, { includeDetailedParameters: true }),
@@ -1878,10 +1976,13 @@ jobs:
                     return "";
                   },
                 });
-                return markdown;
+                return { markdown, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
-                return `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`;
+                return {
+                  markdown: `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
+                  logEntries: [],
+                };
               }
             }
             function scanForToolErrors(logContent) {
diff --git a/.github/workflows/tidy.lock.yml b/.github/workflows/tidy.lock.yml
index 56a13ff89f1..9ac78e04797 100644
--- a/.github/workflows/tidy.lock.yml
+++ b/.github/workflows/tidy.lock.yml
@@ -3536,81 +3536,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/.agent/logs/
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4183,6 +4110,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCopilotLog,
@@ -4224,7 +4322,7 @@ jobs:
                   }
                 }
                 if (!logEntries) {
-                  return "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n";
+                  return { markdown: "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n", logEntries: [] };
                 }
                 const conversationResult = generateConversationMarkdown(logEntries, {
                   formatToolCallback: (toolUse, toolResult) => formatToolUse(toolUse, toolResult, { includeDetailedParameters: true }),
@@ -4276,10 +4374,13 @@ jobs:
                     return "";
                   },
                 });
-                return markdown;
+                return { markdown, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
-                return `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`;
+                return {
+                  markdown: `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
+                  logEntries: [],
+                };
               }
             }
             function scanForToolErrors(logContent) {
diff --git a/.github/workflows/typist.lock.yml b/.github/workflows/typist.lock.yml
index 6714cab0fda..f7a997ac293 100644
--- a/.github/workflows/typist.lock.yml
+++ b/.github/workflows/typist.lock.yml
@@ -4129,81 +4129,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/agent-stdio.log
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4776,6 +4703,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseClaudeLog,
@@ -4791,6 +4889,7 @@ jobs:
                     markdown: "## Agent Log Summary\n\nLog format not recognized as Claude JSON array or JSONL.\n",
                     mcpFailures: [],
                     maxTurnsHit: false,
+                    logEntries: [],
                   };
                 }
                 const mcpFailures = [];
@@ -4844,13 +4943,14 @@ jobs:
                     maxTurnsHit = true;
                   }
                 }
-                return { markdown, mcpFailures, maxTurnsHit };
+                return { markdown, mcpFailures, maxTurnsHit, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
                 return {
                   markdown: `## Agent Log Summary\n\nError parsing Claude log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
                   mcpFailures: [],
                   maxTurnsHit: false,
+                  logEntries: [],
                 };
               }
             }
diff --git a/.github/workflows/unbloat-docs.lock.yml b/.github/workflows/unbloat-docs.lock.yml
index 6f6b128c46e..4f0c6aaebdd 100644
--- a/.github/workflows/unbloat-docs.lock.yml
+++ b/.github/workflows/unbloat-docs.lock.yml
@@ -4914,81 +4914,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/agent-stdio.log
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5561,6 +5488,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseClaudeLog,
@@ -5576,6 +5674,7 @@ jobs:
                     markdown: "## Agent Log Summary\n\nLog format not recognized as Claude JSON array or JSONL.\n",
                     mcpFailures: [],
                     maxTurnsHit: false,
+                    logEntries: [],
                   };
                 }
                 const mcpFailures = [];
@@ -5629,13 +5728,14 @@ jobs:
                     maxTurnsHit = true;
                   }
                 }
-                return { markdown, mcpFailures, maxTurnsHit };
+                return { markdown, mcpFailures, maxTurnsHit, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
                 return {
                   markdown: `## Agent Log Summary\n\nError parsing Claude log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
                   mcpFailures: [],
                   maxTurnsHit: false,
+                  logEntries: [],
                 };
               }
             }
diff --git a/.github/workflows/video-analyzer.lock.yml b/.github/workflows/video-analyzer.lock.yml
index 67551490d90..5674ebb8258 100644
--- a/.github/workflows/video-analyzer.lock.yml
+++ b/.github/workflows/video-analyzer.lock.yml
@@ -3385,81 +3385,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/.agent/logs/
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4032,6 +3959,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCopilotLog,
@@ -4073,7 +4171,7 @@ jobs:
                   }
                 }
                 if (!logEntries) {
-                  return "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n";
+                  return { markdown: "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n", logEntries: [] };
                 }
                 const conversationResult = generateConversationMarkdown(logEntries, {
                   formatToolCallback: (toolUse, toolResult) => formatToolUse(toolUse, toolResult, { includeDetailedParameters: true }),
@@ -4125,10 +4223,13 @@ jobs:
                     return "";
                   },
                 });
-                return markdown;
+                return { markdown, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
-                return `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`;
+                return {
+                  markdown: `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
+                  logEntries: [],
+                };
               }
             }
             function scanForToolErrors(logContent) {
diff --git a/.github/workflows/weekly-issue-summary.lock.yml b/.github/workflows/weekly-issue-summary.lock.yml
index b1b109314e0..d69fdaba59d 100644
--- a/.github/workflows/weekly-issue-summary.lock.yml
+++ b/.github/workflows/weekly-issue-summary.lock.yml
@@ -4129,81 +4129,8 @@ jobs:
           GH_AW_AGENT_OUTPUT: /tmp/gh-aw/.agent/logs/
         with:
           script: |
-            function runLogParser(options) {
-              const fs = require("fs");
-              const path = require("path");
-              const { parseLog, parserName, supportsDirectories = false } = options;
-              try {
-                const logPath = process.env.GH_AW_AGENT_OUTPUT;
-                if (!logPath) {
-                  core.info("No agent log file specified");
-                  return;
-                }
-                if (!fs.existsSync(logPath)) {
-                  core.info(`Log path not found: ${logPath}`);
-                  return;
-                }
-                let content = "";
-                const stat = fs.statSync(logPath);
-                if (stat.isDirectory()) {
-                  if (!supportsDirectories) {
-                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
-                    return;
-                  }
-                  const files = fs.readdirSync(logPath);
-                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
-                  if (logFiles.length === 0) {
-                    core.info(`No log files found in directory: ${logPath}`);
-                    return;
-                  }
-                  logFiles.sort();
-                  for (const file of logFiles) {
-                    const filePath = path.join(logPath, file);
-                    const fileContent = fs.readFileSync(filePath, "utf8");
-                    if (content.length > 0 && !content.endsWith("\n")) {
-                      content += "\n";
-                    }
-                    content += fileContent;
-                  }
-                } else {
-                  content = fs.readFileSync(logPath, "utf8");
-                }
-                const result = parseLog(content);
-                let markdown = "";
-                let mcpFailures = [];
-                let maxTurnsHit = false;
-                if (typeof result === "string") {
-                  markdown = result;
-                } else if (result && typeof result === "object") {
-                  markdown = result.markdown || "";
-                  mcpFailures = result.mcpFailures || [];
-                  maxTurnsHit = result.maxTurnsHit || false;
-                }
-                if (markdown) {
-                  core.info(markdown);
-                  core.summary.addRaw(markdown).write();
-                  core.info(`${parserName} log parsed successfully`);
-                } else {
-                  core.error(`Failed to parse ${parserName} log`);
-                }
-                if (mcpFailures && mcpFailures.length > 0) {
-                  const failedServers = mcpFailures.join(", ");
-                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
-                }
-                if (maxTurnsHit) {
-                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
-                }
-              } catch (error) {
-                core.setFailed(error instanceof Error ? error : String(error));
-              }
-            }
-            if (typeof module !== "undefined" && module.exports) {
-              module.exports = {
-                runLogParser,
-              };
-            }
-            const MAX_TOOL_OUTPUT_LENGTH = 500;
-            const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+            const MAX_TOOL_OUTPUT_LENGTH = 256;
+            const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4776,6 +4703,177 @@ jobs:
               detailsContent = detailsContent.trimEnd();
               return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
             }
+            function generatePlainTextSummary(logEntries, options = {}) {
+              const { model, parserName = "Agent" } = options;
+              const lines = [];
+              lines.push(`=== ${parserName} Execution Summary ===`);
+              if (model) {
+                lines.push(`Model: ${model}`);
+              }
+              lines.push("");
+              const toolUsePairs = new Map();
+              for (const entry of logEntries) {
+                if (entry.type === "user" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_result" && content.tool_use_id) {
+                      toolUsePairs.set(content.tool_use_id, content);
+                    }
+                  }
+                }
+              }
+              const toolCounts = { total: 0, success: 0, error: 0 };
+              const toolSummary = [];
+              for (const entry of logEntries) {
+                if (entry.type === "assistant" && entry.message?.content) {
+                  for (const content of entry.message.content) {
+                    if (content.type === "tool_use") {
+                      const toolName = content.name;
+                      const input = content.input || {};
+                      if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+                        continue;
+                      }
+                      toolCounts.total++;
+                      const toolResult = toolUsePairs.get(content.id);
+                      const isError = toolResult?.is_error === true;
+                      if (isError) {
+                        toolCounts.error++;
+                      } else {
+                        toolCounts.success++;
+                      }
+                      const statusIcon = isError ? "x" : "✓";
+                      let displayName;
+                      if (toolName === "Bash") {
+                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        displayName = `bash: ${cmd}`;
+                      } else if (toolName.startsWith("mcp__")) {
+                        displayName = formatMcpName(toolName);
+                      } else {
+                        displayName = toolName;
+                      }
+                      if (toolSummary.length < 20) {
+                        toolSummary.push(`  [${statusIcon}] ${displayName}`);
+                      }
+                    }
+                  }
+                }
+              }
+              if (toolSummary.length > 0) {
+                lines.push("Tools/Commands:");
+                lines.push(...toolSummary);
+                if (toolCounts.total > 20) {
+                  lines.push(`  ... and ${toolCounts.total - 20} more`);
+                }
+                lines.push("");
+              }
+              const lastEntry = logEntries[logEntries.length - 1];
+              lines.push("Statistics:");
+              if (lastEntry?.num_turns) {
+                lines.push(`  Turns: ${lastEntry.num_turns}`);
+              }
+              if (lastEntry?.duration_ms) {
+                const duration = formatDuration(lastEntry.duration_ms);
+                if (duration) {
+                  lines.push(`  Duration: ${duration}`);
+                }
+              }
+              if (toolCounts.total > 0) {
+                lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+              }
+              if (lastEntry?.usage) {
+                const usage = lastEntry.usage;
+                if (usage.input_tokens && usage.output_tokens) {
+                  lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+                }
+              }
+              if (lastEntry?.total_cost_usd) {
+                lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+              }
+              return lines.join("\n");
+            }
+            function runLogParser(options) {
+              const fs = require("fs");
+              const path = require("path");
+              const { parseLog, parserName, supportsDirectories = false } = options;
+              try {
+                const logPath = process.env.GH_AW_AGENT_OUTPUT;
+                if (!logPath) {
+                  core.info("No agent log file specified");
+                  return;
+                }
+                if (!fs.existsSync(logPath)) {
+                  core.info(`Log path not found: ${logPath}`);
+                  return;
+                }
+                let content = "";
+                const stat = fs.statSync(logPath);
+                if (stat.isDirectory()) {
+                  if (!supportsDirectories) {
+                    core.info(`Log path is a directory but ${parserName} parser does not support directories: ${logPath}`);
+                    return;
+                  }
+                  const files = fs.readdirSync(logPath);
+                  const logFiles = files.filter(file => file.endsWith(".log") || file.endsWith(".txt"));
+                  if (logFiles.length === 0) {
+                    core.info(`No log files found in directory: ${logPath}`);
+                    return;
+                  }
+                  logFiles.sort();
+                  for (const file of logFiles) {
+                    const filePath = path.join(logPath, file);
+                    const fileContent = fs.readFileSync(filePath, "utf8");
+                    if (content.length > 0 && !content.endsWith("\n")) {
+                      content += "\n";
+                    }
+                    content += fileContent;
+                  }
+                } else {
+                  content = fs.readFileSync(logPath, "utf8");
+                }
+                const result = parseLog(content);
+                let markdown = "";
+                let mcpFailures = [];
+                let maxTurnsHit = false;
+                let logEntries = null;
+                if (typeof result === "string") {
+                  markdown = result;
+                } else if (result && typeof result === "object") {
+                  markdown = result.markdown || "";
+                  mcpFailures = result.mcpFailures || [];
+                  maxTurnsHit = result.maxTurnsHit || false;
+                  logEntries = result.logEntries || null;
+                }
+                if (markdown) {
+                  if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+                    const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+                    const model = initEntry?.model || null;
+                    const plainTextSummary = generatePlainTextSummary(logEntries, {
+                      model,
+                      parserName,
+                    });
+                    core.info(plainTextSummary);
+                  } else {
+                    core.info(`${parserName} log parsed successfully`);
+                  }
+                  core.summary.addRaw(markdown).write();
+                } else {
+                  core.error(`Failed to parse ${parserName} log`);
+                }
+                if (mcpFailures && mcpFailures.length > 0) {
+                  const failedServers = mcpFailures.join(", ");
+                  core.setFailed(`MCP server(s) failed to launch: ${failedServers}`);
+                }
+                if (maxTurnsHit) {
+                  core.setFailed(`Agent execution stopped: max-turns limit reached. The agent did not complete its task successfully.`);
+                }
+              } catch (error) {
+                core.setFailed(error instanceof Error ? error : String(error));
+              }
+            }
+            if (typeof module !== "undefined" && module.exports) {
+              module.exports = {
+                runLogParser,
+              };
+            }
             function main() {
               runLogParser({
                 parseLog: parseCopilotLog,
@@ -4817,7 +4915,7 @@ jobs:
                   }
                 }
                 if (!logEntries) {
-                  return "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n";
+                  return { markdown: "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n", logEntries: [] };
                 }
                 const conversationResult = generateConversationMarkdown(logEntries, {
                   formatToolCallback: (toolUse, toolResult) => formatToolUse(toolUse, toolResult, { includeDetailedParameters: true }),
@@ -4869,10 +4967,13 @@ jobs:
                     return "";
                   },
                 });
-                return markdown;
+                return { markdown, logEntries };
               } catch (error) {
                 const errorMessage = error instanceof Error ? error.message : String(error);
-                return `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`;
+                return {
+                  markdown: `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
+                  logEntries: [],
+                };
               }
             }
             function scanForToolErrors(logContent) {
diff --git a/docs/src/content/docs/labs.mdx b/docs/src/content/docs/labs.mdx
index 607839b1daa..c21942c0620 100644
--- a/docs/src/content/docs/labs.mdx
+++ b/docs/src/content/docs/labs.mdx
@@ -37,11 +37,11 @@ These are experimental agentic workflows used by the GitHub Next team to learn,
 | [Daily Issues Report Generator](https://github.com/githubnext/gh-aw/blob/main/.github/workflows/daily-issues-report.md) | codex | [![Daily Issues Report Generator](https://github.com/githubnext/gh-aw/actions/workflows/daily-issues-report.lock.yml/badge.svg)](https://github.com/githubnext/gh-aw/actions/workflows/daily-issues-report.lock.yml) | `0 6 * * *` | - |
 | [Daily Malicious Code Scan Agent](https://github.com/githubnext/gh-aw/blob/main/.github/workflows/daily-malicious-code-scan.md) | copilot | [![Daily Malicious Code Scan Agent](https://github.com/githubnext/gh-aw/actions/workflows/daily-malicious-code-scan.lock.yml/badge.svg)](https://github.com/githubnext/gh-aw/actions/workflows/daily-malicious-code-scan.lock.yml) | `0 9 * * *` | - |
 | [Daily News](https://github.com/githubnext/gh-aw/blob/main/.github/workflows/daily-news.md) | copilot | [![Daily News](https://github.com/githubnext/gh-aw/actions/workflows/daily-news.lock.yml/badge.svg)](https://github.com/githubnext/gh-aw/actions/workflows/daily-news.lock.yml) | `0 9 * * 1-5` | - |
-| [Daily Project Performance Summary Generator (Powered by Skillz)](https://github.com/githubnext/gh-aw/blob/main/.github/workflows/daily-performance-summary.md) | copilot | [![Daily Project Performance Summary Generator (Powered by Skillz)](https://github.com/githubnext/gh-aw/actions/workflows/daily-performance-summary.lock.yml/badge.svg)](https://github.com/githubnext/gh-aw/actions/workflows/daily-performance-summary.lock.yml) | `0 8 * * *` | - |
+| [Daily Project Performance Summary Generator (Using Safe Inputs)](https://github.com/githubnext/gh-aw/blob/main/.github/workflows/daily-performance-summary.md) | codex | [![Daily Project Performance Summary Generator (Using Safe Inputs)](https://github.com/githubnext/gh-aw/actions/workflows/daily-performance-summary.lock.yml/badge.svg)](https://github.com/githubnext/gh-aw/actions/workflows/daily-performance-summary.lock.yml) | `0 8 * * *` | - |
 | [Daily Team Status](https://github.com/githubnext/gh-aw/blob/main/.github/workflows/daily-team-status.md) | copilot | [![Daily Team Status](https://github.com/githubnext/gh-aw/actions/workflows/daily-team-status.lock.yml/badge.svg)](https://github.com/githubnext/gh-aw/actions/workflows/daily-team-status.lock.yml) | - | - |
 | [DeepReport - Intelligence Gathering Agent](https://github.com/githubnext/gh-aw/blob/main/.github/workflows/deep-report.md) | codex | [![DeepReport - Intelligence Gathering Agent](https://github.com/githubnext/gh-aw/actions/workflows/deep-report.lock.yml/badge.svg)](https://github.com/githubnext/gh-aw/actions/workflows/deep-report.lock.yml) | `0 15 * * 1-5` | - |
 | [Dependabot Dependency Checker](https://github.com/githubnext/gh-aw/blob/main/.github/workflows/dependabot-go-checker.md) | copilot | [![Dependabot Dependency Checker](https://github.com/githubnext/gh-aw/actions/workflows/dependabot-go-checker.lock.yml/badge.svg)](https://github.com/githubnext/gh-aw/actions/workflows/dependabot-go-checker.lock.yml) | `0 9 * * 1,3,5` | - |
-| [Dev](https://github.com/githubnext/gh-aw/blob/main/.github/workflows/dev.md) | claude | [![Dev](https://github.com/githubnext/gh-aw/actions/workflows/dev.lock.yml/badge.svg)](https://github.com/githubnext/gh-aw/actions/workflows/dev.lock.yml) | - | - |
+| [Dev](https://github.com/githubnext/gh-aw/blob/main/.github/workflows/dev.md) | codex | [![Dev](https://github.com/githubnext/gh-aw/actions/workflows/dev.lock.yml/badge.svg)](https://github.com/githubnext/gh-aw/actions/workflows/dev.lock.yml) | - | - |
 | [Dev Hawk](https://github.com/githubnext/gh-aw/blob/main/.github/workflows/dev-hawk.md) | copilot | [![Dev Hawk](https://github.com/githubnext/gh-aw/actions/workflows/dev-hawk.lock.yml/badge.svg)](https://github.com/githubnext/gh-aw/actions/workflows/dev-hawk.lock.yml) | - | - |
 | [Developer Documentation Consolidator](https://github.com/githubnext/gh-aw/blob/main/.github/workflows/developer-docs-consolidator.md) | claude | [![Developer Documentation Consolidator](https://github.com/githubnext/gh-aw/actions/workflows/developer-docs-consolidator.lock.yml/badge.svg)](https://github.com/githubnext/gh-aw/actions/workflows/developer-docs-consolidator.lock.yml) | `17 3 * * *` | - |
 | [Dictation Prompt Generator](https://github.com/githubnext/gh-aw/blob/main/.github/workflows/dictation-prompt.md) | copilot | [![Dictation Prompt Generator](https://github.com/githubnext/gh-aw/actions/workflows/dictation-prompt.lock.yml/badge.svg)](https://github.com/githubnext/gh-aw/actions/workflows/dictation-prompt.lock.yml) | `0 6 * * 0` | - |
diff --git a/pkg/workflow/js/log_parser_bootstrap.cjs b/pkg/workflow/js/log_parser_bootstrap.cjs
index a4d3dafa79a..188a084edb6 100644
--- a/pkg/workflow/js/log_parser_bootstrap.cjs
+++ b/pkg/workflow/js/log_parser_bootstrap.cjs
@@ -1,13 +1,15 @@
 // @ts-check
 /// <reference types="@actions/github-script" />
 
+const { generatePlainTextSummary } = require("./log_parser_shared.cjs");
+
 /**
  * Bootstrap helper for log parser entry points.
  * Handles common logic for environment variable lookup, file existence checks,
  * content reading (file or directory), and summary emission.
  *
  * @param {Object} options - Configuration options
- * @param {function(string): string|{markdown: string, mcpFailures?: string[], maxTurnsHit?: boolean}} options.parseLog - Parser function that takes log content and returns markdown or result object
+ * @param {function(string): string|{markdown: string, mcpFailures?: string[], maxTurnsHit?: boolean, logEntries?: Array}} options.parseLog - Parser function that takes log content and returns markdown or result object
  * @param {string} options.parserName - Name of the parser (e.g., "Codex", "Claude", "Copilot")
  * @param {boolean} [options.supportsDirectories=false] - Whether the parser supports reading from directories
  * @returns {void}
@@ -74,6 +76,7 @@ function runLogParser(options) {
     let markdown = "";
     let mcpFailures = [];
     let maxTurnsHit = false;
+    let logEntries = null;
 
     if (typeof result === "string") {
       markdown = result;
@@ -81,12 +84,28 @@ function runLogParser(options) {
       markdown = result.markdown || "";
       mcpFailures = result.mcpFailures || [];
       maxTurnsHit = result.maxTurnsHit || false;
+      logEntries = result.logEntries || null;
     }
 
     if (markdown) {
-      core.info(markdown);
+      // Generate lightweight plain text summary for core.info instead of full markdown
+      if (logEntries && Array.isArray(logEntries) && logEntries.length > 0) {
+        // Extract model from init entry if available
+        const initEntry = logEntries.find(entry => entry.type === "system" && entry.subtype === "init");
+        const model = initEntry?.model || null;
+
+        const plainTextSummary = generatePlainTextSummary(logEntries, {
+          model,
+          parserName,
+        });
+        core.info(plainTextSummary);
+      } else {
+        // Fallback: just log success message for parsers without log entries
+        core.info(`${parserName} log parsed successfully`);
+      }
+
+      // Write full markdown to step summary
       core.summary.addRaw(markdown).write();
-      core.info(`${parserName} log parsed successfully`);
     } else {
       core.error(`Failed to parse ${parserName} log`);
     }
diff --git a/pkg/workflow/js/log_parser_bootstrap.test.cjs b/pkg/workflow/js/log_parser_bootstrap.test.cjs
index 775ae7a1ef3..8fabab010d1 100644
--- a/pkg/workflow/js/log_parser_bootstrap.test.cjs
+++ b/pkg/workflow/js/log_parser_bootstrap.test.cjs
@@ -88,10 +88,10 @@ describe("log_parser_bootstrap.cjs", () => {
       });
 
       expect(mockParseLog).toHaveBeenCalledWith(logContent);
-      expect(mockCore.info).toHaveBeenCalledWith("## Parsed Log\n\nSuccess!");
+      // When no logEntries are returned (string result), we log success message
+      expect(mockCore.info).toHaveBeenCalledWith("TestParser log parsed successfully");
       expect(mockCore.summary.addRaw).toHaveBeenCalledWith("## Parsed Log\n\nSuccess!");
       expect(mockCore.summary.write).toHaveBeenCalled();
-      expect(mockCore.info).toHaveBeenCalledWith("TestParser log parsed successfully");
 
       // Cleanup
       fs.unlinkSync(logFile);
@@ -116,7 +116,8 @@ describe("log_parser_bootstrap.cjs", () => {
         parserName: "TestParser",
       });
 
-      expect(mockCore.info).toHaveBeenCalledWith("## Result\n");
+      // When no logEntries are returned, we log success message
+      expect(mockCore.info).toHaveBeenCalledWith("TestParser log parsed successfully");
       expect(mockCore.summary.addRaw).toHaveBeenCalledWith("## Result\n");
       expect(mockCore.setFailed).not.toHaveBeenCalled();
 
@@ -124,6 +125,42 @@ describe("log_parser_bootstrap.cjs", () => {
       fs.rmdirSync(tmpDir);
     });
 
+    it("should generate plain text summary when logEntries are available", () => {
+      const tmpDir = fs.mkdtempSync(path.join(__dirname, "test-"));
+      const logFile = path.join(tmpDir, "test.log");
+      fs.writeFileSync(logFile, "content");
+
+      process.env.GH_AW_AGENT_OUTPUT = logFile;
+
+      const mockLogEntries = [
+        { type: "system", subtype: "init", model: "gpt-5" },
+        { type: "assistant", message: { content: [{ type: "text", text: "Hello" }] } },
+        { type: "result", num_turns: 2, duration_ms: 5000 },
+      ];
+
+      const mockParseLog = vi.fn().mockReturnValue({
+        markdown: "## Result\n",
+        mcpFailures: [],
+        maxTurnsHit: false,
+        logEntries: mockLogEntries,
+      });
+
+      runLogParser({
+        parseLog: mockParseLog,
+        parserName: "TestParser",
+      });
+
+      // Should generate plain text summary instead of success message
+      const infoCall = mockCore.info.mock.calls.find(call => call[0].includes("=== TestParser Execution Summary ==="));
+      expect(infoCall).toBeDefined();
+      expect(infoCall[0]).toContain("Model: gpt-5");
+      expect(infoCall[0]).toContain("Turns: 2");
+      expect(mockCore.summary.addRaw).toHaveBeenCalledWith("## Result\n");
+
+      fs.unlinkSync(logFile);
+      fs.rmdirSync(tmpDir);
+    });
+
     it("should handle MCP failures", () => {
       const tmpDir = fs.mkdtempSync(path.join(__dirname, "test-"));
       const logFile = path.join(tmpDir, "test.log");
diff --git a/pkg/workflow/js/log_parser_shared.cjs b/pkg/workflow/js/log_parser_shared.cjs
index f439e57f110..6001d489cd7 100644
--- a/pkg/workflow/js/log_parser_shared.cjs
+++ b/pkg/workflow/js/log_parser_shared.cjs
@@ -9,15 +9,16 @@
 /**
  * Maximum length for tool output content in characters.
  * Tool output/response sections are truncated to this length to keep step summaries readable.
+ * Reduced from 500 to 256 for more compact output.
  */
-const MAX_TOOL_OUTPUT_LENGTH = 500;
+const MAX_TOOL_OUTPUT_LENGTH = 256;
 
 /**
- * Maximum step summary size in bytes (8MB).
- * GitHub Actions step summaries have a size limit. We stop rendering additional content
- * when approaching this limit to prevent workflow failures.
+ * Maximum step summary size in bytes (1000KB).
+ * GitHub Actions step summaries have a limit of 1024KB. We use 1000KB to leave buffer space.
+ * We stop rendering additional content when approaching this limit to prevent workflow failures.
  */
-const MAX_STEP_SUMMARY_SIZE = 8 * 1024 * 1024;
+const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
 
 /**
  * Warning message shown when step summary size limit is reached.
@@ -935,6 +936,130 @@ function formatToolCallAsDetails(options) {
   return `<details>\n<summary>${fullSummary}</summary>\n\n${detailsContent}\n</details>\n\n`;
 }
 
+/**
+ * Generates a lightweight plain text summary optimized for raw text rendering.
+ * This is designed for console output (core.info) instead of markdown step summaries.
+ *
+ * The output includes:
+ * - A compact header with model info
+ * - Tool/command summary list (status icon + name only)
+ * - Basic execution statistics
+ *
+ * @param {Array} logEntries - Array of log entries with type, message, etc.
+ * @param {Object} options - Configuration options
+ * @param {string} [options.model] - Model name to include in the header
+ * @param {string} [options.parserName] - Name of the parser (e.g., "Copilot", "Claude")
+ * @returns {string} Plain text summary for console output
+ */
+function generatePlainTextSummary(logEntries, options = {}) {
+  const { model, parserName = "Agent" } = options;
+  const lines = [];
+
+  // Header
+  lines.push(`=== ${parserName} Execution Summary ===`);
+  if (model) {
+    lines.push(`Model: ${model}`);
+  }
+  lines.push("");
+
+  // Collect tool usage summary
+  const toolUsePairs = new Map();
+  for (const entry of logEntries) {
+    if (entry.type === "user" && entry.message?.content) {
+      for (const content of entry.message.content) {
+        if (content.type === "tool_result" && content.tool_use_id) {
+          toolUsePairs.set(content.tool_use_id, content);
+        }
+      }
+    }
+  }
+
+  // Count tools and gather summary
+  const toolCounts = { total: 0, success: 0, error: 0 };
+  const toolSummary = [];
+
+  for (const entry of logEntries) {
+    if (entry.type === "assistant" && entry.message?.content) {
+      for (const content of entry.message.content) {
+        if (content.type === "tool_use") {
+          const toolName = content.name;
+          const input = content.input || {};
+
+          // Skip internal tools
+          if (["Read", "Write", "Edit", "MultiEdit", "LS", "Grep", "Glob", "TodoWrite"].includes(toolName)) {
+            continue;
+          }
+
+          toolCounts.total++;
+          const toolResult = toolUsePairs.get(content.id);
+          const isError = toolResult?.is_error === true;
+
+          if (isError) {
+            toolCounts.error++;
+          } else {
+            toolCounts.success++;
+          }
+
+          const statusIcon = isError ? "x" : "✓";
+
+          // Format tool name compactly
+          let displayName;
+          if (toolName === "Bash") {
+            const cmd = formatBashCommand(input.command || "").slice(0, 40);
+            displayName = `bash: ${cmd}`;
+          } else if (toolName.startsWith("mcp__")) {
+            displayName = formatMcpName(toolName);
+          } else {
+            displayName = toolName;
+          }
+
+          // Limit to 20 tool summaries
+          if (toolSummary.length < 20) {
+            toolSummary.push(`  [${statusIcon}] ${displayName}`);
+          }
+        }
+      }
+    }
+  }
+
+  // Tool summary section
+  if (toolSummary.length > 0) {
+    lines.push("Tools/Commands:");
+    lines.push(...toolSummary);
+    if (toolCounts.total > 20) {
+      lines.push(`  ... and ${toolCounts.total - 20} more`);
+    }
+    lines.push("");
+  }
+
+  // Statistics
+  const lastEntry = logEntries[logEntries.length - 1];
+  lines.push("Statistics:");
+  if (lastEntry?.num_turns) {
+    lines.push(`  Turns: ${lastEntry.num_turns}`);
+  }
+  if (lastEntry?.duration_ms) {
+    const duration = formatDuration(lastEntry.duration_ms);
+    if (duration) {
+      lines.push(`  Duration: ${duration}`);
+    }
+  }
+  if (toolCounts.total > 0) {
+    lines.push(`  Tools: ${toolCounts.success}/${toolCounts.total} succeeded`);
+  }
+  if (lastEntry?.usage) {
+    const usage = lastEntry.usage;
+    if (usage.input_tokens && usage.output_tokens) {
+      lines.push(`  Tokens: ${usage.input_tokens.toLocaleString()} in / ${usage.output_tokens.toLocaleString()} out`);
+    }
+  }
+  if (lastEntry?.total_cost_usd) {
+    lines.push(`  Cost: $${lastEntry.total_cost_usd.toFixed(4)}`);
+  }
+
+  return lines.join("\n");
+}
+
 // Export functions and constants
 module.exports = {
   // Constants
@@ -956,4 +1081,5 @@ module.exports = {
   formatToolUse,
   parseLogEntries,
   formatToolCallAsDetails,
+  generatePlainTextSummary,
 };
diff --git a/pkg/workflow/js/log_parser_shared.test.cjs b/pkg/workflow/js/log_parser_shared.test.cjs
index 401e8579a36..3d9a260b25a 100644
--- a/pkg/workflow/js/log_parser_shared.test.cjs
+++ b/pkg/workflow/js/log_parser_shared.test.cjs
@@ -1170,12 +1170,12 @@ describe("log_parser_shared.cjs", () => {
         sections: [{ label: "Response", content: longContent }],
       });
 
-      // Should contain truncated content (500 chars) plus "... (truncated)"
+      // Should contain truncated content (256 chars) plus "... (truncated)"
       expect(result).toContain("... (truncated)");
       expect(result.length).toBeLessThan(longContent.length + 200);
 
-      // Verify truncation happens at MAX_TOOL_OUTPUT_LENGTH (500)
-      expect(MAX_TOOL_OUTPUT_LENGTH).toBe(500);
+      // Verify truncation happens at MAX_TOOL_OUTPUT_LENGTH (256)
+      expect(MAX_TOOL_OUTPUT_LENGTH).toBe(256);
     });
 
     it("should allow custom maxContentLength", async () => {
@@ -1270,9 +1270,9 @@ describe("log_parser_shared.cjs", () => {
 
       const tracker = new StepSummaryTracker();
 
-      // Default is 8MB
-      expect(MAX_STEP_SUMMARY_SIZE).toBe(8 * 1024 * 1024);
-      expect(tracker.maxSize).toBe(8 * 1024 * 1024);
+      // Default is 1000KB
+      expect(MAX_STEP_SUMMARY_SIZE).toBe(1000 * 1024);
+      expect(tracker.maxSize).toBe(1000 * 1024);
     });
   });
 
@@ -1327,14 +1327,147 @@ describe("log_parser_shared.cjs", () => {
   });
 
   describe("constants", () => {
-    it("should export MAX_TOOL_OUTPUT_LENGTH as 500", async () => {
+    it("should export MAX_TOOL_OUTPUT_LENGTH as 256", async () => {
       const { MAX_TOOL_OUTPUT_LENGTH } = await import("./log_parser_shared.cjs");
-      expect(MAX_TOOL_OUTPUT_LENGTH).toBe(500);
+      expect(MAX_TOOL_OUTPUT_LENGTH).toBe(256);
     });
 
-    it("should export MAX_STEP_SUMMARY_SIZE as 8MB", async () => {
+    it("should export MAX_STEP_SUMMARY_SIZE as 1000KB", async () => {
       const { MAX_STEP_SUMMARY_SIZE } = await import("./log_parser_shared.cjs");
-      expect(MAX_STEP_SUMMARY_SIZE).toBe(8 * 1024 * 1024);
+      expect(MAX_STEP_SUMMARY_SIZE).toBe(1000 * 1024);
+    });
+  });
+
+  describe("generatePlainTextSummary", () => {
+    it("should generate plain text summary with model info", async () => {
+      const { generatePlainTextSummary } = await import("./log_parser_shared.cjs");
+
+      const logEntries = [
+        { type: "system", subtype: "init", model: "gpt-5" },
+        { type: "result", num_turns: 3, duration_ms: 60000 },
+      ];
+
+      const result = generatePlainTextSummary(logEntries, {
+        model: "gpt-5",
+        parserName: "TestParser",
+      });
+
+      expect(result).toContain("=== TestParser Execution Summary ===");
+      expect(result).toContain("Model: gpt-5");
+      expect(result).toContain("Turns: 3");
+      expect(result).toContain("Duration: 1m");
+    });
+
+    it("should include tool usage statistics", async () => {
+      const { generatePlainTextSummary } = await import("./log_parser_shared.cjs");
+
+      const logEntries = [
+        { type: "system", subtype: "init", model: "test-model" },
+        {
+          type: "assistant",
+          message: {
+            content: [
+              { type: "tool_use", id: "1", name: "Bash", input: { command: "echo test" } },
+              { type: "tool_use", id: "2", name: "mcp__github__create_issue", input: {} },
+            ],
+          },
+        },
+        {
+          type: "user",
+          message: {
+            content: [
+              { type: "tool_result", tool_use_id: "1", is_error: false },
+              { type: "tool_result", tool_use_id: "2", is_error: true },
+            ],
+          },
+        },
+        { type: "result", num_turns: 1 },
+      ];
+
+      const result = generatePlainTextSummary(logEntries, { parserName: "Agent" });
+
+      expect(result).toContain("Tools/Commands:");
+      expect(result).toContain("[✓] bash: echo test");
+      expect(result).toContain("[x] github::create_issue");
+      expect(result).toContain("Tools: 1/2 succeeded");
+    });
+
+    it("should limit tool summaries to 20 items", async () => {
+      const { generatePlainTextSummary } = await import("./log_parser_shared.cjs");
+
+      // Create 25 tool uses
+      const toolUses = [];
+      const toolResults = [];
+      for (let i = 0; i < 25; i++) {
+        toolUses.push({ type: "tool_use", id: `${i}`, name: "Bash", input: { command: `cmd${i}` } });
+        toolResults.push({ type: "tool_result", tool_use_id: `${i}`, is_error: false });
+      }
+
+      const logEntries = [
+        { type: "system", subtype: "init" },
+        { type: "assistant", message: { content: toolUses } },
+        { type: "user", message: { content: toolResults } },
+        { type: "result", num_turns: 1 },
+      ];
+
+      const result = generatePlainTextSummary(logEntries, { parserName: "Agent" });
+
+      expect(result).toContain("... and 5 more");
+    });
+
+    it("should include token usage and cost", async () => {
+      const { generatePlainTextSummary } = await import("./log_parser_shared.cjs");
+
+      const logEntries = [
+        { type: "system", subtype: "init" },
+        {
+          type: "result",
+          num_turns: 2,
+          usage: { input_tokens: 1000, output_tokens: 500 },
+          total_cost_usd: 0.0025,
+        },
+      ];
+
+      const result = generatePlainTextSummary(logEntries, { parserName: "Agent" });
+
+      expect(result).toContain("Tokens: 1,000 in / 500 out");
+      expect(result).toContain("Cost: $0.0025");
+    });
+
+    it("should skip internal tools in summary", async () => {
+      const { generatePlainTextSummary } = await import("./log_parser_shared.cjs");
+
+      const logEntries = [
+        { type: "system", subtype: "init" },
+        {
+          type: "assistant",
+          message: {
+            content: [
+              { type: "tool_use", id: "1", name: "Read", input: {} },
+              { type: "tool_use", id: "2", name: "Write", input: {} },
+              { type: "tool_use", id: "3", name: "Bash", input: { command: "test" } },
+            ],
+          },
+        },
+        {
+          type: "user",
+          message: {
+            content: [
+              { type: "tool_result", tool_use_id: "1", is_error: false },
+              { type: "tool_result", tool_use_id: "2", is_error: false },
+              { type: "tool_result", tool_use_id: "3", is_error: false },
+            ],
+          },
+        },
+        { type: "result" },
+      ];
+
+      const result = generatePlainTextSummary(logEntries, { parserName: "Agent" });
+
+      // Should only show Bash, not Read or Write
+      expect(result).toContain("bash: test");
+      expect(result).not.toContain("Read");
+      expect(result).not.toContain("Write");
     });
   });
 });
diff --git a/pkg/workflow/js/parse_claude_log.cjs b/pkg/workflow/js/parse_claude_log.cjs
index 583cc423016..33d467153b0 100644
--- a/pkg/workflow/js/parse_claude_log.cjs
+++ b/pkg/workflow/js/parse_claude_log.cjs
@@ -21,7 +21,7 @@ function main() {
 /**
  * Parses Claude log content and converts it to markdown format
  * @param {string} logContent - The raw log content as a string
- * @returns {{markdown: string, mcpFailures: string[], maxTurnsHit: boolean}} Result with formatted markdown content, MCP failure list, and max-turns status
+ * @returns {{markdown: string, mcpFailures: string[], maxTurnsHit: boolean, logEntries: Array}} Result with formatted markdown content, MCP failure list, max-turns status, and parsed log entries
  */
 function parseClaudeLog(logContent) {
   try {
@@ -33,6 +33,7 @@ function parseClaudeLog(logContent) {
         markdown: "## Agent Log Summary\n\nLog format not recognized as Claude JSON array or JSONL.\n",
         mcpFailures: [],
         maxTurnsHit: false,
+        logEntries: [],
       };
     }
 
@@ -107,13 +108,14 @@ function parseClaudeLog(logContent) {
       }
     }
 
-    return { markdown, mcpFailures, maxTurnsHit };
+    return { markdown, mcpFailures, maxTurnsHit, logEntries };
   } catch (error) {
     const errorMessage = error instanceof Error ? error.message : String(error);
     return {
       markdown: `## Agent Log Summary\n\nError parsing Claude log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
       mcpFailures: [],
       maxTurnsHit: false,
+      logEntries: [],
     };
   }
 }
diff --git a/pkg/workflow/js/parse_claude_log.test.cjs b/pkg/workflow/js/parse_claude_log.test.cjs
index e989017b9d8..3392dcf423e 100644
--- a/pkg/workflow/js/parse_claude_log.test.cjs
+++ b/pkg/workflow/js/parse_claude_log.test.cjs
@@ -571,11 +571,11 @@ npm warn exec The following package was not found
       expect(markdownCall[0]).toContain("🚀 Initialization");
       expect(markdownCall[0]).toContain("integration-test");
 
-      // Verify that core.info was also called with the same content (via write helper)
+      // Verify that core.info was called with plain text summary (contains parser name and model info)
       expect(mockCore.info).toHaveBeenCalled();
-      const infoCall = mockCore.info.mock.calls.find(call => call[0].includes("🚀 Initialization"));
+      const infoCall = mockCore.info.mock.calls.find(call => call[0].includes("=== Claude Execution Summary ==="));
       expect(infoCall).toBeDefined();
-      expect(infoCall[0]).toContain("integration-test");
+      expect(infoCall[0]).toContain("Model: claude-sonnet-4-20250514");
     });
 
     it("should handle log with MCP failures", async () => {
diff --git a/pkg/workflow/js/parse_copilot_log.cjs b/pkg/workflow/js/parse_copilot_log.cjs
index ebf517c6d5d..207f454ae14 100644
--- a/pkg/workflow/js/parse_copilot_log.cjs
+++ b/pkg/workflow/js/parse_copilot_log.cjs
@@ -73,7 +73,7 @@ function parseCopilotLog(logContent) {
     }
 
     if (!logEntries) {
-      return "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n";
+      return { markdown: "## Agent Log Summary\n\nLog format not recognized as Copilot JSON array or JSONL.\n", logEntries: [] };
     }
 
     // Generate conversation markdown using shared function
@@ -141,10 +141,13 @@ function parseCopilotLog(logContent) {
       },
     });
 
-    return markdown;
+    return { markdown, logEntries };
   } catch (error) {
     const errorMessage = error instanceof Error ? error.message : String(error);
-    return `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`;
+    return {
+      markdown: `## Agent Log Summary\n\nError parsing Copilot log (tried both JSON array and JSONL formats): ${errorMessage}\n`,
+      logEntries: [],
+    };
   }
 }
 
diff --git a/pkg/workflow/js/parse_copilot_log.test.cjs b/pkg/workflow/js/parse_copilot_log.test.cjs
index 85872294574..bb3a14cb459 100644
--- a/pkg/workflow/js/parse_copilot_log.test.cjs
+++ b/pkg/workflow/js/parse_copilot_log.test.cjs
@@ -183,13 +183,13 @@ describe("parse_copilot_log.cjs", () => {
 
       const result = parseCopilotLog(jsonArrayLog);
 
-      expect(result).toContain("🚀 Initialization");
-      expect(result).toContain("🤖 Commands and Tools");
-      expect(result).toContain("copilot-test-123");
-      expect(result).toContain("echo 'Hello World'");
-      expect(result).toContain("Total Cost");
-      expect(result).toContain("<details>");
-      expect(result).toContain("<summary>");
+      expect(result.markdown).toContain("🚀 Initialization");
+      expect(result.markdown).toContain("🤖 Commands and Tools");
+      expect(result.markdown).toContain("copilot-test-123");
+      expect(result.markdown).toContain("echo 'Hello World'");
+      expect(result.markdown).toContain("Total Cost");
+      expect(result.markdown).toContain("<details>");
+      expect(result.markdown).toContain("<summary>");
     });
 
     it("should parse mixed format with debug logs and JSON array", () => {
@@ -200,11 +200,11 @@ describe("parse_copilot_log.cjs", () => {
 
       const result = parseCopilotLog(mixedFormatLog);
 
-      expect(result).toContain("🚀 Initialization");
-      expect(result).toContain("🤖 Commands and Tools");
-      expect(result).toContain("copilot-456");
-      expect(result).toContain("safe_outputs::missing-tool");
-      expect(result).toContain("Total Cost");
+      expect(result.markdown).toContain("🚀 Initialization");
+      expect(result.markdown).toContain("🤖 Commands and Tools");
+      expect(result.markdown).toContain("copilot-456");
+      expect(result.markdown).toContain("safe_outputs::missing-tool");
+      expect(result.markdown).toContain("Total Cost");
     });
 
     it("should parse mixed format with individual JSON lines (JSONL)", () => {
@@ -218,11 +218,11 @@ describe("parse_copilot_log.cjs", () => {
 
       const result = parseCopilotLog(jsonlFormatLog);
 
-      expect(result).toContain("🚀 Initialization");
-      expect(result).toContain("🤖 Commands and Tools");
-      expect(result).toContain("copilot-789");
-      expect(result).toContain("ls -la");
-      expect(result).toContain("Total Cost");
+      expect(result.markdown).toContain("🚀 Initialization");
+      expect(result.markdown).toContain("🤖 Commands and Tools");
+      expect(result.markdown).toContain("copilot-789");
+      expect(result.markdown).toContain("ls -la");
+      expect(result.markdown).toContain("Total Cost");
     });
 
     it("should handle tool calls with details in HTML format", () => {
@@ -264,30 +264,30 @@ describe("parse_copilot_log.cjs", () => {
       const result = parseCopilotLog(logWithToolOutput);
 
       // Should contain HTML details tag
-      expect(result).toContain("<details>");
-      expect(result).toContain("<summary>");
-      expect(result).toContain("</summary>");
-      expect(result).toContain("</details>");
+      expect(result.markdown).toContain("<details>");
+      expect(result.markdown).toContain("<summary>");
+      expect(result.markdown).toContain("</summary>");
+      expect(result.markdown).toContain("</details>");
 
       // Summary should contain the command
-      expect(result).toContain("cat README.md");
+      expect(result.markdown).toContain("cat README.md");
 
       // Details should contain the output
-      expect(result).toContain("Project Title");
+      expect(result.markdown).toContain("Project Title");
 
       // Should use 6 backticks (not 5) for code blocks
-      expect(result).toContain("``````json");
-      expect(result).toMatch(/``````\n#/); // Response content should start after 6 backticks
+      expect(result.markdown).toContain("``````json");
+      expect(result.markdown).toMatch(/``````\n#/); // Response content should start after 6 backticks
 
       // Should have Parameters and Response sections
-      expect(result).toContain("**Parameters:**");
-      expect(result).toContain("**Response:**");
+      expect(result.markdown).toContain("**Parameters:**");
+      expect(result.markdown).toContain("**Response:**");
 
       // Parameters should be formatted as JSON
-      expect(result).toContain("``````json");
+      expect(result.markdown).toContain("``````json");
 
       // Verify the structure contains both parameter and response sections
-      const detailsMatch = result.match(/<details>[\s\S]*?<\/details>/);
+      const detailsMatch = result.markdown.match(/<details>[\s\S]*?<\/details>/);
       expect(detailsMatch).toBeDefined();
       const detailsContent = detailsMatch[0];
       expect(detailsContent).toContain("**Parameters:**");
@@ -328,8 +328,8 @@ describe("parse_copilot_log.cjs", () => {
 
       const result = parseCopilotLog(logWithMcpTools);
 
-      expect(result).toContain("github::create_issue");
-      expect(result).toContain("safe_outputs::missing-tool");
+      expect(result.markdown).toContain("github::create_issue");
+      expect(result.markdown).toContain("safe_outputs::missing-tool");
     });
 
     it("should handle unrecognized log format", () => {
@@ -337,13 +337,13 @@ describe("parse_copilot_log.cjs", () => {
 
       const result = parseCopilotLog(invalidLog);
 
-      expect(result).toContain("Log format not recognized");
+      expect(result.markdown).toContain("Log format not recognized");
     });
 
     it("should handle empty log content", () => {
       const result = parseCopilotLog("");
 
-      expect(result).toContain("Log format not recognized");
+      expect(result.markdown).toContain("Log format not recognized");
     });
 
     it("should skip internal file operations in summary", () => {
@@ -378,8 +378,8 @@ describe("parse_copilot_log.cjs", () => {
       const result = parseCopilotLog(logWithInternalTools);
 
       // Commands and Tools section should only show Bash
-      expect(result).toContain("🤖 Commands and Tools");
-      const commandsSection = result.split("📊 Information")[0];
+      expect(result.markdown).toContain("🤖 Commands and Tools");
+      const commandsSection = result.markdown.split("📊 Information")[0];
       expect(commandsSection).toContain("echo test");
       // Read and Write should not be in the summary
       expect(commandsSection.split("🤖 Reasoning")[0]).not.toContain("Read");
@@ -404,10 +404,10 @@ describe("parse_copilot_log.cjs", () => {
       const result = parseCopilotLog(logWithTextMessage);
 
       // Text should be rendered directly in the Reasoning section
-      expect(result).toContain("🤖 Reasoning");
-      expect(result).toContain("Let me analyze the code");
-      expect(result).toContain("## Analysis");
-      expect(result).toContain("could use some improvements");
+      expect(result.markdown).toContain("🤖 Reasoning");
+      expect(result.markdown).toContain("Let me analyze the code");
+      expect(result.markdown).toContain("## Analysis");
+      expect(result.markdown).toContain("could use some improvements");
     });
 
     it("should parse debug log format with tool calls and mark them as successful", () => {
@@ -459,18 +459,18 @@ describe("parse_copilot_log.cjs", () => {
       const result = parseCopilotLog(debugLogFormat);
 
       // Should successfully parse the debug log format
-      expect(result).toContain("🤖 Commands and Tools");
-      expect(result).toContain("echo 'Hello World'");
-      expect(result).toContain("github::search_issues");
+      expect(result.markdown).toContain("🤖 Commands and Tools");
+      expect(result.markdown).toContain("echo 'Hello World'");
+      expect(result.markdown).toContain("github::search_issues");
 
       // CRITICAL: Tools should be marked as successful (✅) not unknown (❓)
       // This is the fix for the issue - parseDebugLogFormat now creates tool_result entries
-      expect(result).toContain("✅");
-      expect(result).not.toContain("❓ `echo");
-      expect(result).not.toContain("❓ `github::search_issues");
+      expect(result.markdown).toContain("✅");
+      expect(result.markdown).not.toContain("❓ `echo");
+      expect(result.markdown).not.toContain("❓ `github::search_issues");
 
       // Check that the tool calls are in the Commands and Tools section with success icon
-      const commandsSection = result.split("📊 Information")[0];
+      const commandsSection = result.markdown.split("📊 Information")[0];
       expect(commandsSection).toContain("✅ `echo 'Hello World'`");
       expect(commandsSection).toContain("✅ `github::search_issues(...)`");
     });
@@ -530,10 +530,10 @@ describe("parse_copilot_log.cjs", () => {
       const result = parseCopilotLog(debugLogWithModelInfo);
 
       // Should successfully parse and display premium model information
-      expect(result).toContain("🚀 Initialization");
-      expect(result).toContain("**Model Name:** Claude Sonnet 4 (Anthropic)");
-      expect(result).toContain("**Premium Model:** Yes");
-      expect(result).toContain("**Required Plans:** pro, pro_plus, max, business, enterprise");
+      expect(result.markdown).toContain("🚀 Initialization");
+      expect(result.markdown).toContain("**Model Name:** Claude Sonnet 4 (Anthropic)");
+      expect(result.markdown).toContain("**Premium Model:** Yes");
+      expect(result.markdown).toContain("**Required Plans:** pro, pro_plus, max, business, enterprise");
     });
 
     it("should handle non-premium models in debug logs", () => {
@@ -560,8 +560,8 @@ describe("parse_copilot_log.cjs", () => {
       const result = parseCopilotLog(debugLogNonPremium);
 
       // Should display non-premium model information
-      expect(result).toContain("**Model Name:** GPT-4o (OpenAI)");
-      expect(result).toContain("**Premium Model:** No");
+      expect(result.markdown).toContain("**Model Name:** GPT-4o (OpenAI)");
+      expect(result.markdown).toContain("**Premium Model:** No");
     });
 
     it("should handle model info with cost multiplier", () => {
@@ -589,8 +589,8 @@ describe("parse_copilot_log.cjs", () => {
       const result = parseCopilotLog(debugLogWithMultiplier);
 
       // Should display cost multiplier
-      expect(result).toContain("**Premium Model:** Yes (2.5x cost multiplier)");
-      expect(result).toContain("**Required Plans:** enterprise");
+      expect(result.markdown).toContain("**Premium Model:** Yes (2.5x cost multiplier)");
+      expect(result.markdown).toContain("**Required Plans:** enterprise");
     });
 
     it("should display premium requests consumed for premium models", () => {
@@ -653,11 +653,11 @@ describe("parse_copilot_log.cjs", () => {
       const result = parseCopilotLog(structuredLog);
 
       // Should display premium requests consumed (always 1 per workflow run, regardless of num_turns)
-      expect(result).toContain("**Premium Requests Consumed:** 1");
-      expect(result).toContain("**Turns:** 5");
-      expect(result).toContain("**Token Usage:**");
-      expect(result).toContain("- Input: 1,000");
-      expect(result).toContain("- Output: 250");
+      expect(result.markdown).toContain("**Premium Requests Consumed:** 1");
+      expect(result.markdown).toContain("**Turns:** 5");
+      expect(result.markdown).toContain("**Token Usage:**");
+      expect(result.markdown).toContain("- Input: 1,000");
+      expect(result.markdown).toContain("- Output: 250");
     });
 
     it("should not display premium requests for non-premium models", () => {
@@ -692,9 +692,9 @@ describe("parse_copilot_log.cjs", () => {
       const result = parseCopilotLog(structuredLog);
 
       // Should NOT display premium requests consumed
-      expect(result).not.toContain("Premium Requests Consumed");
-      expect(result).toContain("**Turns:** 3");
-      expect(result).toContain("**Token Usage:**");
+      expect(result.markdown).not.toContain("Premium Requests Consumed");
+      expect(result.markdown).toContain("**Turns:** 3");
+      expect(result.markdown).toContain("**Token Usage:**");
     });
 
     it("should display 1 premium request consumed regardless of number of turns", () => {
@@ -743,9 +743,9 @@ describe("parse_copilot_log.cjs", () => {
       const result = parseCopilotLog(structuredLog);
 
       // Should display 1 premium request consumed (default when not specified in log)
-      expect(result).toContain("**Premium Requests Consumed:** 1");
-      expect(result).toContain("**Turns:** 17");
-      expect(result).toContain("**Token Usage:**");
+      expect(result.markdown).toContain("**Premium Requests Consumed:** 1");
+      expect(result.markdown).toContain("**Turns:** 17");
+      expect(result.markdown).toContain("**Token Usage:**");
     });
 
     it("should accumulate token usage across multiple API responses in debug logs", () => {
@@ -791,12 +791,12 @@ describe("parse_copilot_log.cjs", () => {
       const result = parseCopilotLog(debugLogWith2Responses);
 
       // Should show accumulated tokens: 100+200=300 input, 50+10=60 output
-      expect(result).toContain("**Token Usage:**");
-      expect(result).toContain("- Input: 300");
-      expect(result).toContain("- Output: 60");
+      expect(result.markdown).toContain("**Token Usage:**");
+      expect(result.markdown).toContain("- Input: 300");
+      expect(result.markdown).toContain("- Output: 60");
 
       // Should have 2 turns
-      expect(result).toContain("**Turns:** 2");
+      expect(result.markdown).toContain("**Turns:** 2");
     });
 
     it("should extract premium request count from log content using regex", () => {
@@ -836,8 +836,8 @@ More log content
       const result = parseCopilotLog(logWithPremiumInfo);
 
       // Should extract 3 from the log content
-      expect(result).toContain("**Premium Requests Consumed:** 3");
-      expect(result).toContain("**Turns:** 10");
+      expect(result.markdown).toContain("**Premium Requests Consumed:** 3");
+      expect(result.markdown).toContain("**Turns:** 10");
     });
   });
 
@@ -910,11 +910,11 @@ More log content
       expect(markdownCall[0]).toContain("🚀 Initialization");
       expect(markdownCall[0]).toContain("integration-test");
 
-      // Verify that core.info was also called with the same content
+      // Verify that core.info was called with plain text summary (contains parser name and model info)
       expect(mockCore.info).toHaveBeenCalled();
-      const infoCall = mockCore.info.mock.calls.find(call => call[0].includes("🚀 Initialization"));
+      const infoCall = mockCore.info.mock.calls.find(call => call[0].includes("=== Copilot Execution Summary ==="));
       expect(infoCall).toBeDefined();
-      expect(infoCall[0]).toContain("integration-test");
+      expect(infoCall[0]).toContain("Model: gpt-5");
     });
 
     it("should handle missing log file", async () => {
@@ -967,7 +967,7 @@ More log content
       const result = parseCopilotLog(logWithCommand);
 
       // Check that multi-line commands are normalized to single line
-      expect(result).toContain("echo 'hello world' && ls -la && pwd");
+      expect(result.markdown).toContain("echo 'hello world' && ls -la && pwd");
     });
 
     it("should truncate long strings appropriately", () => {
@@ -993,7 +993,7 @@ More log content
       const result = parseCopilotLog(logWithLongCommand);
 
       // Should truncate and add ellipsis
-      expect(result).toContain("...");
+      expect(result.markdown).toContain("...");
     });
 
     it("should format MCP tool names correctly", () => {
@@ -1017,7 +1017,7 @@ More log content
 
       const result = parseCopilotLog(logWithMcpTool);
 
-      expect(result).toContain("github::create_pull_request");
+      expect(result.markdown).toContain("github::create_pull_request");
     });
 
     it("should extract tools from debug log format", () => {
@@ -1096,24 +1096,24 @@ More log content
       const result = parseCopilotLog(debugLogWithTools);
 
       // Check that tools were extracted and displayed
-      expect(result).toContain("**Available Tools:**");
-      expect(result).toContain("bash");
+      expect(result.markdown).toContain("**Available Tools:**");
+      expect(result.markdown).toContain("bash");
       // Tools are displayed in formatted form (github::create_issue) not internal form (mcp__github__create_issue)
-      expect(result).toContain("github::create_issue");
+      expect(result.markdown).toContain("github::create_issue");
       // safe_outputs tools are shown without prefix in Safe Outputs category
-      expect(result).toContain("**Safe Outputs:**");
-      expect(result).toContain("create_issue");
+      expect(result.markdown).toContain("**Safe Outputs:**");
+      expect(result.markdown).toContain("create_issue");
 
       // Verify tool categories are shown
-      expect(result).toContain("**Git/GitHub:**");
-      expect(result).toContain("**Builtin:**");
+      expect(result.markdown).toContain("**Git/GitHub:**");
+      expect(result.markdown).toContain("**Builtin:**");
 
       // Check that the model info was extracted
-      expect(result).toContain("Claude Sonnet 4.5");
-      expect(result).toContain("**Premium Model:** Yes");
+      expect(result.markdown).toContain("Claude Sonnet 4.5");
+      expect(result.markdown).toContain("**Premium Model:** Yes");
 
       // Check that tool calls are displayed
-      expect(result).toContain("echo test");
+      expect(result.markdown).toContain("echo test");
     });
 
     it("should detect permission denied errors in tool calls from debug logs", () => {
@@ -1171,10 +1171,10 @@ More log content
       const result = parseCopilotLog(debugLogWithPermissionError);
 
       // Should detect the permission error and mark the tool call as failed
-      expect(result).toContain("github::create_issue");
+      expect(result.markdown).toContain("github::create_issue");
 
       // The tool should be marked with ❌ (failed) instead of ✅ (success)
-      const commandsSection = result.split("📊 Information")[0];
+      const commandsSection = result.markdown.split("📊 Information")[0];
       expect(commandsSection).toContain("❌");
       expect(commandsSection).toContain("❌ `github::create_issue(...)`");
 
@@ -1216,32 +1216,32 @@ More log content
       const result = parseCopilotLog(logWithManyTools);
 
       // Verify all GitHub tools are shown (not just first 3 with "and X more")
-      expect(result).toContain("github::create_issue");
-      expect(result).toContain("github::list_issues");
-      expect(result).toContain("github::get_issue");
-      expect(result).toContain("github::create_pull_request");
-      expect(result).toContain("github::list_pull_requests");
-      expect(result).toContain("github::get_pull_request");
-      expect(result).toContain("github::create_discussion");
-      expect(result).toContain("github::list_discussions");
+      expect(result.markdown).toContain("github::create_issue");
+      expect(result.markdown).toContain("github::list_issues");
+      expect(result.markdown).toContain("github::get_issue");
+      expect(result.markdown).toContain("github::create_pull_request");
+      expect(result.markdown).toContain("github::list_pull_requests");
+      expect(result.markdown).toContain("github::get_pull_request");
+      expect(result.markdown).toContain("github::create_discussion");
+      expect(result.markdown).toContain("github::list_discussions");
 
       // Verify safe_outputs tools are shown (without prefix, in Safe Outputs category)
-      expect(result).toContain("**Safe Outputs:**");
-      expect(result).toContain("create_issue");
-      expect(result).toContain("add-comment");
+      expect(result.markdown).toContain("**Safe Outputs:**");
+      expect(result.markdown).toContain("create_issue");
+      expect(result.markdown).toContain("add-comment");
 
       // Verify file operations are shown
-      expect(result).toContain("Read");
-      expect(result).toContain("Write");
-      expect(result).toContain("Edit");
-      expect(result).toContain("LS");
-      expect(result).toContain("Grep");
+      expect(result.markdown).toContain("Read");
+      expect(result.markdown).toContain("Write");
+      expect(result.markdown).toContain("Edit");
+      expect(result.markdown).toContain("LS");
+      expect(result.markdown).toContain("Grep");
 
       // Verify Bash is shown
-      expect(result).toContain("Bash");
+      expect(result.markdown).toContain("Bash");
 
       // Ensure we don't have "and X more" text in the tools list (the pattern used to truncate tool lists)
-      const toolsSection = result.split("## 🤖 Reasoning")[0];
+      const toolsSection = result.markdown.split("## 🤖 Reasoning")[0];
       expect(toolsSection).not.toMatch(/and \d+ more/);
     });
   });
diff --git a/pkg/workflow/neutral_tools_integration_test.go b/pkg/workflow/neutral_tools_integration_test.go
index b2e37fde74e..686db4c5b4b 100644
--- a/pkg/workflow/neutral_tools_integration_test.go
+++ b/pkg/workflow/neutral_tools_integration_test.go
@@ -97,9 +97,14 @@ Test workflow with neutral tools format.
 		}
 	}
 
-	// Verify that the old format is not present in the compiled output (excluding comments)
-	if strings.Contains(yamlContentNoComments, "bash:") || strings.Contains(yamlContentNoComments, "web-fetch:") {
-		t.Error("Compiled YAML should not contain neutral tool names directly")
+	// Verify that the old format is not present as YAML keys in the compiled output (excluding comments)
+	// The check is for YAML keys specifically, not string literals in bundled JavaScript code
+	// YAML keys will have format like "  bash:" or "\nbash:" at the start of a line
+	if strings.Contains(yamlContentNoComments, "\n  bash:") ||
+		strings.Contains(yamlContentNoComments, "\nbash:") ||
+		strings.Contains(yamlContentNoComments, "\n  web-fetch:") ||
+		strings.Contains(yamlContentNoComments, "\nweb-fetch:") {
+		t.Error("Compiled YAML should not contain neutral tool names as YAML keys")
 	}
 }
 
diff --git a/pkg/workflow/test_data/expected_claude_baseline.md b/pkg/workflow/test_data/expected_claude_baseline.md
index d8389baf600..6ed1e40d2b8 100644
--- a/pkg/workflow/test_data/expected_claude_baseline.md
+++ b/pkg/workflow/test_data/expected_claude_baseline.md
@@ -44,13 +44,7 @@ I'll help you try to call the `draw_pelican` tool. Let me first check if there's
      5→
      6→## Steps to Complete
      7→1. ✓ Check for existing plan (found previous attempt)
-     8→2. ✓ Read existing plan
-     9→3. ✓ Confirm tool is missing
-    10→4. ✓ Report missing tool using safe-outputs
-    11→
-    12→## Discoveries
-    13→- Previous attempt confirmed `draw_pelican` tool does not exist
-    14→- Need to report missing functionali... (truncated)
+     8→2. ✓ Read e... (truncated)
 ``````
 </details>
 
@@ -80,13 +74,7 @@ The file /tmp/gh-aw/cache-memory/plan.md has been updated. Here's the result of
      1→# Execution Plan: Draw Pelican Tool
      2→
      3→## Objective
-     4→Try to call a tool called `draw_pelican` that draws a pelican.
-     5→
-     6→## Steps to Complete
-     7→1. ✓ Check for existing plan (found previous attempt)
-     8→2. ✓ Read existing plan
-     9→3. ✓ Confirm tool is missing (attempted call - tool does not exist)
-    10→4. ✓ Report missing... (truncated)
+     4→Try to call a tool called `draw_pelican` that dr... (truncated)
 ``````
 </details>
 

From 677c94c4ac92ef327d734ffbff2570da48fde0a5 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 1 Dec 2025 01:04:47 +0000
Subject: [PATCH 4/4] Address code review feedback
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

- Update documentation comment to reflect new 256 char limit
- Add MAX_BASH_COMMAND_DISPLAY_LENGTH constant (40)
- Use ✗ instead of x for error status icon for better console compatibility

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
---
 .github/workflows/ai-triage-campaign.lock.yml |  5 +-
 .github/workflows/archie.lock.yml             |  5 +-
 .github/workflows/artifacts-summary.lock.yml  |  5 +-
 .github/workflows/audit-workflows.lock.yml    |  5 +-
 .github/workflows/blog-auditor.lock.yml       |  5 +-
 .github/workflows/brave.lock.yml              |  5 +-
 .../breaking-change-checker.lock.yml          |  5 +-
 .github/workflows/changeset.lock.yml          |  5 +-
 .github/workflows/ci-doctor.lock.yml          |  5 +-
 .../cli-consistency-checker.lock.yml          |  5 +-
 .../workflows/cli-version-checker.lock.yml    |  5 +-
 .github/workflows/cloclo.lock.yml             |  5 +-
 .../workflows/close-old-discussions.lock.yml  |  5 +-
 .../commit-changes-analyzer.lock.yml          |  5 +-
 .../workflows/copilot-agent-analysis.lock.yml |  5 +-
 .../copilot-pr-nlp-analysis.lock.yml          |  5 +-
 .../copilot-pr-prompt-analysis.lock.yml       |  5 +-
 .../copilot-session-insights.lock.yml         |  5 +-
 .github/workflows/craft.lock.yml              |  5 +-
 .github/workflows/daily-code-metrics.lock.yml |  5 +-
 .github/workflows/daily-doc-updater.lock.yml  |  5 +-
 .github/workflows/daily-fact.lock.yml         |  5 +-
 .github/workflows/daily-file-diet.lock.yml    |  5 +-
 .../workflows/daily-firewall-report.lock.yml  |  5 +-
 .../workflows/daily-issues-report.lock.yml    |  5 +-
 .../daily-malicious-code-scan.lock.yml        |  5 +-
 .../daily-multi-device-docs-tester.lock.yml   |  5 +-
 .github/workflows/daily-news.lock.yml         |  5 +-
 .../daily-performance-summary.lock.yml        | 17 ++--
 .../workflows/daily-repo-chronicle.lock.yml   |  5 +-
 .github/workflows/deep-report.lock.yml        |  5 +-
 .../workflows/dependabot-go-checker.lock.yml  |  5 +-
 .github/workflows/dev-hawk.lock.yml           |  5 +-
 .github/workflows/dev.lock.yml                | 87 ++++++++++---------
 .../developer-docs-consolidator.lock.yml      |  5 +-
 .github/workflows/dictation-prompt.lock.yml   |  5 +-
 .github/workflows/docs-noob-tester.lock.yml   |  5 +-
 .../duplicate-code-detector.lock.yml          |  5 +-
 .../example-permissions-warning.lock.yml      |  5 +-
 .../example-workflow-analyzer.lock.yml        |  5 +-
 .github/workflows/firewall.lock.yml           |  5 +-
 .../github-mcp-structural-analysis.lock.yml   |  5 +-
 .../github-mcp-tools-report.lock.yml          |  5 +-
 .../workflows/glossary-maintainer.lock.yml    |  5 +-
 .github/workflows/go-fan.lock.yml             |  5 +-
 .github/workflows/go-logger.lock.yml          |  5 +-
 .../workflows/go-pattern-detector.lock.yml    |  5 +-
 .github/workflows/grumpy-reviewer.lock.yml    |  5 +-
 .../workflows/instructions-janitor.lock.yml   |  5 +-
 .github/workflows/issue-arborist.lock.yml     |  5 +-
 .github/workflows/issue-monster.lock.yml      |  5 +-
 .github/workflows/issue-triage-agent.lock.yml |  5 +-
 .github/workflows/lockfile-stats.lock.yml     |  5 +-
 .github/workflows/mcp-inspector.lock.yml      |  5 +-
 .github/workflows/mergefest.lock.yml          |  5 +-
 .../workflows/notion-issue-summary.lock.yml   |  5 +-
 .github/workflows/pdf-summary.lock.yml        |  5 +-
 .github/workflows/plan.lock.yml               |  5 +-
 .github/workflows/poem-bot.lock.yml           |  5 +-
 .../workflows/pr-nitpick-reviewer.lock.yml    |  5 +-
 .../prompt-clustering-analysis.lock.yml       |  5 +-
 .github/workflows/python-data-charts.lock.yml |  5 +-
 .github/workflows/q.lock.yml                  |  5 +-
 .github/workflows/release.lock.yml            |  5 +-
 .github/workflows/repo-tree-map.lock.yml      |  5 +-
 .../repository-quality-improver.lock.yml      |  5 +-
 .github/workflows/research.lock.yml           |  5 +-
 .github/workflows/safe-output-health.lock.yml |  5 +-
 .../schema-consistency-checker.lock.yml       |  5 +-
 .github/workflows/scout.lock.yml              |  5 +-
 .github/workflows/security-fix-pr.lock.yml    |  5 +-
 .../semantic-function-refactor.lock.yml       |  5 +-
 .github/workflows/smoke-claude.lock.yml       |  5 +-
 .github/workflows/smoke-codex.lock.yml        |  5 +-
 .../smoke-copilot-no-firewall.lock.yml        |  5 +-
 .github/workflows/smoke-copilot.lock.yml      |  5 +-
 .github/workflows/smoke-detector.lock.yml     |  5 +-
 .../smoke-srt-custom-config.lock.yml          |  5 +-
 .github/workflows/smoke-srt.lock.yml          |  5 +-
 .../workflows/static-analysis-report.lock.yml |  5 +-
 .github/workflows/super-linter.lock.yml       |  5 +-
 .../workflows/technical-doc-writer.lock.yml   |  5 +-
 .../workflows/test-firewall-escape.lock.yml   |  5 +-
 .github/workflows/tidy.lock.yml               |  5 +-
 .github/workflows/typist.lock.yml             |  5 +-
 .github/workflows/unbloat-docs.lock.yml       |  5 +-
 .github/workflows/video-analyzer.lock.yml     |  5 +-
 .../workflows/weekly-issue-summary.lock.yml   |  5 +-
 pkg/workflow/js/log_parser_shared.cjs         | 12 ++-
 pkg/workflow/js/log_parser_shared.test.cjs    |  2 +-
 90 files changed, 321 insertions(+), 227 deletions(-)

diff --git a/.github/workflows/ai-triage-campaign.lock.yml b/.github/workflows/ai-triage-campaign.lock.yml
index 808e2dd01d6..5e32289f5da 100644
--- a/.github/workflows/ai-triage-campaign.lock.yml
+++ b/.github/workflows/ai-triage-campaign.lock.yml
@@ -2951,6 +2951,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -3560,10 +3561,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/archie.lock.yml b/.github/workflows/archie.lock.yml
index 35e5aaf794e..f9426f55005 100644
--- a/.github/workflows/archie.lock.yml
+++ b/.github/workflows/archie.lock.yml
@@ -4592,6 +4592,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5201,10 +5202,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/artifacts-summary.lock.yml b/.github/workflows/artifacts-summary.lock.yml
index 2b95f800d88..d9fa053d95e 100644
--- a/.github/workflows/artifacts-summary.lock.yml
+++ b/.github/workflows/artifacts-summary.lock.yml
@@ -3121,6 +3121,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -3730,10 +3731,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/audit-workflows.lock.yml b/.github/workflows/audit-workflows.lock.yml
index 674bf7cf235..94a74799cdb 100644
--- a/.github/workflows/audit-workflows.lock.yml
+++ b/.github/workflows/audit-workflows.lock.yml
@@ -4594,6 +4594,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5203,10 +5204,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/blog-auditor.lock.yml b/.github/workflows/blog-auditor.lock.yml
index 136f3f507b4..973ec47575c 100644
--- a/.github/workflows/blog-auditor.lock.yml
+++ b/.github/workflows/blog-auditor.lock.yml
@@ -3718,6 +3718,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4327,10 +4328,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/brave.lock.yml b/.github/workflows/brave.lock.yml
index 2d21cb78880..d39d884b767 100644
--- a/.github/workflows/brave.lock.yml
+++ b/.github/workflows/brave.lock.yml
@@ -4383,6 +4383,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4992,10 +4993,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/breaking-change-checker.lock.yml b/.github/workflows/breaking-change-checker.lock.yml
index 085e94cd7a5..72002519dc5 100644
--- a/.github/workflows/breaking-change-checker.lock.yml
+++ b/.github/workflows/breaking-change-checker.lock.yml
@@ -3187,6 +3187,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -3796,10 +3797,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/changeset.lock.yml b/.github/workflows/changeset.lock.yml
index 6a30840ec6e..0a3756c7dd6 100644
--- a/.github/workflows/changeset.lock.yml
+++ b/.github/workflows/changeset.lock.yml
@@ -4091,6 +4091,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4700,10 +4701,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/ci-doctor.lock.yml b/.github/workflows/ci-doctor.lock.yml
index ba75567993b..99ff4bb9333 100644
--- a/.github/workflows/ci-doctor.lock.yml
+++ b/.github/workflows/ci-doctor.lock.yml
@@ -3857,6 +3857,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4466,10 +4467,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/cli-consistency-checker.lock.yml b/.github/workflows/cli-consistency-checker.lock.yml
index 752186da19d..592d08d4855 100644
--- a/.github/workflows/cli-consistency-checker.lock.yml
+++ b/.github/workflows/cli-consistency-checker.lock.yml
@@ -3201,6 +3201,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -3810,10 +3811,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/cli-version-checker.lock.yml b/.github/workflows/cli-version-checker.lock.yml
index 310910ce1b2..1ac4f82bb53 100644
--- a/.github/workflows/cli-version-checker.lock.yml
+++ b/.github/workflows/cli-version-checker.lock.yml
@@ -3530,6 +3530,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4139,10 +4140,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/cloclo.lock.yml b/.github/workflows/cloclo.lock.yml
index 2c36c1f00da..eee2081f2ff 100644
--- a/.github/workflows/cloclo.lock.yml
+++ b/.github/workflows/cloclo.lock.yml
@@ -5166,6 +5166,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5775,10 +5776,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/close-old-discussions.lock.yml b/.github/workflows/close-old-discussions.lock.yml
index 8a949b06294..3d2965f026d 100644
--- a/.github/workflows/close-old-discussions.lock.yml
+++ b/.github/workflows/close-old-discussions.lock.yml
@@ -3360,6 +3360,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -3969,10 +3970,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/commit-changes-analyzer.lock.yml b/.github/workflows/commit-changes-analyzer.lock.yml
index f79eeb22b9b..131d4707e4d 100644
--- a/.github/workflows/commit-changes-analyzer.lock.yml
+++ b/.github/workflows/commit-changes-analyzer.lock.yml
@@ -3600,6 +3600,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4209,10 +4210,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/copilot-agent-analysis.lock.yml b/.github/workflows/copilot-agent-analysis.lock.yml
index 9588b7c522f..e4a882ed1ef 100644
--- a/.github/workflows/copilot-agent-analysis.lock.yml
+++ b/.github/workflows/copilot-agent-analysis.lock.yml
@@ -4281,6 +4281,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4890,10 +4891,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/copilot-pr-nlp-analysis.lock.yml b/.github/workflows/copilot-pr-nlp-analysis.lock.yml
index 0d46fb68e41..a66f44393f6 100644
--- a/.github/workflows/copilot-pr-nlp-analysis.lock.yml
+++ b/.github/workflows/copilot-pr-nlp-analysis.lock.yml
@@ -4672,6 +4672,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5281,10 +5282,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/copilot-pr-prompt-analysis.lock.yml b/.github/workflows/copilot-pr-prompt-analysis.lock.yml
index fb25f3589d4..579bc9b41fb 100644
--- a/.github/workflows/copilot-pr-prompt-analysis.lock.yml
+++ b/.github/workflows/copilot-pr-prompt-analysis.lock.yml
@@ -3761,6 +3761,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4370,10 +4371,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/copilot-session-insights.lock.yml b/.github/workflows/copilot-session-insights.lock.yml
index c130b86c664..6b8c92fe393 100644
--- a/.github/workflows/copilot-session-insights.lock.yml
+++ b/.github/workflows/copilot-session-insights.lock.yml
@@ -6221,6 +6221,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -6830,10 +6831,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/craft.lock.yml b/.github/workflows/craft.lock.yml
index 4120d4045d3..c48eda1da89 100644
--- a/.github/workflows/craft.lock.yml
+++ b/.github/workflows/craft.lock.yml
@@ -4729,6 +4729,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5338,10 +5339,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/daily-code-metrics.lock.yml b/.github/workflows/daily-code-metrics.lock.yml
index cb036317054..e6601e7f4ce 100644
--- a/.github/workflows/daily-code-metrics.lock.yml
+++ b/.github/workflows/daily-code-metrics.lock.yml
@@ -4731,6 +4731,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5340,10 +5341,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/daily-doc-updater.lock.yml b/.github/workflows/daily-doc-updater.lock.yml
index c258aafcdc1..ae78fc1f9f2 100644
--- a/.github/workflows/daily-doc-updater.lock.yml
+++ b/.github/workflows/daily-doc-updater.lock.yml
@@ -3398,6 +3398,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4007,10 +4008,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/daily-fact.lock.yml b/.github/workflows/daily-fact.lock.yml
index 91eb0d308ef..e9ba12121ec 100644
--- a/.github/workflows/daily-fact.lock.yml
+++ b/.github/workflows/daily-fact.lock.yml
@@ -3476,6 +3476,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4085,10 +4086,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/daily-file-diet.lock.yml b/.github/workflows/daily-file-diet.lock.yml
index 3b8fe350aa0..1b9fb4a7f2b 100644
--- a/.github/workflows/daily-file-diet.lock.yml
+++ b/.github/workflows/daily-file-diet.lock.yml
@@ -3441,6 +3441,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4050,10 +4051,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/daily-firewall-report.lock.yml b/.github/workflows/daily-firewall-report.lock.yml
index 9e3ca2a4743..602b957832f 100644
--- a/.github/workflows/daily-firewall-report.lock.yml
+++ b/.github/workflows/daily-firewall-report.lock.yml
@@ -4174,6 +4174,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4783,10 +4784,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/daily-issues-report.lock.yml b/.github/workflows/daily-issues-report.lock.yml
index 30661d6c803..220e79fc3bb 100644
--- a/.github/workflows/daily-issues-report.lock.yml
+++ b/.github/workflows/daily-issues-report.lock.yml
@@ -4954,6 +4954,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5563,10 +5564,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/daily-malicious-code-scan.lock.yml b/.github/workflows/daily-malicious-code-scan.lock.yml
index 513413cee8f..82fb1580d97 100644
--- a/.github/workflows/daily-malicious-code-scan.lock.yml
+++ b/.github/workflows/daily-malicious-code-scan.lock.yml
@@ -3426,6 +3426,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4035,10 +4036,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/daily-multi-device-docs-tester.lock.yml b/.github/workflows/daily-multi-device-docs-tester.lock.yml
index 64a5a26693b..dcb551c8009 100644
--- a/.github/workflows/daily-multi-device-docs-tester.lock.yml
+++ b/.github/workflows/daily-multi-device-docs-tester.lock.yml
@@ -3300,6 +3300,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -3909,10 +3910,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/daily-news.lock.yml b/.github/workflows/daily-news.lock.yml
index 879de379dc5..9b36394aa25 100644
--- a/.github/workflows/daily-news.lock.yml
+++ b/.github/workflows/daily-news.lock.yml
@@ -4729,6 +4729,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5338,10 +5339,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/daily-performance-summary.lock.yml b/.github/workflows/daily-performance-summary.lock.yml
index c155695f7cd..c7d08128e81 100644
--- a/.github/workflows/daily-performance-summary.lock.yml
+++ b/.github/workflows/daily-performance-summary.lock.yml
@@ -2383,9 +2383,6 @@ jobs:
             registerTool("github-issue-query", "Query GitHub issues with jq filtering support. Without --jq, returns schema and data size info. Use --jq '.' to get all data, or specific jq expressions to filter.", {"properties":{"jq":{"description":"jq filter expression to apply to output. If not provided, returns schema info instead of full data.","type":"string"},"limit":{"description":"Maximum number of issues to fetch (default: 30)","type":"number"},"repo":{"description":"Repository in owner/repo format (defaults to current repository)","type":"string"},"state":{"description":"Issue state: open, closed, all (default: open)","type":"string"}},"type":"object"}, async (args) => {
               try {
                 const env = { ...process.env };
-                if (args && args["repo"] !== undefined) {
-                  env["INPUT_REPO"] = typeof args["repo"] === "object" ? JSON.stringify(args["repo"]) : String(args["repo"]);
-                }
                 if (args && args["state"] !== undefined) {
                   env["INPUT_STATE"] = typeof args["state"] === "object" ? JSON.stringify(args["state"]) : String(args["state"]);
                 }
@@ -2395,6 +2392,9 @@ jobs:
                 if (args && args["limit"] !== undefined) {
                   env["INPUT_LIMIT"] = typeof args["limit"] === "object" ? JSON.stringify(args["limit"]) : String(args["limit"]);
                 }
+                if (args && args["repo"] !== undefined) {
+                  env["INPUT_REPO"] = typeof args["repo"] === "object" ? JSON.stringify(args["repo"]) : String(args["repo"]);
+                }
                 const scriptPath = path.join(__dirname, "github-issue-query.sh");
                 const { stdout, stderr } = await execFileAsync("bash", [scriptPath], { env });
                 const output = stdout + (stderr ? "\nStderr: " + stderr : "");
@@ -2406,6 +2406,9 @@ jobs:
             registerTool("github-pr-query", "Query GitHub pull requests with jq filtering support. Without --jq, returns schema and data size info. Use --jq '.' to get all data, or specific jq expressions to filter.", {"properties":{"jq":{"description":"jq filter expression to apply to output. If not provided, returns schema info instead of full data.","type":"string"},"limit":{"description":"Maximum number of PRs to fetch (default: 30)","type":"number"},"repo":{"description":"Repository in owner/repo format (defaults to current repository)","type":"string"},"state":{"description":"PR state: open, closed, merged, all (default: open)","type":"string"}},"type":"object"}, async (args) => {
               try {
                 const env = { ...process.env };
+                if (args && args["state"] !== undefined) {
+                  env["INPUT_STATE"] = typeof args["state"] === "object" ? JSON.stringify(args["state"]) : String(args["state"]);
+                }
                 if (args && args["jq"] !== undefined) {
                   env["INPUT_JQ"] = typeof args["jq"] === "object" ? JSON.stringify(args["jq"]) : String(args["jq"]);
                 }
@@ -2415,9 +2418,6 @@ jobs:
                 if (args && args["repo"] !== undefined) {
                   env["INPUT_REPO"] = typeof args["repo"] === "object" ? JSON.stringify(args["repo"]) : String(args["repo"]);
                 }
-                if (args && args["state"] !== undefined) {
-                  env["INPUT_STATE"] = typeof args["state"] === "object" ? JSON.stringify(args["state"]) : String(args["state"]);
-                }
                 const scriptPath = path.join(__dirname, "github-pr-query.sh");
                 const { stdout, stderr } = await execFileAsync("bash", [scriptPath], { env });
                 const output = stdout + (stderr ? "\nStderr: " + stderr : "");
@@ -4969,6 +4969,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5578,10 +5579,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/daily-repo-chronicle.lock.yml b/.github/workflows/daily-repo-chronicle.lock.yml
index 190be0cd6ae..f0dc31ef94a 100644
--- a/.github/workflows/daily-repo-chronicle.lock.yml
+++ b/.github/workflows/daily-repo-chronicle.lock.yml
@@ -4274,6 +4274,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4883,10 +4884,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/deep-report.lock.yml b/.github/workflows/deep-report.lock.yml
index 8cd2e81c5d1..45dbcdbb472 100644
--- a/.github/workflows/deep-report.lock.yml
+++ b/.github/workflows/deep-report.lock.yml
@@ -3895,6 +3895,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4504,10 +4505,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/dependabot-go-checker.lock.yml b/.github/workflows/dependabot-go-checker.lock.yml
index 69f6fbb3430..20eaf907016 100644
--- a/.github/workflows/dependabot-go-checker.lock.yml
+++ b/.github/workflows/dependabot-go-checker.lock.yml
@@ -3721,6 +3721,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4330,10 +4331,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/dev-hawk.lock.yml b/.github/workflows/dev-hawk.lock.yml
index 5c03e6a1c06..6dbd3c81df0 100644
--- a/.github/workflows/dev-hawk.lock.yml
+++ b/.github/workflows/dev-hawk.lock.yml
@@ -3627,6 +3627,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4236,10 +4237,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/dev.lock.yml b/.github/workflows/dev.lock.yml
index 3c4a651c27e..c733f864169 100644
--- a/.github/workflows/dev.lock.yml
+++ b/.github/workflows/dev.lock.yml
@@ -1480,12 +1480,27 @@ jobs:
             function registerTool(name, description, inputSchema, handler) {
               tools[name] = { name, description, inputSchema, handler };
             }
+            registerTool("test-js-string", "Test JavaScript string operations", {"properties":{"text":{"description":"Input text","type":"string"}},"required":["text"],"type":"object"}, async (args) => {
+              try {
+                const toolModule = require("./test-js-string.cjs");
+                const result = await toolModule.execute(args || {});
+                return { content: [{ type: "text", text: typeof result === "string" ? result : JSON.stringify(result, null, 2) }] };
+              } catch (error) {
+                return { content: [{ type: "text", text: "Error: " + (error instanceof Error ? error.message : String(error)) }], isError: true };
+              }
+            });
+            registerTool("test-js-math", "Test JavaScript math operations", {"properties":{"a":{"description":"First number","type":"number"},"b":{"description":"Second number","type":"number"}},"required":["a","b"],"type":"object"}, async (args) => {
+              try {
+                const toolModule = require("./test-js-math.cjs");
+                const result = await toolModule.execute(args || {});
+                return { content: [{ type: "text", text: typeof result === "string" ? result : JSON.stringify(result, null, 2) }] };
+              } catch (error) {
+                return { content: [{ type: "text", text: "Error: " + (error instanceof Error ? error.message : String(error)) }], isError: true };
+              }
+            });
             registerTool("fetch-pr-data", "Fetches pull request data from GitHub using gh CLI. Returns JSON array of PRs with fields: number, title, author, headRefName, createdAt, state, url, body, labels, updatedAt, closedAt, mergedAt", {"properties":{"days":{"default":30,"description":"Number of days to look back (default: 30)","type":"number"},"limit":{"default":100,"description":"Maximum number of PRs to fetch (default: 100)","type":"number"},"repo":{"description":"Repository in owner/repo format (defaults to current repository)","type":"string"},"search":{"description":"Search query for filtering PRs (e.g., 'head:copilot/' for Copilot PRs)","type":"string"},"state":{"default":"all","description":"PR state filter: open, closed, merged, or all (default: all)","type":"string"}},"type":"object"}, async (args) => {
               try {
                 const env = { ...process.env };
-                if (args && args["state"] !== undefined) {
-                  env["INPUT_STATE"] = typeof args["state"] === "object" ? JSON.stringify(args["state"]) : String(args["state"]);
-                }
                 if (args && args["days"] !== undefined) {
                   env["INPUT_DAYS"] = typeof args["days"] === "object" ? JSON.stringify(args["days"]) : String(args["days"]);
                 }
@@ -1498,6 +1513,9 @@ jobs:
                 if (args && args["search"] !== undefined) {
                   env["INPUT_SEARCH"] = typeof args["search"] === "object" ? JSON.stringify(args["search"]) : String(args["search"]);
                 }
+                if (args && args["state"] !== undefined) {
+                  env["INPUT_STATE"] = typeof args["state"] === "object" ? JSON.stringify(args["state"]) : String(args["state"]);
+                }
                 const scriptPath = path.join(__dirname, "fetch-pr-data.sh");
                 const { stdout, stderr } = await execFileAsync("bash", [scriptPath], { env });
                 const output = stdout + (stderr ? "\nStderr: " + stderr : "");
@@ -1506,24 +1524,6 @@ jobs:
                 return { content: [{ type: "text", text: "Error: " + (error instanceof Error ? error.message : String(error)) }], isError: true };
               }
             });
-            registerTool("test-js-math", "Test JavaScript math operations", {"properties":{"a":{"description":"First number","type":"number"},"b":{"description":"Second number","type":"number"}},"required":["a","b"],"type":"object"}, async (args) => {
-              try {
-                const toolModule = require("./test-js-math.cjs");
-                const result = await toolModule.execute(args || {});
-                return { content: [{ type: "text", text: typeof result === "string" ? result : JSON.stringify(result, null, 2) }] };
-              } catch (error) {
-                return { content: [{ type: "text", text: "Error: " + (error instanceof Error ? error.message : String(error)) }], isError: true };
-              }
-            });
-            registerTool("test-js-string", "Test JavaScript string operations", {"properties":{"text":{"description":"Input text","type":"string"}},"required":["text"],"type":"object"}, async (args) => {
-              try {
-                const toolModule = require("./test-js-string.cjs");
-                const result = await toolModule.execute(args || {});
-                return { content: [{ type: "text", text: typeof result === "string" ? result : JSON.stringify(result, null, 2) }] };
-              } catch (error) {
-                return { content: [{ type: "text", text: "Error: " + (error instanceof Error ? error.message : String(error)) }], isError: true };
-              }
-            });
             const LARGE_OUTPUT_THRESHOLD = 500;
             const CALLS_DIR = "/tmp/gh-aw/safe-inputs/calls";
             let callCounter = 0;
@@ -1632,26 +1632,6 @@ jobs:
             });
           EOFSI
           chmod +x /tmp/gh-aw/safe-inputs/mcp-server.cjs
-          cat > /tmp/gh-aw/safe-inputs/test-js-math.cjs << 'EOFJS_test-js-math'
-            async function execute(inputs) {
-              const { a, b } = inputs || {};
-              const sum = a + b;
-              const product = a * b;
-              return { sum, product, inputs: { a, b } };
-            }
-            module.exports = { execute };
-          EOFJS_test-js-math
-          cat > /tmp/gh-aw/safe-inputs/test-js-string.cjs << 'EOFJS_test-js-string'
-            async function execute(inputs) {
-              const { text } = inputs || {};
-              return {
-                original: text,
-                uppercase: text.toUpperCase(),
-                length: text.length
-              };
-            }
-            module.exports = { execute };
-          EOFJS_test-js-string
           cat > /tmp/gh-aw/safe-inputs/fetch-pr-data.sh << 'EOFSH_fetch-pr-data'
           #!/bin/bash
           # Auto-generated safe-input tool: fetch-pr-data
@@ -1685,6 +1665,26 @@ jobs:
           
           EOFSH_fetch-pr-data
           chmod +x /tmp/gh-aw/safe-inputs/fetch-pr-data.sh
+          cat > /tmp/gh-aw/safe-inputs/test-js-string.cjs << 'EOFJS_test-js-string'
+            async function execute(inputs) {
+              const { text } = inputs || {};
+              return {
+                original: text,
+                uppercase: text.toUpperCase(),
+                length: text.length
+              };
+            }
+            module.exports = { execute };
+          EOFJS_test-js-string
+          cat > /tmp/gh-aw/safe-inputs/test-js-math.cjs << 'EOFJS_test-js-math'
+            async function execute(inputs) {
+              const { a, b } = inputs || {};
+              const sum = a + b;
+              const product = a * b;
+              return { sum, product, inputs: { a, b } };
+            }
+            module.exports = { execute };
+          EOFJS_test-js-math
           
       - name: Setup MCPs
         env:
@@ -3101,6 +3101,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -3710,10 +3711,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/developer-docs-consolidator.lock.yml b/.github/workflows/developer-docs-consolidator.lock.yml
index 47c00d33d8b..5555466e9b3 100644
--- a/.github/workflows/developer-docs-consolidator.lock.yml
+++ b/.github/workflows/developer-docs-consolidator.lock.yml
@@ -4480,6 +4480,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5089,10 +5090,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/dictation-prompt.lock.yml b/.github/workflows/dictation-prompt.lock.yml
index 2197133d411..f0d91044e11 100644
--- a/.github/workflows/dictation-prompt.lock.yml
+++ b/.github/workflows/dictation-prompt.lock.yml
@@ -3130,6 +3130,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -3739,10 +3740,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/docs-noob-tester.lock.yml b/.github/workflows/docs-noob-tester.lock.yml
index d9ad391920c..c11fd3befc8 100644
--- a/.github/workflows/docs-noob-tester.lock.yml
+++ b/.github/workflows/docs-noob-tester.lock.yml
@@ -3211,6 +3211,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -3820,10 +3821,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/duplicate-code-detector.lock.yml b/.github/workflows/duplicate-code-detector.lock.yml
index c5b8ec1704c..baf699db448 100644
--- a/.github/workflows/duplicate-code-detector.lock.yml
+++ b/.github/workflows/duplicate-code-detector.lock.yml
@@ -3272,6 +3272,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -3881,10 +3882,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/example-permissions-warning.lock.yml b/.github/workflows/example-permissions-warning.lock.yml
index 95f04c59c0d..7463d90d723 100644
--- a/.github/workflows/example-permissions-warning.lock.yml
+++ b/.github/workflows/example-permissions-warning.lock.yml
@@ -752,6 +752,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -1361,10 +1362,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/example-workflow-analyzer.lock.yml b/.github/workflows/example-workflow-analyzer.lock.yml
index 73a1c70b925..3e22a2caa8b 100644
--- a/.github/workflows/example-workflow-analyzer.lock.yml
+++ b/.github/workflows/example-workflow-analyzer.lock.yml
@@ -3175,6 +3175,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -3784,10 +3785,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/firewall.lock.yml b/.github/workflows/firewall.lock.yml
index 3933cb96695..ecf37502e47 100644
--- a/.github/workflows/firewall.lock.yml
+++ b/.github/workflows/firewall.lock.yml
@@ -815,6 +815,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -1424,10 +1425,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/github-mcp-structural-analysis.lock.yml b/.github/workflows/github-mcp-structural-analysis.lock.yml
index eb09fd40b02..bb13fcf54dc 100644
--- a/.github/workflows/github-mcp-structural-analysis.lock.yml
+++ b/.github/workflows/github-mcp-structural-analysis.lock.yml
@@ -4406,6 +4406,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5015,10 +5016,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/github-mcp-tools-report.lock.yml b/.github/workflows/github-mcp-tools-report.lock.yml
index 8e50aa64b6a..1c09706c9b2 100644
--- a/.github/workflows/github-mcp-tools-report.lock.yml
+++ b/.github/workflows/github-mcp-tools-report.lock.yml
@@ -4186,6 +4186,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4795,10 +4796,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/glossary-maintainer.lock.yml b/.github/workflows/glossary-maintainer.lock.yml
index 2153585c05e..b16a984ed49 100644
--- a/.github/workflows/glossary-maintainer.lock.yml
+++ b/.github/workflows/glossary-maintainer.lock.yml
@@ -4181,6 +4181,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4790,10 +4791,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/go-fan.lock.yml b/.github/workflows/go-fan.lock.yml
index daefc143d0c..816bad1192b 100644
--- a/.github/workflows/go-fan.lock.yml
+++ b/.github/workflows/go-fan.lock.yml
@@ -3789,6 +3789,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4398,10 +4399,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/go-logger.lock.yml b/.github/workflows/go-logger.lock.yml
index 6d7067cc817..317207651d9 100644
--- a/.github/workflows/go-logger.lock.yml
+++ b/.github/workflows/go-logger.lock.yml
@@ -3626,6 +3626,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4235,10 +4236,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/go-pattern-detector.lock.yml b/.github/workflows/go-pattern-detector.lock.yml
index e1ff9054414..3799d68d6a0 100644
--- a/.github/workflows/go-pattern-detector.lock.yml
+++ b/.github/workflows/go-pattern-detector.lock.yml
@@ -3314,6 +3314,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -3923,10 +3924,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/grumpy-reviewer.lock.yml b/.github/workflows/grumpy-reviewer.lock.yml
index a55d60cbb3e..af86a3dd577 100644
--- a/.github/workflows/grumpy-reviewer.lock.yml
+++ b/.github/workflows/grumpy-reviewer.lock.yml
@@ -4534,6 +4534,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5143,10 +5144,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/instructions-janitor.lock.yml b/.github/workflows/instructions-janitor.lock.yml
index 187a63cc391..ec2ed6d8d05 100644
--- a/.github/workflows/instructions-janitor.lock.yml
+++ b/.github/workflows/instructions-janitor.lock.yml
@@ -3392,6 +3392,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4001,10 +4002,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/issue-arborist.lock.yml b/.github/workflows/issue-arborist.lock.yml
index 3f3454bf876..2a9464458b4 100644
--- a/.github/workflows/issue-arborist.lock.yml
+++ b/.github/workflows/issue-arborist.lock.yml
@@ -3286,6 +3286,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -3895,10 +3896,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/issue-monster.lock.yml b/.github/workflows/issue-monster.lock.yml
index 62e68e2f793..4c2edeff4a4 100644
--- a/.github/workflows/issue-monster.lock.yml
+++ b/.github/workflows/issue-monster.lock.yml
@@ -3643,6 +3643,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4252,10 +4253,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/issue-triage-agent.lock.yml b/.github/workflows/issue-triage-agent.lock.yml
index 4ea6efe39f3..0a0a938c2cd 100644
--- a/.github/workflows/issue-triage-agent.lock.yml
+++ b/.github/workflows/issue-triage-agent.lock.yml
@@ -3297,6 +3297,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -3906,10 +3907,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/lockfile-stats.lock.yml b/.github/workflows/lockfile-stats.lock.yml
index dda04c266dc..edc477cec6f 100644
--- a/.github/workflows/lockfile-stats.lock.yml
+++ b/.github/workflows/lockfile-stats.lock.yml
@@ -3834,6 +3834,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4443,10 +4444,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/mcp-inspector.lock.yml b/.github/workflows/mcp-inspector.lock.yml
index 908209e06e9..d1f232d28a5 100644
--- a/.github/workflows/mcp-inspector.lock.yml
+++ b/.github/workflows/mcp-inspector.lock.yml
@@ -3805,6 +3805,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4414,10 +4415,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/mergefest.lock.yml b/.github/workflows/mergefest.lock.yml
index 3feb71355ac..0b3a6d875b7 100644
--- a/.github/workflows/mergefest.lock.yml
+++ b/.github/workflows/mergefest.lock.yml
@@ -3896,6 +3896,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4505,10 +4506,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/notion-issue-summary.lock.yml b/.github/workflows/notion-issue-summary.lock.yml
index 6cc00ca81a7..f742c5460d4 100644
--- a/.github/workflows/notion-issue-summary.lock.yml
+++ b/.github/workflows/notion-issue-summary.lock.yml
@@ -2799,6 +2799,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -3408,10 +3409,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/pdf-summary.lock.yml b/.github/workflows/pdf-summary.lock.yml
index 80cbee8c0c9..02e6db38f41 100644
--- a/.github/workflows/pdf-summary.lock.yml
+++ b/.github/workflows/pdf-summary.lock.yml
@@ -4553,6 +4553,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5162,10 +5163,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/plan.lock.yml b/.github/workflows/plan.lock.yml
index 862fb978b69..0b5796ce38c 100644
--- a/.github/workflows/plan.lock.yml
+++ b/.github/workflows/plan.lock.yml
@@ -3904,6 +3904,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4513,10 +4514,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/poem-bot.lock.yml b/.github/workflows/poem-bot.lock.yml
index 97c55834eef..5543ada043e 100644
--- a/.github/workflows/poem-bot.lock.yml
+++ b/.github/workflows/poem-bot.lock.yml
@@ -5603,6 +5603,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -6212,10 +6213,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/pr-nitpick-reviewer.lock.yml b/.github/workflows/pr-nitpick-reviewer.lock.yml
index 4a13c12e3b5..f712c5d717b 100644
--- a/.github/workflows/pr-nitpick-reviewer.lock.yml
+++ b/.github/workflows/pr-nitpick-reviewer.lock.yml
@@ -4873,6 +4873,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5482,10 +5483,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/prompt-clustering-analysis.lock.yml b/.github/workflows/prompt-clustering-analysis.lock.yml
index cdce4b5f719..96be224bc30 100644
--- a/.github/workflows/prompt-clustering-analysis.lock.yml
+++ b/.github/workflows/prompt-clustering-analysis.lock.yml
@@ -5043,6 +5043,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5652,10 +5653,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/python-data-charts.lock.yml b/.github/workflows/python-data-charts.lock.yml
index 12b0b5e12df..da5131bb8eb 100644
--- a/.github/workflows/python-data-charts.lock.yml
+++ b/.github/workflows/python-data-charts.lock.yml
@@ -4903,6 +4903,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5512,10 +5513,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/q.lock.yml b/.github/workflows/q.lock.yml
index b95a9a1c57d..5136d5f47cb 100644
--- a/.github/workflows/q.lock.yml
+++ b/.github/workflows/q.lock.yml
@@ -5134,6 +5134,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5743,10 +5744,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/release.lock.yml b/.github/workflows/release.lock.yml
index 11d38349885..3d039770874 100644
--- a/.github/workflows/release.lock.yml
+++ b/.github/workflows/release.lock.yml
@@ -3206,6 +3206,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -3815,10 +3816,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/repo-tree-map.lock.yml b/.github/workflows/repo-tree-map.lock.yml
index aeb09791607..7570c05386a 100644
--- a/.github/workflows/repo-tree-map.lock.yml
+++ b/.github/workflows/repo-tree-map.lock.yml
@@ -3198,6 +3198,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -3807,10 +3808,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/repository-quality-improver.lock.yml b/.github/workflows/repository-quality-improver.lock.yml
index 18b0118a6c1..94426cccd60 100644
--- a/.github/workflows/repository-quality-improver.lock.yml
+++ b/.github/workflows/repository-quality-improver.lock.yml
@@ -4107,6 +4107,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4716,10 +4717,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/research.lock.yml b/.github/workflows/research.lock.yml
index 9a0c7237706..107d9b8e37b 100644
--- a/.github/workflows/research.lock.yml
+++ b/.github/workflows/research.lock.yml
@@ -3060,6 +3060,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -3669,10 +3670,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/safe-output-health.lock.yml b/.github/workflows/safe-output-health.lock.yml
index 374cfa339f3..3c222d7f64b 100644
--- a/.github/workflows/safe-output-health.lock.yml
+++ b/.github/workflows/safe-output-health.lock.yml
@@ -4066,6 +4066,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4675,10 +4676,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/schema-consistency-checker.lock.yml b/.github/workflows/schema-consistency-checker.lock.yml
index e797b5f4890..e7843262b5d 100644
--- a/.github/workflows/schema-consistency-checker.lock.yml
+++ b/.github/workflows/schema-consistency-checker.lock.yml
@@ -3844,6 +3844,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4453,10 +4454,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/scout.lock.yml b/.github/workflows/scout.lock.yml
index e39a261669a..ec5898d43d2 100644
--- a/.github/workflows/scout.lock.yml
+++ b/.github/workflows/scout.lock.yml
@@ -5167,6 +5167,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5776,10 +5777,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/security-fix-pr.lock.yml b/.github/workflows/security-fix-pr.lock.yml
index 9ab7599b78d..76e8e69307c 100644
--- a/.github/workflows/security-fix-pr.lock.yml
+++ b/.github/workflows/security-fix-pr.lock.yml
@@ -3330,6 +3330,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -3939,10 +3940,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/semantic-function-refactor.lock.yml b/.github/workflows/semantic-function-refactor.lock.yml
index e1a41b00dbc..a901dcaa261 100644
--- a/.github/workflows/semantic-function-refactor.lock.yml
+++ b/.github/workflows/semantic-function-refactor.lock.yml
@@ -4100,6 +4100,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4709,10 +4710,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/smoke-claude.lock.yml b/.github/workflows/smoke-claude.lock.yml
index 410d60da3d4..33b483010ea 100644
--- a/.github/workflows/smoke-claude.lock.yml
+++ b/.github/workflows/smoke-claude.lock.yml
@@ -4995,6 +4995,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5604,10 +5605,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/smoke-codex.lock.yml b/.github/workflows/smoke-codex.lock.yml
index 8747751daeb..de97ec076cc 100644
--- a/.github/workflows/smoke-codex.lock.yml
+++ b/.github/workflows/smoke-codex.lock.yml
@@ -4561,6 +4561,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5170,10 +5171,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/smoke-copilot-no-firewall.lock.yml b/.github/workflows/smoke-copilot-no-firewall.lock.yml
index 715c15d6f59..03ea691047a 100644
--- a/.github/workflows/smoke-copilot-no-firewall.lock.yml
+++ b/.github/workflows/smoke-copilot-no-firewall.lock.yml
@@ -4645,6 +4645,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5254,10 +5255,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/smoke-copilot.lock.yml b/.github/workflows/smoke-copilot.lock.yml
index 20efdb52986..a52b81ab6d8 100644
--- a/.github/workflows/smoke-copilot.lock.yml
+++ b/.github/workflows/smoke-copilot.lock.yml
@@ -4649,6 +4649,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5258,10 +5259,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/smoke-detector.lock.yml b/.github/workflows/smoke-detector.lock.yml
index cd96cd250e2..c2f6ff42b75 100644
--- a/.github/workflows/smoke-detector.lock.yml
+++ b/.github/workflows/smoke-detector.lock.yml
@@ -4783,6 +4783,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5392,10 +5393,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/smoke-srt-custom-config.lock.yml b/.github/workflows/smoke-srt-custom-config.lock.yml
index 019f6dd43e4..cb9750a96ee 100644
--- a/.github/workflows/smoke-srt-custom-config.lock.yml
+++ b/.github/workflows/smoke-srt-custom-config.lock.yml
@@ -1065,6 +1065,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -1674,10 +1675,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/smoke-srt.lock.yml b/.github/workflows/smoke-srt.lock.yml
index 9bad9c3e859..2f0fde2ea40 100644
--- a/.github/workflows/smoke-srt.lock.yml
+++ b/.github/workflows/smoke-srt.lock.yml
@@ -3083,6 +3083,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -3692,10 +3693,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/static-analysis-report.lock.yml b/.github/workflows/static-analysis-report.lock.yml
index f462d61caa0..1d3e6592a3b 100644
--- a/.github/workflows/static-analysis-report.lock.yml
+++ b/.github/workflows/static-analysis-report.lock.yml
@@ -3870,6 +3870,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4479,10 +4480,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/super-linter.lock.yml b/.github/workflows/super-linter.lock.yml
index ad6260dc5a8..0078943fd62 100644
--- a/.github/workflows/super-linter.lock.yml
+++ b/.github/workflows/super-linter.lock.yml
@@ -3344,6 +3344,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -3953,10 +3954,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/technical-doc-writer.lock.yml b/.github/workflows/technical-doc-writer.lock.yml
index 1d2fe2de960..665707ad58c 100644
--- a/.github/workflows/technical-doc-writer.lock.yml
+++ b/.github/workflows/technical-doc-writer.lock.yml
@@ -4415,6 +4415,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5024,10 +5025,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/test-firewall-escape.lock.yml b/.github/workflows/test-firewall-escape.lock.yml
index 462e97b1688..c13781a643c 100644
--- a/.github/workflows/test-firewall-escape.lock.yml
+++ b/.github/workflows/test-firewall-escape.lock.yml
@@ -1140,6 +1140,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -1749,10 +1750,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/tidy.lock.yml b/.github/workflows/tidy.lock.yml
index 9ac78e04797..5b2f34f46b8 100644
--- a/.github/workflows/tidy.lock.yml
+++ b/.github/workflows/tidy.lock.yml
@@ -3538,6 +3538,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4147,10 +4148,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/typist.lock.yml b/.github/workflows/typist.lock.yml
index f7a997ac293..8f08eff0475 100644
--- a/.github/workflows/typist.lock.yml
+++ b/.github/workflows/typist.lock.yml
@@ -4131,6 +4131,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4740,10 +4741,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/unbloat-docs.lock.yml b/.github/workflows/unbloat-docs.lock.yml
index 4f0c6aaebdd..efcc791a527 100644
--- a/.github/workflows/unbloat-docs.lock.yml
+++ b/.github/workflows/unbloat-docs.lock.yml
@@ -4916,6 +4916,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -5525,10 +5526,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/video-analyzer.lock.yml b/.github/workflows/video-analyzer.lock.yml
index 5674ebb8258..8b7bd5f3138 100644
--- a/.github/workflows/video-analyzer.lock.yml
+++ b/.github/workflows/video-analyzer.lock.yml
@@ -3387,6 +3387,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -3996,10 +3997,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/.github/workflows/weekly-issue-summary.lock.yml b/.github/workflows/weekly-issue-summary.lock.yml
index d69fdaba59d..52156abf241 100644
--- a/.github/workflows/weekly-issue-summary.lock.yml
+++ b/.github/workflows/weekly-issue-summary.lock.yml
@@ -4131,6 +4131,7 @@ jobs:
           script: |
             const MAX_TOOL_OUTPUT_LENGTH = 256;
             const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
+            const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
             const SIZE_LIMIT_WARNING = "\n\n⚠️ *Step summary size limit reached. Additional content truncated.*\n\n";
             class StepSummaryTracker {
               constructor(maxSize = MAX_STEP_SUMMARY_SIZE) {
@@ -4740,10 +4741,10 @@ jobs:
                       } else {
                         toolCounts.success++;
                       }
-                      const statusIcon = isError ? "x" : "✓";
+                      const statusIcon = isError ? "✗" : "✓";
                       let displayName;
                       if (toolName === "Bash") {
-                        const cmd = formatBashCommand(input.command || "").slice(0, 40);
+                        const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
                         displayName = `bash: ${cmd}`;
                       } else if (toolName.startsWith("mcp__")) {
                         displayName = formatMcpName(toolName);
diff --git a/pkg/workflow/js/log_parser_shared.cjs b/pkg/workflow/js/log_parser_shared.cjs
index 6001d489cd7..2f91df82d87 100644
--- a/pkg/workflow/js/log_parser_shared.cjs
+++ b/pkg/workflow/js/log_parser_shared.cjs
@@ -20,6 +20,12 @@ const MAX_TOOL_OUTPUT_LENGTH = 256;
  */
 const MAX_STEP_SUMMARY_SIZE = 1000 * 1024;
 
+/**
+ * Maximum length for bash command display in plain text summaries.
+ * Commands are truncated to this length for compact display.
+ */
+const MAX_BASH_COMMAND_DISPLAY_LENGTH = 40;
+
 /**
  * Warning message shown when step summary size limit is reached.
  * This message is added directly to markdown (not tracked) to ensure it's always visible.
@@ -855,7 +861,7 @@ function parseLogEntries(logContent) {
  * Generic helper to format a tool call as an HTML details section.
  * This is a reusable helper for all code engines (Claude, Copilot, Codex).
  *
- * Tool output/response content is automatically truncated to MAX_TOOL_OUTPUT_LENGTH (500 chars)
+ * Tool output/response content is automatically truncated to MAX_TOOL_OUTPUT_LENGTH (256 chars)
  * to keep step summaries readable and prevent size limit issues.
  *
  * @param {Object} options - Configuration options
@@ -1000,12 +1006,12 @@ function generatePlainTextSummary(logEntries, options = {}) {
             toolCounts.success++;
           }
 
-          const statusIcon = isError ? "x" : "✓";
+          const statusIcon = isError ? "✗" : "✓";
 
           // Format tool name compactly
           let displayName;
           if (toolName === "Bash") {
-            const cmd = formatBashCommand(input.command || "").slice(0, 40);
+            const cmd = formatBashCommand(input.command || "").slice(0, MAX_BASH_COMMAND_DISPLAY_LENGTH);
             displayName = `bash: ${cmd}`;
           } else if (toolName.startsWith("mcp__")) {
             displayName = formatMcpName(toolName);
diff --git a/pkg/workflow/js/log_parser_shared.test.cjs b/pkg/workflow/js/log_parser_shared.test.cjs
index 3d9a260b25a..f9576bf22fb 100644
--- a/pkg/workflow/js/log_parser_shared.test.cjs
+++ b/pkg/workflow/js/log_parser_shared.test.cjs
@@ -1388,7 +1388,7 @@ describe("log_parser_shared.cjs", () => {
 
       expect(result).toContain("Tools/Commands:");
       expect(result).toContain("[✓] bash: echo test");
-      expect(result).toContain("[x] github::create_issue");
+      expect(result).toContain("[✗] github::create_issue");
       expect(result).toContain("Tools: 1/2 succeeded");
     });
 
