> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bepurple.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Share & team

> Share a spec session for review, see incoming feedback from a bell, and pair your phone for Remote Control.

export const Mock = props => {
  const {kind, ...rest} = props;
  const iconBase = {
    xmlns: "http://www.w3.org/2000/svg",
    viewBox: "0 0 24 24",
    fill: "none",
    stroke: "currentColor",
    strokeWidth: "2",
    strokeLinecap: "round",
    strokeLinejoin: "round",
    width: "14",
    height: "14",
    "aria-hidden": "true"
  };
  const renderShapes = shapes => shapes.map((shape, idx) => {
    if (shape.tag === "circle") return <circle key={idx} {...shape.attrs} />;
    if (shape.tag === "rect") return <rect key={idx} {...shape.attrs} />;
    if (shape.tag === "line") return <line key={idx} {...shape.attrs} />;
    if (shape.tag === "polyline") return <polyline key={idx} {...shape.attrs} />;
    if (shape.tag === "polygon") return <polygon key={idx} {...shape.attrs} />;
    return <path key={idx} {...shape.attrs} />;
  });
  if (kind === "appShell") {
    const {sidebar, children} = rest;
    return <div className="p0-app-shell" role="img" aria-label="p0 application window mock">
        <div className="p0-app-shell__titlebar" aria-hidden="true">
          <span className="p0-app-shell__dot p0-app-shell__dot--close" />
          <span className="p0-app-shell__dot p0-app-shell__dot--minimize" />
          <span className="p0-app-shell__dot p0-app-shell__dot--maximize" />
        </div>
        <div className="p0-app-shell__body">
          {sidebar ? <aside className="p0-app-shell__sidebar">{sidebar}</aside> : null}
          <main className="p0-app-shell__main">{children}</main>
        </div>
      </div>;
  }
  if (kind === "sidebar") {
    const {sessions = [], repos = []} = rest;
    return <div className="p0-sidebar" role="navigation" aria-label="p0 sidebar mock">
        <section className="p0-sidebar__section">
          <header className="p0-sidebar__section-header">
            <span className="p0-sidebar__section-title">Sessions</span>
            <button type="button" className="p0-sidebar__section-action" aria-label="New session" tabIndex={-1}>
              <svg {...iconBase}>
                <path d="M5 12h14" />
                <path d="M12 5v14" />
              </svg>
            </button>
          </header>
          <ul className="p0-sidebar__list">
            {sessions.map(s => <li key={s.id} className={s.active ? "p0-sidebar__item p0-sidebar__item--active" : "p0-sidebar__item"}>
                <svg {...iconBase} className="p0-sidebar__item-icon">
                  <path d="M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z" />
                </svg>
                <span className="p0-sidebar__item-label">{s.title}</span>
              </li>)}
          </ul>
        </section>

        <section className="p0-sidebar__section">
          <header className="p0-sidebar__section-header">
            <span className="p0-sidebar__section-title">Repositories</span>
          </header>
          <ul className="p0-sidebar__list">
            {repos.map(r => <li key={r.name} className="p0-sidebar__item">
                <svg {...iconBase} className="p0-sidebar__item-icon">
                  <path d="M18 19a5 5 0 0 1-5-5v8" />
                  <path d="M9 20H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H20a2 2 0 0 1 2 2v5" />
                  <circle cx="13" cy="12" r="2" />
                  <circle cx="20" cy="19" r="2" />
                </svg>
                <span className="p0-sidebar__item-label">{r.name}</span>
              </li>)}
          </ul>
        </section>
      </div>;
  }
  if (kind === "chatInput") {
    const {placeholder = "Message p0…", slashOpen = false} = rest;
    const SLASH_PREVIEW = [{
      command: "/plan",
      description: "Switch to Plan mode"
    }, {
      command: "/build-from-spec",
      description: "End-to-end spec → PR pipeline"
    }, {
      command: "/refine",
      description: "Iterate on a built feature"
    }];
    const ciIconBase = {
      ...iconBase,
      width: "16",
      height: "16"
    };
    const slashIconBase = {
      ...ciIconBase,
      width: "12",
      height: "12"
    };
    return <div className="p0-chat-input-wrapper">
        {slashOpen ? <div className="p0-chat-input__dropdown-slot">
            <div className="p0-slash-dropdown" role="listbox" aria-label="Slash command suggestions">
              <div className="p0-slash-dropdown__header">
                <svg {...slashIconBase}>
                  <path d="M22 2 2 22" />
                </svg>
                <span>Commands matching /</span>
              </div>
              <ul className="p0-slash-dropdown__list">
                {SLASH_PREVIEW.map((c, i) => <li key={c.command} className={i === 0 ? "p0-slash-dropdown__item p0-slash-dropdown__item--active" : "p0-slash-dropdown__item"} role="option" aria-selected={i === 0}>
                    <code className="p0-slash-dropdown__command">{c.command}</code>
                    <span className="p0-slash-dropdown__description">{c.description}</span>
                  </li>)}
              </ul>
            </div>
          </div> : null}
        <div className="p0-chat-input" role="group" aria-label="p0 chat input mock">
          <button type="button" className="p0-chat-input__icon-btn" aria-label="Attach file" tabIndex={-1}>
            <svg {...ciIconBase}>
              <path d="m16 6-8.414 8.586a2 2 0 0 0 2.829 2.829l8.414-8.586a4 4 0 1 0-5.657-5.657l-8.379 8.551a6 6 0 1 0 8.485 8.485l8.379-8.551" />
            </svg>
          </button>
          <span className="p0-chat-input__field" aria-hidden="true">
            {placeholder}
          </span>
          <button type="button" className="p0-chat-input__send" aria-label="Send message" tabIndex={-1}>
            <svg {...ciIconBase}>
              <path d="m5 12 7-7 7 7" />
              <path d="M12 19V5" />
            </svg>
          </button>
        </div>
      </div>;
  }
  if (kind === "slashDropdown") {
    const {query = "/"} = rest;
    const SLASH_COMMANDS = [{
      command: "/agent",
      description: "Switch to Agent mode (applies changes directly)"
    }, {
      command: "/clear",
      description: "Start a new conversation (creates new sub-chat)"
    }, {
      command: "/compact",
      description: "Compact conversation context to reduce token usage"
    }, {
      command: "/config",
      description: "View and modify configuration settings"
    }, {
      command: "/cost",
      description: "Show token usage and cost for the session"
    }, {
      command: "/doctor",
      description: "Check the health of your p0 installation"
    }, {
      command: "/help",
      description: "Show available commands and help"
    }, {
      command: "/mcp",
      description: "View and manage MCP server connections"
    }, {
      command: "/memory",
      description: "View and edit CLAUDE.md memory files"
    }, {
      command: "/model",
      description: "Switch AI model"
    }, {
      command: "/permissions",
      description: "View and manage tool permissions"
    }, {
      command: "/plan",
      description: "Switch to Plan mode (creates plan before making changes)"
    }, {
      command: "/pr-comments",
      description: "Ask the agent to generate PR review comments"
    }, {
      command: "/release-notes",
      description: "Ask the agent to generate release notes"
    }, {
      command: "/review",
      description: "Ask the agent to review your code"
    }, {
      command: "/security-review",
      description: "Ask the agent to perform a security audit"
    }, {
      command: "/skills",
      description: "Manage your skills"
    }, {
      command: "/status",
      description: "Show current session status and context"
    }, {
      command: "/build-from-spec",
      description: "Run the end-to-end spec → build → QA pipeline"
    }, {
      command: "/create-standards",
      description: "Generate engineering standards for your workspace"
    }, {
      command: "/refine",
      description: "Make incremental changes to a recently built feature"
    }, {
      command: "/import-spec",
      description: "Import a product spec and ask clarifying questions"
    }];
    const sdIconBase = {
      ...iconBase,
      width: "12",
      height: "12"
    };
    const needle = (query || "/").toLowerCase();
    const matches = SLASH_COMMANDS.filter(c => c.command.toLowerCase().startsWith(needle));
    return <div className="p0-slash-dropdown" role="listbox" aria-label="Slash command suggestions">
        <div className="p0-slash-dropdown__header">
          <svg {...sdIconBase}>
            <path d="M22 2 2 22" />
          </svg>
          <span>Commands matching {query}</span>
        </div>
        {matches.length === 0 ? <div className="p0-slash-dropdown__empty">No commands match.</div> : <ul className="p0-slash-dropdown__list">
            {matches.map((c, i) => <li key={c.command} className={i === 0 ? "p0-slash-dropdown__item p0-slash-dropdown__item--active" : "p0-slash-dropdown__item"} role="option" aria-selected={i === 0}>
                <code className="p0-slash-dropdown__command">{c.command}</code>
                <span className="p0-slash-dropdown__description">{c.description}</span>
              </li>)}
          </ul>}
      </div>;
  }
  if (kind === "ticketTree") {
    const {phases = []} = rest;
    const STATUS_META = {
      todo: {
        label: "Todo",
        modifier: "todo",
        shapes: [{
          tag: "circle",
          attrs: {
            cx: "12",
            cy: "12",
            r: "10"
          }
        }]
      },
      in_progress: {
        label: "In progress",
        modifier: "in-progress",
        shapes: [{
          tag: "path",
          attrs: {
            d: "M21 12a9 9 0 1 1-6.219-8.56"
          }
        }]
      },
      completed: {
        label: "Completed",
        modifier: "completed",
        shapes: [{
          tag: "circle",
          attrs: {
            cx: "12",
            cy: "12",
            r: "10"
          }
        }, {
          tag: "path",
          attrs: {
            d: "m9 12 2 2 4-4"
          }
        }]
      },
      failed: {
        label: "Failed",
        modifier: "failed",
        shapes: [{
          tag: "circle",
          attrs: {
            cx: "12",
            cy: "12",
            r: "10"
          }
        }, {
          tag: "path",
          attrs: {
            d: "m15 9-6 6"
          }
        }, {
          tag: "path",
          attrs: {
            d: "m9 9 6 6"
          }
        }]
      }
    };
    return <div className="p0-ticket-tree" role="tree" aria-label="Build progress">
        <ul className="p0-ticket-tree__phases">
          {phases.map(phase => <li key={phase.name} className="p0-ticket-tree__phase">
              <div className="p0-ticket-tree__phase-name">{phase.name}</div>
              <ul className="p0-ticket-tree__tickets">
                {phase.tickets.map(ticket => {
      const meta = STATUS_META[ticket.status] ?? STATUS_META.todo;
      return <li key={ticket.id} className="p0-ticket-tree__ticket" data-status={ticket.status}>
                      <span className={`p0-ticket-tree__dot p0-ticket-tree__dot--${meta.modifier}`} role="img" aria-label={meta.label}>
                        <svg {...iconBase} aria-hidden="true">
                          {renderShapes(meta.shapes)}
                        </svg>
                      </span>
                      <code className="p0-ticket-tree__ticket-id">{ticket.id}</code>
                      <span className="p0-ticket-tree__ticket-name">{ticket.name}</span>
                    </li>;
    })}
              </ul>
            </li>)}
        </ul>
      </div>;
  }
  if (kind === "diffView") {
    const {mode = "unified", file, before = "", after = ""} = rest;
    const computeUnifiedLines = (b, a) => {
      const beforeLines = b.split("\n");
      const afterLines = a.split("\n");
      const lines = [];
      const max = Math.max(beforeLines.length, afterLines.length);
      for (let i = 0; i < max; i++) {
        const bl = beforeLines[i];
        const al = afterLines[i];
        if (bl === al) {
          if (bl !== undefined) lines.push({
            kind: "context",
            text: bl
          });
        } else {
          if (bl !== undefined) lines.push({
            kind: "remove",
            text: bl
          });
          if (al !== undefined) lines.push({
            kind: "add",
            text: al
          });
        }
      }
      return lines;
    };
    const PREFIX = {
      add: "+",
      remove: "-",
      context: " "
    };
    const MODIFIER = {
      add: "add",
      remove: "remove",
      context: "context"
    };
    const computeSplitRows = (b, a) => {
      const beforeLines = b.split("\n");
      const afterLines = a.split("\n");
      const max = Math.max(beforeLines.length, afterLines.length);
      const rows = [];
      for (let i = 0; i < max; i++) {
        const bl = beforeLines[i];
        const al = afterLines[i];
        const sameRow = bl === al;
        rows.push({
          before: bl === undefined ? {
            kind: "empty",
            text: ""
          } : sameRow ? {
            kind: "context",
            text: bl
          } : {
            kind: "remove",
            text: bl
          },
          after: al === undefined ? {
            kind: "empty",
            text: ""
          } : sameRow ? {
            kind: "context",
            text: al
          } : {
            kind: "add",
            text: al
          }
        });
      }
      return rows;
    };
    const unifiedLines = mode === "unified" ? computeUnifiedLines(before, after) : [];
    const splitRows = mode === "split" ? computeSplitRows(before, after) : [];
    return <div className={`p0-diff-view p0-diff-view--${mode}`} role="figure" aria-label={`Diff for ${file}`}>
        <div className="p0-diff-view__header">
          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" width="14" height="14" aria-hidden="true">
            <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" />
            <path d="M14 2v4a2 2 0 0 0 2 2h4" />
            <path d="M9 10h6" />
            <path d="M12 13v-6" />
            <path d="M9 17h6" />
          </svg>
          <code className="p0-diff-view__file">{file}</code>
        </div>

        {mode === "split" ? <div className="p0-diff-view__body p0-diff-view__body--split">
            <div className="p0-diff-view__column" aria-label="Before">
              {splitRows.map((row, i) => row.before.kind === "empty" ? <div key={`b-${i}`} className="p0-diff-view__line p0-diff-view__line--empty" aria-hidden="true">
                    <span className="p0-diff-view__text">{" "}</span>
                  </div> : <div key={`b-${i}`} className={`p0-diff-view__line p0-diff-view__line--${MODIFIER[row.before.kind]}`} data-kind={row.before.kind}>
                    <span className="p0-diff-view__prefix" aria-hidden="true">
                      {PREFIX[row.before.kind]}
                    </span>
                    <span className="p0-diff-view__text">{row.before.text || " "}</span>
                  </div>)}
            </div>
            <div className="p0-diff-view__column" aria-label="After">
              {splitRows.map((row, i) => row.after.kind === "empty" ? <div key={`a-${i}`} className="p0-diff-view__line p0-diff-view__line--empty" aria-hidden="true">
                    <span className="p0-diff-view__text">{" "}</span>
                  </div> : <div key={`a-${i}`} className={`p0-diff-view__line p0-diff-view__line--${MODIFIER[row.after.kind]}`} data-kind={row.after.kind}>
                    <span className="p0-diff-view__prefix" aria-hidden="true">
                      {PREFIX[row.after.kind]}
                    </span>
                    <span className="p0-diff-view__text">{row.after.text || " "}</span>
                  </div>)}
            </div>
          </div> : <div className="p0-diff-view__body">
            {unifiedLines.map((line, i) => <div key={i} className={`p0-diff-view__line p0-diff-view__line--${MODIFIER[line.kind]}`} data-kind={line.kind}>
                <span className="p0-diff-view__prefix" aria-hidden="true">
                  {PREFIX[line.kind]}
                </span>
                <span className="p0-diff-view__text">{line.text || " "}</span>
              </div>)}
          </div>}
      </div>;
  }
  if (kind === "terminalPane") {
    const {prompt = "$", command, output} = rest;
    return <div className="p0-terminal-pane" role="figure" aria-label="Terminal output">
        <div className="p0-terminal-pane__chrome" aria-hidden="true">
          <span className="p0-terminal-pane__dot p0-terminal-pane__dot--red" />
          <span className="p0-terminal-pane__dot p0-terminal-pane__dot--yellow" />
          <span className="p0-terminal-pane__dot p0-terminal-pane__dot--green" />
          <span className="p0-terminal-pane__title">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" width="12" height="12" aria-hidden="true">
              <path d="m7 11 2-2-2-2" />
              <path d="M11 13h4" />
              <rect width="18" height="18" x="3" y="3" rx="2" ry="2" />
            </svg>
            {" "}terminal
          </span>
        </div>
        <pre className="p0-terminal-pane__body">
          <code>
            <span className="p0-terminal-pane__line">
              <span className="p0-terminal-pane__prompt">{prompt}</span>
              <span className="p0-terminal-pane__command">{command}</span>
            </span>
            {output ? <span className="p0-terminal-pane__output">{"\n" + output}</span> : null}
          </code>
        </pre>
      </div>;
  }
  if (kind === "devToolsPanel") {
    const {defaultTab = "terminal", terminal, changes, run} = rest;
    const SECTIONS = [{
      id: "terminal",
      label: "Terminal",
      shapes: [{
        tag: "path",
        attrs: {
          d: "m7 11 2-2-2-2"
        }
      }, {
        tag: "path",
        attrs: {
          d: "M11 13h4"
        }
      }, {
        tag: "rect",
        attrs: {
          width: "18",
          height: "18",
          x: "3",
          y: "3",
          rx: "2",
          ry: "2"
        }
      }]
    }, {
      id: "changes",
      label: "Changes",
      shapes: [{
        tag: "path",
        attrs: {
          d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"
        }
      }, {
        tag: "path",
        attrs: {
          d: "M14 2v4a2 2 0 0 0 2 2h4"
        }
      }, {
        tag: "path",
        attrs: {
          d: "M9 10h6"
        }
      }, {
        tag: "path",
        attrs: {
          d: "M12 13v-6"
        }
      }, {
        tag: "path",
        attrs: {
          d: "M9 17h6"
        }
      }]
    }, {
      id: "run",
      label: "Run",
      shapes: [{
        tag: "polygon",
        attrs: {
          points: "6 3 20 12 6 21 6 3"
        }
      }]
    }];
    const panes = {
      terminal,
      changes,
      run
    };
    return <div className="p0-devtools-panel" role="region" aria-label="DevTools panel">
        {SECTIONS.map(section => {
      const isEmphasized = section.id === defaultTab;
      return <section key={section.id} id={`p0-devtools-panel__section--${section.id}`} className={"p0-devtools-panel__section" + (isEmphasized ? " p0-devtools-panel__section--active" : "")} aria-label={section.label}>
              <h4 className="p0-devtools-panel__section-heading">
                <svg {...iconBase} aria-hidden="true">
                  {renderShapes(section.shapes)}
                </svg>
                <span>{section.label}</span>
              </h4>
              <div className="p0-devtools-panel__section-body">
                {panes[section.id]}
              </div>
            </section>;
    })}
      </div>;
  }
  if (kind === "howToP0Dialog") {
    const htpIconBase = {
      ...iconBase,
      width: "16",
      height: "16"
    };
    const ICON_SHAPES = {
      archive: [{
        tag: "rect",
        attrs: {
          width: "20",
          height: "5",
          x: "2",
          y: "3",
          rx: "1"
        }
      }, {
        tag: "path",
        attrs: {
          d: "M4 8v11a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8"
        }
      }, {
        tag: "path",
        attrs: {
          d: "M10 12h4"
        }
      }],
      book: [{
        tag: "path",
        attrs: {
          d: "M4 19.5v-15A2.5 2.5 0 0 1 6.5 2H19a1 1 0 0 1 1 1v17a1 1 0 0 1-1 1H6.5a1 1 0 0 1 0-5H20"
        }
      }],
      calendarDays: [{
        tag: "path",
        attrs: {
          d: "M8 2v4"
        }
      }, {
        tag: "path",
        attrs: {
          d: "M16 2v4"
        }
      }, {
        tag: "rect",
        attrs: {
          width: "18",
          height: "18",
          x: "3",
          y: "4",
          rx: "2"
        }
      }, {
        tag: "path",
        attrs: {
          d: "M3 10h18"
        }
      }, {
        tag: "path",
        attrs: {
          d: "M8 14h.01"
        }
      }, {
        tag: "path",
        attrs: {
          d: "M12 14h.01"
        }
      }, {
        tag: "path",
        attrs: {
          d: "M16 14h.01"
        }
      }, {
        tag: "path",
        attrs: {
          d: "M8 18h.01"
        }
      }, {
        tag: "path",
        attrs: {
          d: "M12 18h.01"
        }
      }, {
        tag: "path",
        attrs: {
          d: "M16 18h.01"
        }
      }],
      code: [{
        tag: "polyline",
        attrs: {
          points: "16 18 22 12 16 6"
        }
      }, {
        tag: "polyline",
        attrs: {
          points: "8 6 2 12 8 18"
        }
      }],
      gitBranch: [{
        tag: "line",
        attrs: {
          x1: "6",
          x2: "6",
          y1: "3",
          y2: "15"
        }
      }, {
        tag: "circle",
        attrs: {
          cx: "18",
          cy: "6",
          r: "3"
        }
      }, {
        tag: "circle",
        attrs: {
          cx: "6",
          cy: "18",
          r: "3"
        }
      }, {
        tag: "path",
        attrs: {
          d: "M18 9a9 9 0 0 1-9 9"
        }
      }],
      gitCompare: [{
        tag: "circle",
        attrs: {
          cx: "5",
          cy: "6",
          r: "3"
        }
      }, {
        tag: "path",
        attrs: {
          d: "M12 6h5a2 2 0 0 1 2 2v7"
        }
      }, {
        tag: "circle",
        attrs: {
          cx: "19",
          cy: "18",
          r: "3"
        }
      }, {
        tag: "path",
        attrs: {
          d: "M12 18H7a2 2 0 0 1-2-2V9"
        }
      }],
      gitPullRequestArrow: [{
        tag: "circle",
        attrs: {
          cx: "5",
          cy: "6",
          r: "3"
        }
      }, {
        tag: "path",
        attrs: {
          d: "M5 9v12"
        }
      }, {
        tag: "circle",
        attrs: {
          cx: "19",
          cy: "18",
          r: "3"
        }
      }, {
        tag: "path",
        attrs: {
          d: "m15 9-3-3 3-3"
        }
      }, {
        tag: "path",
        attrs: {
          d: "M12 6h5a2 2 0 0 1 2 2v7"
        }
      }],
      keyRound: [{
        tag: "path",
        attrs: {
          d: "M2.586 17.414A2 2 0 0 0 2 18.828V21a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h1a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h.172a2 2 0 0 0 1.414-.586l.814-.814a6.5 6.5 0 1 0-4-4z"
        }
      }, {
        tag: "circle",
        attrs: {
          cx: "16.5",
          cy: "7.5",
          r: ".5",
          fill: "currentColor"
        }
      }],
      lightbulb: [{
        tag: "path",
        attrs: {
          d: "M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5"
        }
      }, {
        tag: "path",
        attrs: {
          d: "M9 18h6"
        }
      }, {
        tag: "path",
        attrs: {
          d: "M10 22h4"
        }
      }],
      messageCircle: [{
        tag: "path",
        attrs: {
          d: "M7.9 20A9 9 0 1 0 4 16.1L2 22z"
        }
      }],
      messageSquare: [{
        tag: "path",
        attrs: {
          d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"
        }
      }],
      notebookText: [{
        tag: "path",
        attrs: {
          d: "M2 6h4"
        }
      }, {
        tag: "path",
        attrs: {
          d: "M2 10h4"
        }
      }, {
        tag: "path",
        attrs: {
          d: "M2 14h4"
        }
      }, {
        tag: "path",
        attrs: {
          d: "M2 18h4"
        }
      }, {
        tag: "rect",
        attrs: {
          width: "16",
          height: "20",
          x: "4",
          y: "2",
          rx: "2"
        }
      }, {
        tag: "path",
        attrs: {
          d: "M9.5 8h5"
        }
      }, {
        tag: "path",
        attrs: {
          d: "M9.5 12H16"
        }
      }, {
        tag: "path",
        attrs: {
          d: "M9.5 16H14"
        }
      }],
      play: [{
        tag: "polygon",
        attrs: {
          points: "6 3 20 12 6 21 6 3"
        }
      }],
      rocket: [{
        tag: "path",
        attrs: {
          d: "M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09z"
        }
      }, {
        tag: "path",
        attrs: {
          d: "m12 15-3-3a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.35 22.35 0 0 1-4 2z"
        }
      }, {
        tag: "path",
        attrs: {
          d: "M9 12H4s.55-3.03 2-4c1.62-1.08 5 0 5 0"
        }
      }, {
        tag: "path",
        attrs: {
          d: "M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5"
        }
      }],
      terminal: [{
        tag: "polyline",
        attrs: {
          points: "4 17 10 11 4 5"
        }
      }, {
        tag: "line",
        attrs: {
          x1: "12",
          x2: "20",
          y1: "19",
          y2: "19"
        }
      }],
      testTube2: [{
        tag: "path",
        attrs: {
          d: "M21 7 6.82 21.18a2.83 2.83 0 0 1-3.99-.01a2.83 2.83 0 0 1 0-4L17 3"
        }
      }, {
        tag: "path",
        attrs: {
          d: "m16 2 6 6"
        }
      }, {
        tag: "path",
        attrs: {
          d: "M12 16H4"
        }
      }]
    };
    const SECTIONS = [{
      id: "modes-of-working",
      label: "Modes of Working",
      description: "p0 has different modes for different tasks. Pick the right one to get the best results.",
      tips: [{
        id: "brainstorm-mode",
        title: "Plan & Build Mode",
        description: "Use Plan & Build to flesh out an idea into a product spec, then let p0 build and QA it autonomously.",
        icon: "lightbulb"
      }, {
        id: "quick-changes",
        title: "Quick Changes (Chat)",
        description: "Ask p0 to fix bugs, refactor code, or make quick changes — just describe what you need.",
        icon: "messageSquare"
      }]
    }, {
      id: "project-setup",
      label: "Project Setup",
      description: "Open the Repositories manager from your sidebar to configure your project for p0.",
      tips: [{
        id: "engineering-standards",
        title: "Create Engineering Standards",
        description: "Define your coding conventions so p0 follows your team's patterns and preferences.",
        icon: "notebookText"
      }, {
        id: "qa-loops",
        title: "Create QA Loops",
        description: "Teach agents how to verify their work in your environment — URLs, credentials, and testing workflows.",
        icon: "testTube2"
      }, {
        id: "env-variables",
        title: "Set Up Environment Variables",
        description: "Configure .env files so p0 can run your project with the right secrets and config.",
        icon: "keyRound"
      }, {
        id: "run-commands",
        title: "Configure Run Commands",
        description: "Define how to start, build, or test your project so p0 can run it for you.",
        icon: "play"
      }, {
        id: "default-branch",
        title: "Set Default Branch",
        description: "Choose which branch p0 branches off from and creates PRs into for each repo.",
        icon: "gitPullRequestArrow"
      }]
    }, {
      id: "toolbar-actions",
      label: "Toolbar Actions",
      description: "On the top right of each session you'll find these tools to run, edit, and review your code.",
      tips: [{
        id: "open-terminal",
        title: "Open Terminal",
        description: "Launch a terminal inside your session's worktree to run commands without switching apps.",
        icon: "terminal"
      }, {
        id: "run-project",
        title: "Run Your Project",
        description: "Start your dev server or build process right from the session's worktree.",
        icon: "rocket"
      }, {
        id: "open-in-editor",
        title: "Open in Code Editor",
        description: "Open the session's worktree in your preferred code editor (VS Code, Cursor, etc.).",
        icon: "code"
      }, {
        id: "review-changes",
        title: "Review Changes",
        description: "See a diff of all changes p0 has made in the current session before committing.",
        icon: "gitCompare"
      }]
    }, {
      id: "advanced",
      label: "Advanced",
      description: "Power-user features that give you more control over how p0 works with your codebase.",
      tips: [{
        id: "worktrees",
        title: "Worktrees",
        description: "Each session branches off your repo's default branch into an isolated worktree — your main branch stays clean.",
        icon: "gitBranch"
      }, {
        id: "archive-sessions",
        title: "Archive & Unarchive Sessions",
        description: "Keep your sidebar clean by archiving old sessions. Right-click any session to archive or restore it.",
        icon: "archive"
      }]
    }];
    return <div className="p0-howto-dialog" role="img" aria-label="How to p0 dialog mock">
        <div className="p0-howto-dialog__header">
          <h3 className="p0-howto-dialog__title">How to p0</h3>
          <p className="p0-howto-dialog__subtitle">
            Learn everything p0 can do for you.
          </p>
        </div>

        {SECTIONS.map(section => <div key={section.id} className="p0-howto-dialog__section">
            <h4 className="p0-howto-dialog__section-heading">{section.label}</h4>
            <p className="p0-howto-dialog__section-desc">{section.description}</p>
            <ul className="p0-howto-dialog__tip-list">
              {section.tips.map(tip => <li key={tip.id} className="p0-howto-dialog__tip">
                  <span className="p0-howto-dialog__tip-check" aria-hidden="true" />
                  <span className="p0-howto-dialog__tip-body">
                    <span className="p0-howto-dialog__tip-title-row">
                      <svg {...htpIconBase} className="p0-howto-dialog__tip-icon">
                        {renderShapes(ICON_SHAPES[tip.icon] || [])}
                      </svg>
                      <span className="p0-howto-dialog__tip-title">{tip.title}</span>
                    </span>
                    <span className="p0-howto-dialog__tip-desc">{tip.description}</span>
                  </span>
                </li>)}
            </ul>
          </div>)}

        <div className="p0-howto-dialog__footer">
          <span className="p0-howto-dialog__footer-link">
            <svg {...htpIconBase} className="p0-howto-dialog__footer-icon">
              {renderShapes(ICON_SHAPES.book)}
            </svg>
            Open Documentation
          </span>
          <span className="p0-howto-dialog__footer-link">
            <svg {...htpIconBase} className="p0-howto-dialog__footer-icon">
              {renderShapes(ICON_SHAPES.messageCircle)}
            </svg>
            Join Community
          </span>
          <span className="p0-howto-dialog__footer-link">
            <svg {...htpIconBase} className="p0-howto-dialog__footer-icon">
              {renderShapes(ICON_SHAPES.calendarDays)}
            </svg>
            Book a Call
          </span>
        </div>
      </div>;
  }
  if (kind === "modelPicker") {
    const {current = "claude"} = rest;
    const mpIconBase = {
      ...iconBase,
      width: "16",
      height: "16"
    };
    const CHEVRON_SHAPES = [{
      tag: "path",
      attrs: {
        d: "m6 9 6 6 6-6"
      }
    }];
    const SPARKLES_SHAPES = [{
      tag: "path",
      attrs: {
        d: "M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"
      }
    }, {
      tag: "path",
      attrs: {
        d: "M20 3v4"
      }
    }, {
      tag: "path",
      attrs: {
        d: "M22 5h-4"
      }
    }, {
      tag: "path",
      attrs: {
        d: "M4 17v2"
      }
    }, {
      tag: "path",
      attrs: {
        d: "M5 18H3"
      }
    }];
    const CPU_SHAPES = [{
      tag: "rect",
      attrs: {
        width: "16",
        height: "16",
        x: "4",
        y: "4",
        rx: "2"
      }
    }, {
      tag: "rect",
      attrs: {
        width: "6",
        height: "6",
        x: "9",
        y: "9",
        rx: "1"
      }
    }, {
      tag: "path",
      attrs: {
        d: "M15 2v2"
      }
    }, {
      tag: "path",
      attrs: {
        d: "M15 20v2"
      }
    }, {
      tag: "path",
      attrs: {
        d: "M2 15h2"
      }
    }, {
      tag: "path",
      attrs: {
        d: "M2 9h2"
      }
    }, {
      tag: "path",
      attrs: {
        d: "M20 15h2"
      }
    }, {
      tag: "path",
      attrs: {
        d: "M20 9h2"
      }
    }, {
      tag: "path",
      attrs: {
        d: "M9 2v2"
      }
    }, {
      tag: "path",
      attrs: {
        d: "M9 20v2"
      }
    }];
    const MODEL_META = {
      claude: {
        label: "Claude",
        shapes: SPARKLES_SHAPES
      },
      codex: {
        label: "Codex",
        shapes: CPU_SHAPES
      }
    };
    const active = MODEL_META[current] ?? MODEL_META.claude;
    const alternateId = current === "claude" ? "codex" : "claude";
    const alternate = MODEL_META[alternateId];
    return <span className="p0-model-picker" role="img" aria-label={`Model picker mock, current selection ${active.label}`}>
        <button type="button" className="p0-model-picker__chip" aria-haspopup="listbox" aria-expanded="false">
          <svg {...mpIconBase} className="p0-model-picker__icon">
            {renderShapes(active.shapes)}
          </svg>
          <span className="p0-model-picker__label">{active.label}</span>
          <svg {...mpIconBase} className="p0-model-picker__chevron">
            {renderShapes(CHEVRON_SHAPES)}
          </svg>
        </button>
        <span className="p0-model-picker__menu" role="listbox" aria-hidden="true">
          <span className="p0-model-picker__option p0-model-picker__option--active">
            <svg {...mpIconBase} className="p0-model-picker__icon">
              {renderShapes(active.shapes)}
            </svg>
            <span className="p0-model-picker__label">{active.label}</span>
          </span>
          <span className="p0-model-picker__option">
            <svg {...mpIconBase} className="p0-model-picker__icon">
              {renderShapes(alternate.shapes)}
            </svg>
            <span className="p0-model-picker__label">{alternate.label}</span>
          </span>
        </span>
      </span>;
  }
  if (kind === "prCelebration") {
    const {prNumber, tokens, costCents} = rest;
    const formatCostCents = cents => {
      const safe = Number.isFinite(cents) ? Math.max(0, cents) : 0;
      return `$${(safe / 100).toFixed(2)}`;
    };
    const formatTokens = t => {
      const safe = Number.isFinite(t) ? Math.max(0, Math.floor(t)) : 0;
      return safe.toLocaleString("en-US");
    };
    const costLabel = formatCostCents(costCents);
    const tokenLabel = formatTokens(tokens);
    return <div className="p0-pr-celebration" role="img" aria-label={`PR shipped celebration overlay mock for PR #${prNumber}`}>
        <div className="p0-pr-celebration__backdrop" aria-hidden="true" />
        <div className="p0-pr-celebration__panel">
          <div className="p0-pr-celebration__icon" aria-hidden="true">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" width="16" height="16" className="p0-pr-celebration__icon-glyph" aria-hidden="true">
              <path d="M5.8 11.3 2 22l10.7-3.79" />
              <path d="M4 3h.01" />
              <path d="M22 8h.01" />
              <path d="M15 2h.01" />
              <path d="M22 20h.01" />
              <path d="m22 2-2.24.75a2.9 2.9 0 0 0-1.96 3.12c.1.86-.57 1.63-1.45 1.63h-.38c-.86 0-1.6.6-1.76 1.44L14 10" />
              <path d="m22 13-1.7.3c-.87.16-1.46.94-1.42 1.81v.5c.04.87-.55 1.65-1.42 1.81L16 18" />
              <path d="M3 7v4c0 1.1.9 2 2 2h4" />
              <path d="m7.5 11 4.55-4.55c.36-.36.85-.55 1.36-.45L17 7" />
            </svg>
          </div>
          <h3 className="p0-pr-celebration__title">Pull Request Created!</h3>
          <p className="p0-pr-celebration__pr">PR #{prNumber}</p>
          <p className="p0-pr-celebration__stats">
            <span className="p0-pr-celebration__stat-value">{tokenLabel}</span> tokens
            {" · "}
            <span className="p0-pr-celebration__stat-value">{costLabel}</span>
          </p>
          <div className="p0-pr-celebration__actions">
            <span className="p0-pr-celebration__btn p0-pr-celebration__btn--secondary">
              Continue
            </span>
            <span className="p0-pr-celebration__btn p0-pr-celebration__btn--primary">
              View PR
            </span>
          </div>
        </div>
      </div>;
  }
  if (kind === "contributionHeatmap") {
    const {weeks, seed} = rest;
    const ROWS = 7;
    const DEFAULT_WEEKS = 52;
    const DEFAULT_SEED = 42;
    const LEVELS = 5;
    const resolvedWeeks = weeks === undefined ? DEFAULT_WEEKS : weeks;
    const resolvedSeed = seed === undefined ? DEFAULT_SEED : seed;
    const makeRng = s => {
      let state = s >>> 0 || 1;
      return () => {
        state = Math.imul(state, 1664525) + 1013904223 >>> 0;
        return state;
      };
    };
    const pickLevel = rng => {
      const r = rng() >>> 16;
      if (r < 0.3 * 65536) return 0;
      if (r < 0.55 * 65536) return 1;
      if (r < 0.75 * 65536) return 2;
      if (r < 0.9 * 65536) return 3;
      return 4;
    };
    const rng = makeRng(resolvedSeed);
    const cells = [];
    for (let col = 0; col < resolvedWeeks; col++) {
      const column = [];
      for (let row = 0; row < ROWS; row++) {
        column.push(pickLevel(rng));
      }
      cells.push(column);
    }
    return <div className="p0-heatmap" role="img" aria-label={`Contribution heatmap mock — ${resolvedWeeks} weeks of activity`}>
        <div className="p0-heatmap__grid" aria-hidden="true">
          {cells.map((column, colIdx) => <div className="p0-heatmap__col" key={`col-${colIdx}`}>
              {column.map((level, rowIdx) => <span className={`p0-heatmap__cell p0-heatmap__cell--level-${level}`} key={`cell-${colIdx}-${rowIdx}`} />)}
            </div>)}
        </div>
        <div className="p0-heatmap__legend" aria-hidden="true">
          <span className="p0-heatmap__legend-label">Less</span>
          {Array.from({
      length: LEVELS
    }).map((_, i) => <span className={`p0-heatmap__cell p0-heatmap__cell--level-${i}`} key={`legend-${i}`} />)}
          <span className="p0-heatmap__legend-label">More</span>
        </div>
      </div>;
  }
  if (kind === "shareSheet") {
    const {link, teammates = [], expiry} = rest;
    const getInitials = name => {
      if (!name) return "?";
      const parts = name.trim().split(/\s+/);
      if (parts.length === 1) return parts[0].charAt(0).toUpperCase();
      return parts[0].charAt(0).toUpperCase() + parts[parts.length - 1].charAt(0).toUpperCase();
    };
    return <div className="p0-share-sheet" role="dialog" aria-label="Share session">
        <div className="p0-share-sheet__header">
          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" width="16" height="16" className="p0-share-sheet__icon" aria-hidden="true">
            <path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" />
            <path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" />
          </svg>
          <span className="p0-share-sheet__title">Share session</span>
        </div>

        <div className="p0-share-sheet__link-row">
          <input className="p0-share-sheet__link-input" type="text" value={link} readOnly aria-label="Share link" />
          <button className="p0-share-sheet__copy" type="button" aria-label="Copy link" onClick={event => event.preventDefault()}>
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" width="14" height="14" aria-hidden="true">
              <rect x="9" y="9" width="13" height="13" rx="2" ry="2" />
              <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" />
            </svg>
            <span>Copy</span>
          </button>
        </div>

        {teammates.length > 0 ? <div className="p0-share-sheet__teammates">
            <span className="p0-share-sheet__label">Shared with</span>
            <div className="p0-share-sheet__avatars">
              {teammates.map((member, idx) => member.avatar ? <img key={`${member.name}-${idx}`} className="p0-share-sheet__avatar p0-share-sheet__avatar--img" src={member.avatar} alt={member.name} /> : <span key={`${member.name}-${idx}`} className="p0-share-sheet__avatar p0-share-sheet__avatar--initials" aria-label={member.name} title={member.name}>
                    {getInitials(member.name)}
                  </span>)}
            </div>
          </div> : null}

        {expiry ? <div className="p0-share-sheet__expiry">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" width="12" height="12" aria-hidden="true">
              <circle cx="12" cy="12" r="10" />
              <polyline points="12 6 12 12 16 14" />
            </svg>
            <span>{expiry}</span>
          </div> : null}
      </div>;
  }
  if (kind === "reviewsBell") {
    const {unread} = rest;
    const BADGE_CAP = 99;
    const count = Number.isFinite(unread) ? unread : 0;
    const showBadge = count > 0;
    const label = count > BADGE_CAP ? `${BADGE_CAP}+` : String(count);
    return <span className={`p0-reviews-bell${showBadge ? " p0-reviews-bell--has-unread" : ""}`} role="status" aria-label={showBadge ? `Reviews — ${count} unread` : "Reviews — no unread feedback"}>
        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" width="18" height="18" className="p0-reviews-bell__icon" aria-hidden="true">
          <path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9" />
          <path d="M10.3 21a1.94 1.94 0 0 0 3.4 0" />
        </svg>
        {showBadge ? <span className="p0-reviews-bell__badge" aria-hidden="true">
            {label}
          </span> : null}
      </span>;
  }
  if (kind === "remoteControlQR") {
    const {code = "PURPLE"} = rest;
    const SIZE = 21;
    const FINDER = 7;
    const djb2 = input => {
      let hash = 5381;
      for (let i = 0; i < input.length; i++) {
        hash = (hash << 5) + hash + input.charCodeAt(i) | 0;
      }
      return hash >>> 0;
    };
    const makeRng = seed => {
      let state = seed >>> 0 || 1;
      return () => {
        state = Math.imul(state, 1664525) + 1013904223 >>> 0;
        return state;
      };
    };
    const isFinderCell = (row, col) => {
      const inTopLeft = row < FINDER && col < FINDER;
      const inTopRight = row < FINDER && col >= SIZE - FINDER;
      const inBottomLeft = row >= SIZE - FINDER && col < FINDER;
      return inTopLeft || inTopRight || inBottomLeft;
    };
    const finderFill = (row, col) => {
      let r = row;
      let c = col;
      if (col >= SIZE - FINDER) c = col - (SIZE - FINDER);
      if (row >= SIZE - FINDER) r = row - (SIZE - FINDER);
      const onOuterRing = r === 0 || r === 6 || c === 0 || c === 6;
      const inInnerSquare = r >= 2 && r <= 4 && c >= 2 && c <= 4;
      return onOuterRing || inInnerSquare;
    };
    const rng = makeRng(djb2(String(code)));
    const cells = [];
    for (let row = 0; row < SIZE; row++) {
      for (let col = 0; col < SIZE; col++) {
        let fill;
        if (isFinderCell(row, col)) {
          fill = finderFill(row, col);
        } else {
          fill = rng() >>> 31 === 1;
        }
        cells.push(fill);
      }
    }
    return <div className="p0-remote-qr" role="img" aria-label={`Illustrative QR mock for pairing code ${code}`}>
        <div className="p0-remote-qr__grid" style={{
      gridTemplateColumns: `repeat(${SIZE}, 1fr)`,
      gridTemplateRows: `repeat(${SIZE}, 1fr)`
    }} aria-hidden="true">
          {cells.map((fill, idx) => <span key={`qr-${idx}`} className={`p0-remote-qr__cell${fill ? " p0-remote-qr__cell--on" : ""}`} />)}
        </div>
        <div className="p0-remote-qr__caption">
          <span className="p0-remote-qr__illustrative">Illustrative</span>
          <span className="p0-remote-qr__code">{code}</span>
        </div>
        <div className="p0-remote-qr__status" role="status">
          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" width="14" height="14" className="p0-remote-qr__status-icon" aria-hidden="true">
            <rect x="5" y="2" width="14" height="20" rx="2" ry="2" />
            <path d="M12 18h.01" />
          </svg>
          <span>Waiting for phone…</span>
        </div>
      </div>;
  }
  if (kind === "kbdRow") {
    const {keys = [], description} = rest;
    return <span className="p0-kbd-row" role="group" aria-label={description}>
        <span className="p0-kbd-row__chips" aria-hidden="true">
          {keys.map((key, idx) => <span className="p0-kbd-row__chip" key={`kbd-${idx}-${key}`}>
              {idx > 0 ? <span className="p0-kbd-row__plus">+</span> : null}
              <kbd className="p0-kbd">{key}</kbd>
            </span>)}
        </span>
        <span className="p0-kbd-row__description">{description}</span>
      </span>;
  }
  if (kind === "renamedCallout") {
    const {from, to, version} = rest;
    return <span className="p0-renamed-callout" role="note">
        Renamed in v{version}:{" "}
        <span className="p0-renamed-callout__from">{from}</span>
        {" → "}
        <span className="p0-renamed-callout__to">{to}</span>
      </span>;
  }
  if (kind === "slashCommandsTable") {
    const SLASH_COMMANDS = [{
      command: "/agent",
      description: "Switch to Agent mode (applies changes directly)"
    }, {
      command: "/clear",
      description: "Start a new conversation (creates new sub-chat)"
    }, {
      command: "/compact",
      description: "Compact conversation context to reduce token usage"
    }, {
      command: "/config",
      description: "View and modify configuration settings"
    }, {
      command: "/cost",
      description: "Show token usage and cost for the session"
    }, {
      command: "/doctor",
      description: "Check the health of your p0 installation"
    }, {
      command: "/help",
      description: "Show available commands and help"
    }, {
      command: "/mcp",
      description: "View and manage MCP server connections"
    }, {
      command: "/memory",
      description: "View and edit CLAUDE.md memory files"
    }, {
      command: "/model",
      description: "Switch AI model"
    }, {
      command: "/permissions",
      description: "View and manage tool permissions"
    }, {
      command: "/plan",
      description: "Switch to Plan mode (creates plan before making changes)"
    }, {
      command: "/pr-comments",
      description: "Ask the agent to generate PR review comments"
    }, {
      command: "/release-notes",
      description: "Ask the agent to generate release notes"
    }, {
      command: "/review",
      description: "Ask the agent to review your code"
    }, {
      command: "/security-review",
      description: "Ask the agent to perform a security audit"
    }, {
      command: "/skills",
      description: "Manage your skills"
    }, {
      command: "/status",
      description: "Show current session status and context"
    }, {
      command: "/build-from-spec",
      description: "Run the end-to-end spec → build → QA pipeline"
    }, {
      command: "/create-standards",
      description: "Generate engineering standards for your workspace"
    }, {
      command: "/refine",
      description: "Make incremental changes to a recently built feature"
    }, {
      command: "/import-spec",
      description: "Import a product spec and ask clarifying questions"
    }];
    return <table>
        <thead>
          <tr>
            <th>Command</th>
            <th>What it does</th>
            <th>Where to find it</th>
          </tr>
        </thead>
        <tbody>
          {SLASH_COMMANDS.map(row => <tr key={row.command}>
              <td><code>{row.command}</code></td>
              <td>{row.description}</td>
              <td>Chat input · slash menu</td>
            </tr>)}
        </tbody>
      </table>;
  }
  return null;
};

