跳到正文
cccskills
免费在 GitHub 公开

build-dashboard

Build the user interface for a holaOS app whose data resources are already connected through the SDK. Choose a feed, table, kanban board, form, or calendar layout using shared components and workspace styling.

中文简介正在准备中。当前显示英语简介。

原文查看原文说明

Build the visual layer of a holaOS dashboard app — TanStack Start + @holaboss/ui + workspace tokens. Use when an app has SDK primitives wired (via app-builder-sdk) AND needs a `src/client/` UI surface. NOT for marketing pages, NOT for snapshot HTML reports.

查看安装方法

适用场景

  • Display scheduled items in a chronological feed
  • Show CRM contacts or tickets in a table
  • Organize issues by status on a kanban board
  • Build a form for editing a single record

包含的文件(10)

  • SKILL.md25.5 KB
  • reference/messaging-dashboard/README.md7.6 KB
  • reference/messaging-dashboard/src/client/app.css466 B
  • reference/messaging-dashboard/src/client/components/connection-pill.tsx839 B
  • reference/messaging-dashboard/src/client/components/header-bar.tsx1.2 KB
  • reference/messaging-dashboard/src/client/components/messages-table.tsx5.0 KB
  • reference/messaging-dashboard/src/client/components/status-badge.tsx727 B
  • reference/messaging-dashboard/src/client/lib/sample-data.ts1.9 KB
  • reference/messaging-dashboard/src/client/routes/__root.tsx479 B
  • reference/messaging-dashboard/src/client/routes/index.tsx3.7 KB

SKILL.md(原文)

安装前可以查看交给 AI 代理的指令内容。

build-dashboard

The agent before you reliably produces ugly dashboards because it starts from a blank page and reaches for default shapes (single-column full-width cards, KPI strips that don't fit, sidebars that don't earn their space). This skill exists to bypass that default. The visual decisions are already made — your job is to fill in the data and copy.

When to use

  • The user asked for a dashboard, workspace pane, list view, kanban, calendar, or "let me see my X"
  • The app's app.ts already declares resource(...) rows via the SDK (set up via the app-builder-sdk skill first)
  • The app dir needs a src/client/ directory

Skip this skill when:

  • Integration-only module (Slack/Discord/Stripe-style MCP-only) — those use only app-builder-sdk
  • Marketing landing page → use frontend-design
  • One-off static HTML report → not this product class

The two non-negotiables

  1. Copy the bundled reference. Don't invent. reference/messaging-dashboard/src/client/ is the canonical starting point. Three files below are verbatim across every dashboard; the rest gets customized per shape.
  2. Two style imports, not one. @holaboss/ui/styles.css only bakes in utilities used inside the library. Every Tailwind class your src/client/ writes needs your own app-side compile pass. The register-time lint workspace_app_missing_tailwind_compile rejects apps missing this.

The shape catalog — pick one

Look at the user's data, NOT at "what dashboards usually have". Most apps are shape 1.

#ShapePick when the data is…Template
1Queue / feedscheduled items, drafts, an action queue, an activity log, anything time-orderedreference/messaging-dashboard/ (full, ready to copy)
2Dense tableflat records (CRM contacts, log rows, ticket list) that the user scans like a spreadsheetReplace shape-1's messages-table.tsx with the <Table> primitive (see snippet below)
3Kanbanrows that move between named statuses; user drags between columnsReplace shape-1's main column with horizontal status columns (see snippet below)
4Detail / forma single resource the user edits or watches in depthReplace shape-1's main column with <Field> form (see snippet below)
5Calendar weekrows with start_time + duration that pin to a day-gridReplace shape-1's main column with @holaboss/ui's Calendar primitive

Shapes 2–5 still keep shape 1's header, app.css, connection pill, status badge, and tokens. Only the main content area changes.

