Skip to content

bug(workspace): project page prints the goal as raw markdown instead of rendering it #3692

Closed

Description

@vybe

Summary

The Workspace project page (Projects → a project) shows the project goal as raw text: **bold** markers, backtick spans and > blockquote prefixes are printed literally instead of being rendered. Agents and people write project goals in markdown (the Create modal and the create_project / import_project MCP tools accept free text), so most goals longer than one line come out with visible markup.

Context

Seen on a live project whose goal is three short paragraphs with a blockquote and inline bold/code. Every other place the Workspace shows agent-written prose (chat bubbles, rooms, Inbox, project material files) goes through the shared PortalMarkdown component; the project page header does not. The goal is bound as plain text with whitespace-pre-line in src/frontend/src/components/portal/projects/ProjectPage.vue, so line breaks survive but nothing else does.

The same plain-text pattern is used for task objectives and log entry bodies on the project page (ProjectTasks.vue, ProjectLog.vue), which get the same markup leakage when an agent writes them in markdown.

Acceptance Criteria

  • The project goal on the project page renders markdown (bold, inline code, blockquotes, lists, links) through the shared Workspace markdown renderer, sanitized the same way as chat content
  • A plain-text goal with line breaks still renders with its paragraphs intact (no regression for goals that never used markup)
  • Task objectives and project log entry bodies on the same page render markdown the same way
  • Rendered goal respects the existing max-w-3xl reading width and light/dark theming of the header
  • A unit test covers a goal containing bold, inline code and a blockquote and asserts the markup is rendered, not printed

Technical Notes

  • PortalMarkdown.vue is designed as "the one v-html" body for any surface that renders agent markdown; ProjectMaterial.vue already mounts it for .md files in the project
  • Rendering path: renderMarkdownWithCodeBlocks in src/frontend/src/utils/markdown (DOMPurify inside)
  • The heading style of .prose-portal may be heavier than a header subtitle wants; a compact variant or a wrapper class may be needed so a one-line goal still reads as a subtitle

Activity

  1. added
    complexity-lowComplexity: low (board points 1-3)
    status-readyGreenlit and ready for development (vetted; counterpart to status-incubating)
    on Oct 14, 2026
  2. added and removed
    status-readyGreenlit and ready for development (vetted; counterpart to status-incubating)
    on Oct 14, 2026
  3. added
    status-in-devMerged to dev, awaiting release cut to main
    and removed on Oct 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions