> ## 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.

# Repo manager

> Add, configure, and remove the repositories that live inside a workspace.

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;
};

The repo manager is where you wire up the git repos a [workspace](/workspaces) contains. It opens as a dialog titled **Repository Manager** and lists every repo registered to the workspace along with its clone status.

You can open it two ways:

* From the sidebar's repos section, click the **Manage repositories →** link at the bottom.
* From the run sidebar's "No run script configured" state, click **Open Repository Manager**.

## What the dialog shows

Each row is one repo with a status badge. Status is one of:

* **Cloned** — the repo exists on disk inside the workspace.
* **Pending** — registered but not yet cloned.
* **Cloning** — clone in progress.
* **Error** — the last clone or pull attempt failed.

A search box filters by name, URL, or local path. Filter chips (**All**, **Cloned**, **Pending**, **Errors**) narrow the list to one status group.

## Adding a repo

Click **Add** to open the **Add Repositories** dialog. It has three tabs:

* **Browse** — picks from the repos already on your linked GitHub or GitLab account. Multi-select; **Add** clones each one.
* **Add by URL** — paste an HTTPS URL and pick a default branch via the branch selector. Supported hosts are **GitHub**, **GitLab**, and **Bitbucket**. If the host isn't recognized, a dropdown asks which provider hosts it (GitHub or GitLab).
* **Create New** — creates a brand-new repository on GitHub or GitLab (toggle at the top of the tab), with a **Private** or **Public** visibility choice, and then adds it to the workspace.

After adding, p0 clones the repo into the workspace under `repos/{repo-name}`.

## Default branch

Every repo has a default branch. p0 uses it when creating new [sessions](/sessions/overview) — sessions branch off from this branch. You can change it from the repo row's branch picker (titled **Change Default Branch**); p0 lists the remote branches with a search box and marks the current default. If the remote can't be reached, p0 falls back to the locally available branches and shows an amber warning.

The default branch is also asked for when you add a repo by URL — the field is pre-filled with `main`.

## Multiple repos in one workspace

A workspace can host as many repos as you want. They appear together in the sidebar's repos section and in the run sidebar's tab bar (one tab per repo, plus extra tabs for monorepo sub-paths that have their own run script). Batch actions in the manager apply across them all:

* **Refresh** — re-syncs the repo list from the Purple API.
* **Clone All** — clones every pending repo.
* **Pull All** — runs `git pull` on every cloned repo.

<Mock kind="sidebar" sessions={[]} repos={[{name: "acme-app"}, {name: "acme-api"}]} />

## Removing a repo

The remove control on a repo row opens a **Remove Repository?** confirmation. If the repo is cloned locally, the dialog shows the local path and offers an **Also delete local clone** checkbox. Leaving it unchecked unregisters the repo from the workspace but keeps the files on disk.