ASCII for shape 1 (the most common, read this even if you're using another shape):

                ┌────────────────────────────────────────────┐
                │  Outgoing ●            ● Connected · @jot  │  ← header
                │  5 queued · agent will send on schedule    │
                │                                            │
                │  NEEDS ATTENTION                           │
                │  ┌──────────────────────────────────┐     │  ← attention strip
                │  │ #ops · Failed · 3h ago           │     │    (warning-bordered,
                │  │  Composio retry exhausted…       │     │     always-visible Retry)
                │  │                  [Retry] [Edit]  │     │
                │  └──────────────────────────────────┘     │
                │                                            │
                │  TODAY ───────────────────────────── 02   │  ← day divider
                │  NOW · 08:42 ─────────────────────────    │  ← "now" cursor on rail
                │  09:00 ● #general · ● Scheduled            │  ← next-up marker
                │        Heads-up: pricing page goes live…  │
                │  17:00 · #growth · ● Draft                 │
                │        Weekly recap — KPI strip…           │
                │                                            │
                │  TOMORROW ────────────────────────── 02   │
                │  …                                         │
                └────────────────────────────────────────────┘
                       (max-w-3xl centered on bg-background)

Foundation — paste verbatim into every dashboard

These five files do NOT vary per shape. Copy them exactly.

src/client/app.css (13 lines)

/* App-local Tailwind compile entry.
 *
 * `@holaboss/ui/styles.css` only bakes in utilities used INSIDE the library.
 * Every Tailwind class your `src/client/` writes (max-w-3xl, grid-cols-*,
 * text-fg-48, bg-card, flex-1, etc.) needs an app-side compile pass to land
 * in the bundle. Without it the page renders mostly unstyled.
 *
 * Required by the register-time lint `workspace_app_missing_tailwind_compile`.
 */

@import "tailwindcss";

@source "../client";

src/client/routes/__root.tsx

import "@holaboss/ui/styles.css"
import "../app.css"

import type { ReactNode } from "react"

export function RootLayout({ children }: { children: ReactNode }) {
  return (
    <html lang="en" data-theme="holaos-light">
      <head>
        <meta charSet="utf-8" />
        <meta name="viewport" content="width=device-width,initial-scale=1" />
        <title>Your App — holaOS</title>
      </head>
      <body className="antialiased">{children}</body>
    </html>
  )
}

src/client/components/connection-pill.tsx

import { StatusDot } from "@holaboss/ui"

type Props = {
  state: "ready" | "needs_connect" | "needs_reauth" | "checking"
  handle?: string
}

const COPY: Record<Props["state"], { label: string; tone: "success" | "warning" | "muted" }> = {
  ready: { label: "Connected", tone: "success" },
  needs_connect: { label: "Not connected", tone: "warning" },
  needs_reauth: { label: "Reauth required", tone: "warning" },
  checking: { label: "Checking…", tone: "muted" },
}

export function ConnectionPill({ state, handle }: Props) {
  const { label, tone } = COPY[state]
  return (
    <span className="inline-flex items-center gap-1.5 text-xs text-fg-64">
      <StatusDot variant={tone} size="sm" />
      <span className="text-fg-80">{label}</span>
      {handle ? <span className="text-fg-48">· {handle}</span> : null}
    </span>
  )
}

Wire state from getIntegrationStatus() — ready === true → "ready", code === "integration_not_connected" → "needs_connect", code === "integration_needs_reauth" → "needs_reauth". See app-builder-sdk skill for the helper.

src/client/components/header-bar.tsx

import { Button, StatusDot } from "@holaboss/ui"
import { Plus } from "lucide-react"
import type { ReactNode } from "react"

type Props = {
  title: string
  subtitle?: string
  rightSlot?: ReactNode
  onCompose?: () => void
}

