Features
tab.json — Your own workspace tab
Last updated: 2026-09-21
On iOS, add .repogo/tab.json to a workspace to show your own tab beside
Browser and Terminal. A tab shows a workspace HTML page, a markdown file, or a
website, and appears in the preview tabs and the inspector picker.
What it looks like#
{
"label": "Dashboard",
"path": "docs/dashboard.html",
"icon": { "ios": "chart.bar.fill" }
}Save this as .repogo/tab.json. A Dashboard tab appears beside Browser and Terminal and opens docs/dashboard.html.
path is relative to the workspace root. The optional icon.ios value is an
SF Symbol name; a missing or unknown symbol falls back to the default tab icon.
Custom tabs are currently available on iOS only.
Several pages#
List them under tabs. The top-level label and icon name the tab itself
(defaulting to "Pages"); each entry names a row. The tab opens as a list, and
tapping a row opens that page:
{
"label": "Pages",
"icon": { "ios": "doc.richtext" },
"tabs": [
{ "label": "Dashboard", "path": ".repogo/dashboard.html", "icon": { "ios": "chart.bar.xaxis" } },
{ "label": "Runbook", "path": ".repogo/runbook.md", "icon": { "ios": "book" } },
{ "label": "Documentation", "url": "https://example.com/docs", "icon": { "ios": "globe" } }
]
}A tabs list with one entry behaves like the single-page form and opens
straight into the page. File, markdown, and URL pages can be mixed.
Sections#
To group the rows, use sections instead of tabs. Each section has an
optional label, shown as its header, and its own tabs:
{
"label": "Pages",
"icon": { "ios": "doc.richtext" },
"sections": [
{
"label": "Dashboards",
"tabs": [
{ "label": "Overview", "path": ".repogo/overview.html", "icon": { "ios": "chart.bar.xaxis" } },
{ "label": "Usage", "path": ".repogo/usage.html", "icon": { "ios": "gauge" } }
]
},
{
"label": "Docs",
"tabs": [
{ "label": "Runbook", "path": "docs/RUNBOOK.md", "icon": { "ios": "book" } },
{ "label": "API Reference", "url": "https://example.com/api", "icon": { "ios": "globe" } }
]
}
]
}A section without a label groups its rows with no header. A section whose
rows are all skipped is dropped. If only one section remains, its header is
omitted and the tab shows a flat list; if only one row remains, the tab opens
straight into that page.
Badges#
Any row in tabs can show a small status chip before its chevron — handy for
marking plans as draft, in review, or shipped:
{ "label": "Auth Rewrite", "path": "plans/auth.md", "icon": { "ios": "doc.text" },
"badge": { "label": "In review", "color": "#F59E0B" } }badge.label is the chip's text. badge.color is optional and takes a
#RGB or #RRGGBB hex value, used as the chip's tint; leave it out, or give
an unrecognized value, for a neutral gray chip. Long chip text is truncated so
the row label keeps its space. Badges only appear in the list; a tab that opens
straight into a single page has no row to show one on.
Markdown pages#
A path ending in .md, .mdx, or .markdown renders as formatted markdown
with headings, lists, tables, code blocks, and task lists. Links to other files in the
workspace open them in the editor; web links open the in-app browser.
{
"label": "Runbook",
"path": "docs/RUNBOOK.md",
"icon": { "ios": "book" }
}Websites#
{
"label": "Documentation",
"url": "https://example.com/docs",
"icon": { "ios": "globe" }
}URLs must be absolute HTTP or HTTPS addresses with a hostname. Websites load inside the tab in a private web session, separate from Browser sign-ins.
Reaching your dev server#
HTML pages reach your Mac's dev server the same way the Browser tab does. A
path page is served from http://localhost:<port>/ — the on-device forwarder
that proxies to the paired Mac — so a relative fetch("/api/…") in your HTML
lands on the server running there. The port is the top-level port (default
3000):
{
"label": "Dashboard",
"port": 5173,
"path": ".repogo/dashboard.html"
}A url page on localhost:<port> is forwarded the same way, so the Mac's dev
server can also serve the whole page. The forwarder runs while RepoGo is in the
foreground and needs the workspace's paired Mac; cloud sandboxes answer 502.
What gets skipped#
Each page needs exactly one of path or url. Entries with missing or
conflicting sources, empty labels or paths, or unsupported URLs are skipped; if
none remain in any section, the tab is omitted. Malformed JSON or incorrect field types omit
the manifest entirely.