Three collaboration surfaces, one page. Share a Phase 2 spec for review, watch the Reviews bell for incoming feedback, and pair your phone to check on sessions while you're away.

## Sharing a session

The **Share** button sits in the Phase 2 (Improve) header next to the Reviews bell. It's disabled until your product spec has content and you belong to a team. Clicking it opens a modal titled **Share this spec** with the description "Select teammates to review your work. They'll see your latest spec and can send you written feedback."

<Mock kind="shareSheet" link="p0://share/spec/sess_abc123" teammates={[{ name: "Alex Kim" }, { name: "Sam Patel" }]} />

The modal lists your teammates with a checkbox per row. Already-shared teammates show a **Shared** badge. A search field appears when the team has more than eight members. Click **Share** to confirm the selection — a toast confirms the count, and the bell appears for those reviewers.

If your team has no other members yet, the modal shows an empty state pointing you at team settings to invite teammates. (The link inside the empty state is a placeholder — open **Settings → Team Members** to invite people.)

Reviewers see the session in their sidebar under a **Shared Sessions** section. Unread shares get a blue dot. Clicking one opens a read-only **Reviewer View** with Product and Technical tabs — attachments and mockups are not synced. The reviewer types feedback in the composer; it lands back in your Reviews bell.

## Reviews

The bell icon appears in the Phase 2 header any time the session has been shared, even with zero reviews. When feedback lands, a numeric badge shows the unread count.