export function HeaderBar({ title, subtitle, rightSlot, onCompose }: Props) {
  return (
    <header className="px-10 pt-12 pb-8">
      <div className="flex items-center gap-3">
        <div className="flex min-w-0 flex-1 items-center gap-2.5">
          <h1
            className="font-serif text-[22px] leading-none text-foreground"
            style={{ fontFamily: "'Source Serif 4', serif", fontWeight: 500 }}
          >
            {title}
          </h1>
          <StatusDot variant="success" size="sm" pulse />
        </div>
        {rightSlot}
        <Button
          variant="ghost"
          size="sm"
          onClick={onCompose}
          className="h-7 gap-1.5 px-2 text-xs text-fg-64 hover:text-foreground"
        >
          <Plus className="size-3" />
          Add draft
        </Button>
      </div>
      {subtitle ? (
        <p className="mt-2 truncate text-xs text-fg-48">{subtitle}</p>
      ) : null}
    </header>
  )
}

src/client/components/status-badge.tsx

import { StatusDot } from "@holaboss/ui"

// REPLACE this union with your resource's state machine.
type MyStatus = "draft" | "scheduled" | "sent" | "edited" | "failed"

// REPLACE this map: one entry per state with its label and dot variant.
// Use `success` for completed/healthy, `info` for in-flight/scheduled,
// `muted` for inert/draft, `warning` for soft problems, `destructive`
// for hard failures.
const MAP: Record<MyStatus, { label: string; dot: "success" | "warning" | "destructive" | "muted" | "info" }> = {
  draft: { label: "Draft", dot: "muted" },
  scheduled: { label: "Scheduled", dot: "info" },
  sent: { label: "Sent", dot: "success" },
  edited: { label: "Edited", dot: "info" },
  failed: { label: "Failed", dot: "destructive" },
}

export function StatusBadge({ status }: { status: MyStatus }) {
  const { label, dot } = MAP[status]
  return (
    <span className="inline-flex items-center gap-1 text-[11px] text-fg-64">
      <StatusDot variant={dot} size="sm" />
      {label}
    </span>
  )
}

Shape 1: queue / feed (canonical, fully bundled)

The full implementation is bundled at reference/messaging-dashboard/src/client/ next to this skill. Two files vary per app — read them directly from the bundled reference:

  • routes/index.tsx — page composition (~100 lines). Sets up the 3-region layout: header → attention strip → grouped sections. Read this whole file before copying.
  • components/messages-table.tsx — the row + rail + attention list (~150 lines). The hardest file; spent the most iteration. Read this whole file before copying.
  • lib/sample-data.ts — mock data with the MessageRow shape (channel / text / status / bucket / timeLabel / authorHandle / errorReason). Replace this file entirely with TanStack Start server functions that read from your app.resource() rows.

What to swap when copying shape 1:

FileChangeKeep
lib/sample-data.tsReplace entirely with server functions; rename to data.ts.The row shape — your data should map to the same field set, or the table needs JSX changes too.
routes/index.tsxPage title ("Outgoing"), subtitle, nowLabel (real current time), day-divider labels.The 3-region structure (header → attention → grouped sections), max-w-3xl, spatial sketch comment, useMemo grouping.
messages-table.tsxColumn meta layout (#{channel} · author · time), body field, error-reason placement.3-col grid (64px_16px_1fr_auto), rail (bg-fg-32), marker treatment, attention strip styling.
status-badge.tsxMAP lookup → your states.Component shape.
header-bar.tsx, connection-pill.tsx, __root.tsx, app.cssnothing.everything.

Shape 2: dense table (CRM / log / ticket list)

When the data is naturally rows-and-columns and the user scans like a spreadsheet, replace shape-1's messages-table.tsx with the <Table> primitive. Header + connection pill + app.css setup stay.

import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, Badge } from "@holaboss/ui"
import { StatusBadge } from "./status-badge"

