diff --git a/backend/app/services/export_service.py b/backend/app/services/export_service.py index d680b277..41da72cb 100644 --- a/backend/app/services/export_service.py +++ b/backend/app/services/export_service.py @@ -90,6 +90,26 @@ def _get_command_output(decision: dict[str, Any]) -> str | None: return output if output else None +def _truncate_command_output(output: str, max_lines: int = 5, fmt: str = "text") -> str: + """Truncate command output to max_lines for standard detail level. + + Args: + fmt: One of "markdown", "text", "html", "psa" — controls suffix formatting. + """ + lines = output.splitlines() + if len(lines) <= max_lines: + return output + truncated = "\n".join(lines[:max_lines]) + count = len(lines) + if fmt == "markdown": + suffix = f"*(full output omitted — {count} lines)*" + elif fmt == "html": + suffix = f"(full output omitted — {count} lines)" + else: # text, psa + suffix = f"(full output omitted — {count} lines)" + return f"{truncated}\n{suffix}" + + def _find_node_commands(tree_snapshot: dict[str, Any], node_id: str) -> list[str]: """Find the commands list for a node in the tree snapshot.""" def _search(node: dict[str, Any]) -> list[str] | None: @@ -170,6 +190,8 @@ def generate_markdown_export(session: Session, options: SessionExport) -> str: if notes: lines.append(f"**Notes:** {notes}") if command_output := _get_command_output(decision): + if options.detail_level == "standard": + command_output = _truncate_command_output(command_output, fmt="markdown") commands = _find_node_commands(session.tree_snapshot, decision.get("node_id", "")) if commands: lines.append(f"**Commands Run:** {', '.join(f'`{c}`' for c in commands)}") @@ -259,6 +281,8 @@ def generate_text_export(session: Session, options: SessionExport) -> str: if notes: lines.append(f" Notes: {notes}") if command_output := _get_command_output(decision): + if options.detail_level == "standard": + command_output = _truncate_command_output(command_output, fmt="text") commands = _find_node_commands(session.tree_snapshot, decision.get("node_id", "")) if commands: lines.append(f" Commands Run: {', '.join(commands)}") @@ -353,6 +377,8 @@ def generate_html_export(session: Session, options: SessionExport) -> str: if notes: html_parts.append(f'

Notes: {notes}

') if command_output := _get_command_output(decision): + if options.detail_level == "standard": + command_output = _truncate_command_output(command_output, fmt="html") commands = _find_node_commands(session.tree_snapshot, decision.get("node_id", "")) if commands: cmd_html = ", ".join(f"{html.escape(c)}" for c in commands) @@ -429,6 +455,8 @@ def generate_psa_export(session: Session, options: SessionExport) -> str: if notes: lines.append(f" Notes: {notes}") if command_output := _get_command_output(decision): + if options.detail_level == "standard": + command_output = _truncate_command_output(command_output, fmt="psa") commands = _find_node_commands(session.tree_snapshot, decision.get("node_id", "")) if commands: lines.append(f" Commands: {', '.join(commands)}")