<Mock kind="reviewsBell" unread={3} />

Click the bell to open the popover. The header reads **Reviews (N)** with a **Mark all as read** action when there's anything unread. Each row shows the reviewer's avatar, name, relative timestamp, and feedback text. Two actions per row:

| Action         | What it does                                                                                |
| -------------- | ------------------------------------------------------------------------------------------- |
| **Send to p0** | Prefills the spec chat with `Apply these changes:` followed by the review text, then sends. |
| **Copy**       | Copies the review text to your clipboard.                                                   |

A dismiss X appears on hover. Reviews that are sent to p0 or dismissed disappear from the list. Closing the popover marks remaining reviews as read.

## Remote Control

Pair your phone with p0 to check on sessions and inject messages while you're away from your desk. Open **Settings → Remote Control** to set it up.

<Mock kind="remoteControlQR" />

Remote Control is **off by default**. The enrollment card explains what syncs and what doesn't, then offers a single **Turn on Remote Control** button. Once on, the tab shows a QR code linking to the web view, plus a copyable URL.

**What syncs.** Session titles, device label, connection status, and the last 5 messages per session.

**What stays local.** Full chat history, tool calls, file contents, terminal output, and worktree paths.

The **Device name** field labels this machine on your phone (placeholder: "Work laptop"). The status line shows `Connected · heartbeat 3s ago · 4 sessions synced` when the service is live, or `Disconnected · last heartbeat ...` when not. Flip the **Remote Control** switch off any time — the phone view goes offline immediately.

The QR code points at `${webUrl}/app/remote`. The `webUrl` host is the value of `MAIN_VITE_WEB_URL` at build time, so the exact domain depends on which build you installed.