export function RecordsTable({ rows }: { rows: MyRow[] }) {
  return (
    <Table className="text-[13px]">
      <TableHeader>
        <TableRow className="text-fg-48">
          <TableHead className="w-[180px] pl-6">Name</TableHead>
          <TableHead>Email</TableHead>
          <TableHead className="w-[140px]">Owner</TableHead>
          <TableHead className="w-[120px]">Status</TableHead>
          <TableHead className="w-[140px] text-right pr-6">Last touch</TableHead>
        </TableRow>
      </TableHeader>
      <TableBody>
        {rows.map((row) => (
          <TableRow key={row.id} className="hover:bg-muted/40">
            <TableCell className="pl-6 text-foreground">{row.name}</TableCell>
            <TableCell className="text-fg-64">{row.email}</TableCell>
            <TableCell className="text-fg-64">{row.owner}</TableCell>
            <TableCell><StatusBadge status={row.status} /></TableCell>
            <TableCell className="text-right text-fg-64 tabular-nums pr-6">{row.lastTouchLabel}</TableCell>
          </TableRow>
        ))}
      </TableBody>
    </Table>
  )
}

Layout shape: drop the time-rail; keep max-w-3xl (or bump to max-w-5xl if 5+ columns). Day-divider sections from shape 1 become optional — usually one flat table is fine.

Shape 3: kanban (status board)

When rows move between named statuses and the user drags between them. Replace shape-1's main column with horizontally-arranged status columns. Header + connection pill + app.css stay.

import { Card } from "@holaboss/ui"
import { StatusBadge } from "./status-badge"

const COLUMNS = ["draft", "scheduled", "sent", "failed"] as const

export function KanbanBoard({ rows }: { rows: MyRow[] }) {
  const byStatus = COLUMNS.map((status) => ({
    status,
    rows: rows.filter((r) => r.status === status),
  }))

  return (
    <div className="grid grid-cols-4 gap-3 px-10 pb-12">
      {byStatus.map(({ status, rows }) => (
        <div key={status} className="flex flex-col gap-2">
          <div className="flex items-baseline justify-between px-1">
            <span className="text-[10px] tracking-wider text-fg-48 uppercase">{status}</span>
            <span className="font-mono text-[10px] text-fg-32 tabular-nums">
              {rows.length.toString().padStart(2, "0")}
            </span>
          </div>
          <div className="flex flex-col gap-2">
            {rows.map((row) => (
              <Card key={row.id} size="sm" className="cursor-pointer hover:bg-muted/40">
                <div className="px-3 py-2">
                  <div className="text-[11px] text-fg-48">#{row.channel}</div>
                  <p className="mt-1 line-clamp-3 text-sm leading-snug text-fg-80">{row.text}</p>
                  <div className="mt-2">
                    <StatusBadge status={row.status} />
                  </div>
                </div>
              </Card>
            ))}
          </div>
        </div>
      ))}
    </div>
  )
}

Layout shape: change max-w-3xl on the outer container to max-w-6xl for breathing room. Drop the attention strip (failed rows surface naturally in the "failed" column).

Shape 4: single-resource detail / form

For workflows where the user edits one resource at a time (settings, single-record CRM contact, single bookmark editor). Replace shape-1's main column with a <Field>-based form. Header + connection pill + app.css stay.

import { Button, Field, FieldDescription, FieldGroup, FieldLabel, Input, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Textarea } from "@holaboss/ui"

export function RecordForm({ record, onSave }: { record: MyRow; onSave: (r: MyRow) => void }) {
  return (
    <form className="mx-auto flex max-w-2xl flex-col gap-6 px-10 pb-12">
      <FieldGroup>
        <Field>
          <FieldLabel>Title</FieldLabel>
          <Input defaultValue={record.title} />
        </Field>
        <Field>
          <FieldLabel>Owner</FieldLabel>
          <Select defaultValue={record.owner}>
            <SelectTrigger><SelectValue /></SelectTrigger>
            <SelectContent>
              <SelectItem value="alice">Alice</SelectItem>
              <SelectItem value="bob">Bob</SelectItem>
            </SelectContent>
          </Select>
        </Field>
        <Field>
          <FieldLabel>Notes</FieldLabel>
          <Textarea rows={6} defaultValue={record.notes} />
          <FieldDescription>Markdown is supported.</FieldDescription>
        </Field>
      </FieldGroup>
      <div className="flex justify-end gap-2">
        <Button variant="ghost" type="button">Cancel</Button>
        <Button type="submit">Save</Button>
      </div>
    </form>
  )
}

