HarborHarbor
DocumentationGuidesPlugins
Recipes

HTML report from Orbit

Generate a styled HTML report and serve it from a signed Orbit storage URL. (Beta)

Beta

Uses /sdk/orbit HTML templates which are part of the Apps/Functions beta surface.

A Function that generates a polished HTML artifact (a weekly board, a project status, a per-customer report) and stores it under orbit.storage. You get a signed URL anyone with the link can open — no Harbor login required.

status-report.ts

defineJob({
  name: "weekly-status",
  description: "Generate this week's status report as a sharable HTML page.",
  handler: async (ctx) => {
    const rows = await ctx.plugins.linearMcp.listIssues({
      filter: { updatedAt: { gte: lastWeekISO() } },
      limit:  100,
    });

    const html = listPage({
      title:   "Weekly status",
      lead:    `${rows.length} updates this week.`,
      columns: [
        { key: "title",      label: "Issue" },
        { key: "state.name", label: "State" },
        { key: "assignee.name", label: "Owner" },
        { key: "updatedAt",  label: "Updated", type: "datetime" },
      ],
      rows,
    });

    const path = \`reports/weekly-\${todayISO()}.html\`;
    await ctx.orbit.storage.put(path, html, { contentType: "text/html" });
    const url  = await ctx.orbit.storage.url(path, { expiresIn: "14d" });

    return { url, count: rows.length };
  },
});

function todayISO()    { return new Date().toISOString().slice(0, 10); }
function lastWeekISO() {
  return new Date(Date.now() - 7 * 86_400_000).toISOString();
}

What you get

The listPage template applies sensible defaults (Inter font, neutral palette, responsive table). For your own brand colors, override CSS variables in the template options.

Variations

  • Per-team reports: loop teams, generate one file per team, return the list of URLs.
  • Public report: drop the signed-URL step and instead expose via an App route with auth: "public".
  • Embeddable widget: include { embedMode: true } to render without the page chrome.

See Authoring → App UI for the full template catalogue.