Layout shape: tighter column (max-w-2xl). No attention strip; surface validation errors inline via FieldError.

Shape 5: calendar week

When rows have a real start_time + duration that pin to a day-grid. Use @holaboss/ui's Calendar primitive. This shape is intentionally less battle-tested — extend the base only when calendar truly fits.

import { Calendar } from "@holaboss/ui"

export function WeekCalendar({ rows }: { rows: MyRow[] }) {
  // Calendar is the base-ui primitive; for full week-view with custom
  // event rendering you'll need to compose it yourself. The skeleton:
  return (
    <div className="px-10 pb-12">
      <Calendar mode="single" />
      {/* Layer events on top via absolute-positioned cards keyed by date. */}
    </div>
  )
}

Wiring the rest of the app

Everything below is the same as the app-builder-sdk skill describes for any app — repeat here only for the dashboard-specific gotchas.

Required deps in package.json

{
  "dependencies": {
    "@holaboss/app-builder-sdk": "latest",
    "@holaboss/ui": "latest",
    "react": "^19.0.0",
    "react-dom": "^19.0.0",
    "lucide-react": "^0.542.0"
  },
  "devDependencies": {
    "@tailwindcss/vite": "^4.2.1",
    "@vitejs/plugin-react": "^5.0.0",
    "tailwindcss": "^4.2.1",
    "vite": "^6.3.0"
  }
}

Use "latest" literally for the two @holaboss/* packages — pre-1.0 caret semver drifts.

Required vite.config.ts

import tailwind from "@tailwindcss/vite"
import react from "@vitejs/plugin-react"
import { defineConfig } from "vite"

export default defineConfig({
  plugins: [react(), tailwind()],
})

Without @tailwindcss/vite, the @import "tailwindcss" in app.css is a no-op and your custom utilities don't compile.

server.ts boots BOTH MCP and the dashboard

import { startMcpServer, SqliteStateBackend, createRuntimeBrokerTransport } from "@holaboss/app-builder-sdk"
import { buildMyApp } from "./app.ts"

const state = new SqliteStateBackend({ path: process.env.WORKSPACE_DB_PATH! })
const bridge = createRuntimeBrokerTransport({ provider: "<provider>" })
const app = buildMyApp({ state, bridge })

// MCP for the agent
await startMcpServer({
  port: Number(process.env.MCP_PORT),
  app, bridge,
})

// Dashboard for the user (iframe loads this URL)
// Use TanStack Start's production build output OR Vite's dev server.
// IMPORTANT: read from the SAME SqliteStateBackend the SDK uses; never
// spin up a second DB.
import { build } from "./client/build"
Bun.serve({ port: Number(process.env.PORT), fetch: build.fetch })

The desktop's AppSurfacePane iframe resolves to process.env.PORT — whatever you serve there is what the user sees.

Required setup checklist (lint-enforced)

The register-time lint rejects dashboard apps that fail any of these. Run through the list before declaring done.

CheckLint code (if fails)
src/client/ has ≥3 distinct named imports from @holaboss/uiworkspace_app_holaboss_ui_named_imports_too_few
At least one .css file under src/client/ contains @import "tailwindcss"workspace_app_missing_tailwind_compile
No hex / rgb() / hsl() / oklch() literals in src/client/**/*.cssworkspace_app_parallel_design_system
No custom --<token>: definitions in CSS (passthroughs like --mine: var(--background) allowed)workspace_app_parallel_design_system

If any lint fires, the runtime returns the file + line + suggested fix. Don't try to bypass — read the message and fix the root cause.

What you may NOT do (read once, internalize)

These are hard rules. The lint catches some; the rest are caught by review (or by the user noticing the dashboard looks alien).

  • No font-bold / font-semibold / font-extrabold / inline style={{ fontWeight: ... }}. Design system clamps all of those to 500. Hierarchy comes from size (text-2xl for hero numbers, text-base for headings, text-xs for labels) and color (text-foreground → text-fg-80 → text-fg-64 → text-fg-48).
  • No hex / rgb() / oklch() literals anywhere. Lint rejects in CSS; review catches in JSX. Use tokens: bg-background, bg-card, bg-muted, text-foreground, text-fg-{12,16,32,48,64,80,92}, border, border-warning, bg-warning/[0.06], text-primary.
  • No second component library. No MUI, Ant, Chakra, raw Radix, Headless UI, react-aria. The @holaboss/ui package wraps base-ui's shadcn-flavored primitives; that is the only allowed source.
  • No components/ui/ directory (shadcn-add copy). Import primitives from @holaboss/ui only.
  • No bg-gradient-* on cards, no hover:shadow-*, no hover:-translate-y-* lift effects. Subtle hover via hover:bg-muted/40 only.
  • No per-app theme toggle. Theme is workspace-level; the app inherits via CSS variables.
  • No custom CSS files beyond app.css (and app.css must contain only @import "tailwindcss" + @source, possibly empty @layer blocks).
  • No KPI strip "because dashboards usually have them". Add stat cards only when the user genuinely tracks ≥3 comparable numbers that need to sit side-by-side. The single count of "5 queued" goes in the subtitle, not in a card.
  • No sidebar "because dashboards usually have them". Add one only when the user has a genuine second navigation axis that must stay on screen (multi-channel chat, multi-project switcher).
  • No Promise.all rendering gate. Each card / table / chart renders the moment its own data lands, with Skeleton during fetch and EmptyState if empty. A 0.5s skeleton beats a 4s blank page.

What you SHOULD do

  • Read reference/messaging-dashboard/ end-to-end (it lives next to this skill — 4 component files, 1 lib file, 1 routes file). Even if your shape isn't queue/feed, the patterns transfer.
  • Spend 30 seconds on a one-line spatial sketch BEFORE writing JSX. Single sentence: "Header strip + grouped sections of rows" or "Header + 4-column kanban". If you can't say it in one sentence, pick from the shape catalog above.
  • Replace lib/sample-data.ts with TanStack Start server functions that read from the SDK's SqliteStateBackend (the table app.resource() declared). Never spin up a second DB. Never call MCP tools from the dashboard.
  • Wire ConnectionPill to getIntegrationStatus() (helper from @holaboss/app-builder-sdk). The four state values map directly to readiness codes.
  • Test in both light AND dark. Workspace theme can be either; the dashboard inherits via [data-theme]. Set data-theme="holaos-dark" on <html> to verify dark renders correctly.

Examples

User: "Build a GitHub work tracker dashboard"
→ Shape 1 (queue / feed). Rows = issues + PRs, grouped by today / this week / older.
  Status mapping: open → info, in_progress → success, closed → muted, failed → destructive.
  Replace `sample-data.ts` with a server function reading from your `app.resource("issue")` rows.

User: "Make me a Notion page tracker"
→ Shape 2 (dense table). One row per page, columns: title / database / author / last-edited / status.
  No attention strip; just one flat sortable table.

User: "I want to see my Linear issues organized by status"
→ Shape 3 (kanban). Columns: backlog / todo / in-progress / done / canceled. Cards have title + assignee + priority.

User: "I want to manage my Mailchimp campaigns"
→ Shape 1 (queue / feed) grouped by send time — campaigns are time-ordered drafts → scheduled → sent, exactly the messaging metaphor.

User: "I want a calendar of my upcoming gcal events"
→ Shape 5 (calendar week). Compose from `Calendar` primitive; this is the least-tested shape, expect to iterate.

When you're done

Run through this list — if any item is uncertain, fix before declaring done:

  1. bun install in the app dir → exit 0
  2. bun run server.ts → "MCP server listening on :<port>" AND dashboard responds on :$PORT
  3. curl http://localhost:<PORT>/ returns a TanStack Start HTML response, NOT the SDK's "headless module" placeholder (search for headless module in the response body)
  4. Open the dashboard in the desktop iframe. Visually:
    • Fonts are Inter + Source Serif 4 (NOT Times / system-ui)
    • Connection pill shows correct state (Connected / Reauth / Not connected)
    • Empty state renders when filtered to a status with no rows
    • Hover affordances on rows (subtle bg shift, no shadow lift)
    • Light mode AND dark mode both look intentional (set data-theme="holaos-dark" on <html> to test)
  5. The dashboard looks like the rest of the workspace (same fonts, borders, radii, card surface color). If it looks alien, you've broken a token import, imported from outside @holaboss/ui, or redefined a primitive.

If all 5 pass, you're done. Do not invoke interface-design. The build pass should already produce shipping-quality output via this skill + the bundled reference + the register-time lints.

If you later receive an [Auto-queued post-build polish pass] input for this app (the runtime queues one when a binding completes and unblocks pendingIntegrations), re-enter this skill — not interface-design — and re-evaluate src/client/ against the bundled reference now that real data is wired in. That second pass is the safety net for cases the build-time agent finished before the integrations were connected, not a license to add chrome that this skill didn't already endorse.

评价

还没有评价。欢迎分享你的使用感受。

评论

无需登录即可发表。欢迎分享使用感受、提问,或说明在哪些环境下无法运行。

还没有评论。来写第一条吧。

提交后会立即公开。请勿填写邮箱、电话等个人信息。URL 最多 2 个。

0 / 1000 字

此表单受 reCAPTCHA 保护,适用 Google 的隐私权政策和服务条款。

同一仓库的技能

Build holaOS apps for connecting external services or managing work through a dashboard. The skill uses shared SDK building blocks for stored records, actions, and synchronization, with the dashboard and agent tools working on the same data.

中文简介正在准备中。当前显示英语简介。

  • Building an external service integration
  • Creating a CRM dashboard
  • Building a content planning workspace
holaboss-ai/holaOS1.1万2026年8月21日 更新

Analyze audience demographics and engagement to identify distinct groups, understand what they want, and prioritize valuable segments. Turn those findings into recommendations for content topics, formats, posting times, and tone, while explaining limits in the data.

中文简介正在准备中。当前显示英语简介。

  • Identify distinct groups within an audience
  • Prioritize groups that engage or convert
  • Plan topics and formats for each audience group
holaboss-ai/holaOS1.1万2026年8月21日 更新

Guide an agent through efficient use of an embedded browser by choosing targeted actions, searches, and waits. Reduce repeated tool calls and unnecessary page snapshots, while using more detailed inspection when the target or result remains unclear.

中文简介正在准备中。当前显示英语简介。

  • Act on known buttons or fields with fewer browser calls
  • Locate a known target on a large page
  • Wait for navigation or downloads to finish
holaboss-ai/holaOS1.1万2026年8月21日 更新

Validate workflows and reproduce issues in an embedded browser. Distinguish application problems from incorrect targets, missing waits, or session state, then report the shortest reliable reproduction steps with only the evidence needed to support the finding.

中文简介正在准备中。当前显示英语简介。

  • Reproducing a browser workflow failure
  • Checking for regressions after a fix
  • Distinguishing timing issues from application failures
holaboss-ai/holaOS1.1万2026年8月21日 更新

Package workspace skills and their required service integrations into one named, installable capability. Create a manifest that references existing skills, install the capability, and report which integrations still need to be connected.

中文简介正在准备中。当前显示英语简介。

  • Bundle multiple skills for a shared outcome
  • Declare required external service integrations
  • Create a manifest that references existing skills
holaboss-ai/holaOS1.1万2026年8月21日 更新

Research a named competitor using public websites, social posts, and press coverage. Track launches, pricing, and messaging changes, then summarize three to five notable developments with brief takeaways in a weekly digest for the team.

中文简介正在准备中。当前显示英语简介。

  • Preparing weekly competitor updates
  • Tracking competitors' product launches
  • Reviewing pricing and messaging changes
holaboss-ai/holaOS1.1万2026年8月21日 更新

查看 holaboss-ai 的全部技能

报告此技能的问题