ok
This commit is contained in:
264
skills-cursor/canvas/sdk/canvas-tokens.d.ts
vendored
Normal file
264
skills-cursor/canvas/sdk/canvas-tokens.d.ts
vendored
Normal file
@@ -0,0 +1,264 @@
|
||||
/**
|
||||
* Design tokens for `cursor/canvas` (standalone; no UI framework dependency).
|
||||
*
|
||||
* Color values are aligned with the Cursor app dark theme (`packages/ui` `cursor-dark` sources).
|
||||
*/
|
||||
export declare const canvasPaletteDark: {
|
||||
readonly foreground: "#E4E4E4EB";
|
||||
readonly foregroundSecondary: "#E4E4E48D";
|
||||
readonly foregroundTertiary: "#E4E4E45E";
|
||||
readonly foregroundQuaternary: "#E4E4E442";
|
||||
readonly editor: "#181818";
|
||||
readonly chrome: "#141414";
|
||||
readonly sidebar: "#141414";
|
||||
readonly elevated: "#181818";
|
||||
readonly fillPrimary: "#E4E4E430";
|
||||
readonly fillSecondary: "#E4E4E41E";
|
||||
readonly fillTertiary: "#E4E4E411";
|
||||
readonly fillQuaternary: "#E4E4E40A";
|
||||
readonly strokePrimary: "#E4E4E433";
|
||||
readonly strokeSecondary: "#E4E4E41F";
|
||||
readonly strokeTertiary: "#E4E4E414";
|
||||
readonly accent: "#599CE7";
|
||||
readonly buttonBackground: "#599CE7";
|
||||
readonly buttonForeground: "#191c22";
|
||||
readonly buttonHoverBackground: "#6AABE9";
|
||||
readonly link: "#87c3ff";
|
||||
readonly diffInsertedLine: "#3FA26633";
|
||||
readonly diffRemovedLine: "#B8004933";
|
||||
readonly diffStripAdded: "#3FA2668F";
|
||||
readonly diffStripRemoved: "#FC6B838F";
|
||||
};
|
||||
/**
|
||||
* Light-mode palette derived from `packages/ui/src/tokens/themes/cursor-core/light.ts`.
|
||||
* Base color: #141414. Same percentages as dark (regular light has no overrides
|
||||
* in CURSOR_SEMANTIC_OVERRIDES — only high-contrast does).
|
||||
*/
|
||||
export declare const canvasPaletteLight: {
|
||||
readonly foreground: "#141414F0";
|
||||
readonly foregroundSecondary: "#141414BD";
|
||||
readonly foregroundTertiary: "#1414148A";
|
||||
readonly foregroundQuaternary: "#1414145C";
|
||||
readonly editor: "#FCFCFC";
|
||||
readonly chrome: "#F8F8F8";
|
||||
readonly sidebar: "#F3F3F3";
|
||||
readonly elevated: "#FCFCFC";
|
||||
readonly fillPrimary: "#14141433";
|
||||
readonly fillSecondary: "#14141424";
|
||||
readonly fillTertiary: "#14141414";
|
||||
readonly fillQuaternary: "#1414140F";
|
||||
readonly strokePrimary: "#14141433";
|
||||
readonly strokeSecondary: "#1414141F";
|
||||
readonly strokeTertiary: "#14141414";
|
||||
readonly accent: "#3685BF";
|
||||
readonly buttonBackground: "#3685BF";
|
||||
readonly buttonForeground: "#FCFCFC";
|
||||
readonly buttonHoverBackground: "#2E76AB";
|
||||
readonly link: "#3685BF";
|
||||
readonly diffInsertedLine: "#1F8A651F";
|
||||
readonly diffRemovedLine: "#CF2D5614";
|
||||
readonly diffStripAdded: "#1F8A65CC";
|
||||
readonly diffStripRemoved: "#CF2D56CC";
|
||||
};
|
||||
export interface CanvasPalette {
|
||||
readonly foreground: string;
|
||||
readonly foregroundSecondary: string;
|
||||
readonly foregroundTertiary: string;
|
||||
readonly foregroundQuaternary: string;
|
||||
readonly editor: string;
|
||||
readonly chrome: string;
|
||||
readonly sidebar: string;
|
||||
readonly elevated: string;
|
||||
readonly fillPrimary: string;
|
||||
readonly fillSecondary: string;
|
||||
readonly fillTertiary: string;
|
||||
readonly fillQuaternary: string;
|
||||
readonly strokePrimary: string;
|
||||
readonly strokeSecondary: string;
|
||||
readonly strokeTertiary: string;
|
||||
readonly accent: string;
|
||||
readonly buttonBackground: string;
|
||||
readonly buttonForeground: string;
|
||||
readonly buttonHoverBackground: string;
|
||||
readonly link: string;
|
||||
readonly diffInsertedLine: string;
|
||||
readonly diffRemovedLine: string;
|
||||
readonly diffStripAdded: string;
|
||||
readonly diffStripRemoved: string;
|
||||
}
|
||||
/**
|
||||
* Chart color palette — distilled from portal-website analytics charts.
|
||||
* 88% opacity (E0) softens vibrancy without dulling; palette maximizes
|
||||
* hue + luminosity spread for distinguishable multi-series charts.
|
||||
*/
|
||||
export declare const chartPalette: {
|
||||
readonly green: "#1F8A65E8";
|
||||
readonly darkGreen: "#0D855AE0";
|
||||
readonly lightGreen: "#52B896E0";
|
||||
readonly mintGreen: "#7DCAB0E0";
|
||||
readonly blue: "#2E79B5E0";
|
||||
readonly lightBlue: "#70B0D8E0";
|
||||
readonly indigo: "#5A6CC0F0";
|
||||
readonly lightIndigo: "#9AAADCE0";
|
||||
readonly purple: "#7B64B8F0";
|
||||
readonly lightPurple: "#AA98D8E0";
|
||||
readonly warmPink: "#C85898E0";
|
||||
readonly lightPink: "#E8A0C4E0";
|
||||
readonly brightOrange: "#F0A040E0";
|
||||
readonly deepOrange: "#C06028E0";
|
||||
readonly goldenYellow: "#E8C030E0";
|
||||
readonly darkAmber: "#C04848E0";
|
||||
readonly warmPeach: "#F0A088E0";
|
||||
readonly vibrantTeal: "#2A9A8AE0";
|
||||
readonly muted: "#8888A8E0";
|
||||
readonly neutralLine: "#888899D0";
|
||||
};
|
||||
/**
|
||||
* Shared category palette for canvas primitives that show categorical tints
|
||||
* (`Swatch`, `UsageBar` segments, etc.). Uses a coherent subset of
|
||||
* `chartPalette` so a category's color reads consistently across any
|
||||
* primitive that consumes it.
|
||||
*
|
||||
* The insertion order here is the canonical category order — primitives
|
||||
* that auto-assign colors (e.g. `UsageBar` segments without an explicit
|
||||
* `color`) cycle through these keys in order.
|
||||
*/
|
||||
export declare const colorPalette: {
|
||||
readonly gray: "#8888A8E0";
|
||||
readonly purple: "#7B64B8F0";
|
||||
readonly green: "#1F8A65E8";
|
||||
readonly yellow: "#E8C030E0";
|
||||
readonly pink: "#C85898E0";
|
||||
readonly blue: "#2E79B5E0";
|
||||
readonly orange: "#F0A040E0";
|
||||
};
|
||||
export type Color = keyof typeof colorPalette;
|
||||
/**
|
||||
* Auto-color rotation for `UsageBar` segments without an explicit `color`.
|
||||
* Decoupled from `colorPalette`'s declaration order so the palette can grow
|
||||
* or be reordered without changing how unspecified segments cycle.
|
||||
*
|
||||
* Matches the original `packages/ui` `ContextUsageTray` order so the same
|
||||
* segment index lands on the same hue as the source.
|
||||
*/
|
||||
export declare const usageColorSequence: readonly Color[];
|
||||
/**
|
||||
* Ordered array for automatic series coloring — alternates dark/light across
|
||||
* distinct hue families for maximum perceptual separation.
|
||||
*/
|
||||
export declare const chartColorSequence: readonly ["#1F8A65E8", "#70B0D8E0", "#5A6CC0F0", "#F0A040E0", "#C06028E0", "#E8C030E0", "#C85898E0", "#F0A088E0", "#7B64B8F0", "#7DCAB0E0", "#8888A8E0", "#2A9A8AE0"];
|
||||
declare function buildTokens(palette: CanvasPalette): {
|
||||
bg: {
|
||||
editor: string;
|
||||
chrome: string;
|
||||
elevated: string;
|
||||
};
|
||||
text: {
|
||||
primary: string;
|
||||
secondary: string;
|
||||
tertiary: string;
|
||||
quaternary: string;
|
||||
link: string;
|
||||
onAccent: string;
|
||||
};
|
||||
stroke: {
|
||||
primary: string;
|
||||
secondary: string;
|
||||
tertiary: string;
|
||||
};
|
||||
fill: {
|
||||
primary: string;
|
||||
secondary: string;
|
||||
tertiary: string;
|
||||
quaternary: string;
|
||||
};
|
||||
accent: {
|
||||
primary: string;
|
||||
control: string;
|
||||
controlHover: string;
|
||||
};
|
||||
diff: {
|
||||
insertedLine: string;
|
||||
removedLine: string;
|
||||
stripAdded: string;
|
||||
stripRemoved: string;
|
||||
};
|
||||
};
|
||||
/** Semantic colors for components (spacing and radius live in `theme.ts`). */
|
||||
export declare const canvasTokens: {
|
||||
bg: {
|
||||
editor: string;
|
||||
chrome: string;
|
||||
elevated: string;
|
||||
};
|
||||
text: {
|
||||
primary: string;
|
||||
secondary: string;
|
||||
tertiary: string;
|
||||
quaternary: string;
|
||||
link: string;
|
||||
onAccent: string;
|
||||
};
|
||||
stroke: {
|
||||
primary: string;
|
||||
secondary: string;
|
||||
tertiary: string;
|
||||
};
|
||||
fill: {
|
||||
primary: string;
|
||||
secondary: string;
|
||||
tertiary: string;
|
||||
quaternary: string;
|
||||
};
|
||||
accent: {
|
||||
primary: string;
|
||||
control: string;
|
||||
controlHover: string;
|
||||
};
|
||||
diff: {
|
||||
insertedLine: string;
|
||||
removedLine: string;
|
||||
stripAdded: string;
|
||||
stripRemoved: string;
|
||||
};
|
||||
};
|
||||
export declare const canvasTokensLight: {
|
||||
bg: {
|
||||
editor: string;
|
||||
chrome: string;
|
||||
elevated: string;
|
||||
};
|
||||
text: {
|
||||
primary: string;
|
||||
secondary: string;
|
||||
tertiary: string;
|
||||
quaternary: string;
|
||||
link: string;
|
||||
onAccent: string;
|
||||
};
|
||||
stroke: {
|
||||
primary: string;
|
||||
secondary: string;
|
||||
tertiary: string;
|
||||
};
|
||||
fill: {
|
||||
primary: string;
|
||||
secondary: string;
|
||||
tertiary: string;
|
||||
quaternary: string;
|
||||
};
|
||||
accent: {
|
||||
primary: string;
|
||||
control: string;
|
||||
controlHover: string;
|
||||
};
|
||||
diff: {
|
||||
insertedLine: string;
|
||||
removedLine: string;
|
||||
stripAdded: string;
|
||||
stripRemoved: string;
|
||||
};
|
||||
};
|
||||
export type CanvasTokens = ReturnType<typeof buildTokens>;
|
||||
export {};
|
||||
//# sourceMappingURL=canvas-tokens.d.ts.map
|
||||
200
skills-cursor/canvas/sdk/chart-primitives.d.ts
vendored
Normal file
200
skills-cursor/canvas/sdk/chart-primitives.d.ts
vendored
Normal file
@@ -0,0 +1,200 @@
|
||||
/**
|
||||
* Chart primitives for `cursor/canvas` — multi-series, stacked, and pie charts
|
||||
* rendered as pure inline SVG with zero external dependencies.
|
||||
*
|
||||
* Distilled from the portal-website Highcharts analytics charting layer.
|
||||
*/
|
||||
import type { CSSProperties, JSX } from "react";
|
||||
/**
|
||||
* Semantic tone for a chart series or slice. Mirrors the tone vocabulary
|
||||
* used by `Stat`, `Pill`, `Table`, and other SDK primitives so colors
|
||||
* match across a canvas — e.g. a `Stat tone="success"` and a
|
||||
* `ChartSeries tone="success"` render in the same green.
|
||||
*
|
||||
* Omit `tone` to let the chart auto-assign a distinct color from the
|
||||
* chart palette; supply `tone` only when the value carries semantic
|
||||
* meaning that should match other tonal elements on the page.
|
||||
*/
|
||||
export type ChartTone = "success" | "danger" | "warning" | "info" | "neutral";
|
||||
/** A single labeled value, used by `PieChart`. */
|
||||
export type ChartDataPoint = {
|
||||
label: string;
|
||||
/** Non-negative numeric value. */
|
||||
value: number;
|
||||
};
|
||||
/**
|
||||
* A named data series for `BarChart` and `LineChart`.
|
||||
* The `data` array aligns by index with the parent component's `categories`.
|
||||
* If `tone` is omitted, a color is auto-assigned from the chart palette.
|
||||
*/
|
||||
export type ChartSeries = {
|
||||
name: string;
|
||||
data: number[];
|
||||
tone?: ChartTone;
|
||||
};
|
||||
export type BarChartProps = {
|
||||
/** Category labels along the independent axis. */
|
||||
categories: string[];
|
||||
/** One or more data series. Values align by index with `categories`. */
|
||||
series: ChartSeries[];
|
||||
height?: number;
|
||||
/** Stack series on top of each other instead of grouping side-by-side. */
|
||||
stacked?: boolean;
|
||||
/** Render horizontal bars instead of vertical columns. */
|
||||
horizontal?: boolean;
|
||||
/** Show as 100% stacked (implies `stacked`). */
|
||||
normalized?: boolean;
|
||||
/** Suffix for y-axis tick labels (e.g. "%"). */
|
||||
valueSuffix?: string;
|
||||
style?: CSSProperties;
|
||||
};
|
||||
export type LineChartProps = {
|
||||
categories: string[];
|
||||
series: ChartSeries[];
|
||||
height?: number;
|
||||
/** Fill the area under each line with a soft tint. */
|
||||
fill?: boolean;
|
||||
valueSuffix?: string;
|
||||
style?: CSSProperties;
|
||||
};
|
||||
export type PieChartProps = {
|
||||
data: Array<ChartDataPoint & {
|
||||
tone?: ChartTone;
|
||||
}>;
|
||||
size?: number;
|
||||
donut?: boolean;
|
||||
style?: CSSProperties;
|
||||
};
|
||||
/**
|
||||
* Multi-series bar/column chart with optional stacking and normalization.
|
||||
* Distilled from the portal-website Highcharts analytics charts.
|
||||
*
|
||||
* Pass `categories` for x-axis labels and one or more `series` whose `data`
|
||||
* arrays align by index. With a single series you get simple bars; with
|
||||
* multiple series the default is grouped (side-by-side) — set `stacked` for
|
||||
* stacked columns or `normalized` for 100%-stacked share-mode.
|
||||
*
|
||||
* Colors are auto-assigned from the chart palette. With a **single series**,
|
||||
* each bar gets a different color by category (so a chart of 5 categories
|
||||
* shows 5 colors out of the box). With **multiple series**, each series gets
|
||||
* its own color. A legend appears when there are 2+ series.
|
||||
*
|
||||
* For semantic coloring, pass `tone` on a series — it maps to the same
|
||||
* palette entries used by `Stat`, `Pill`, and `Table` so your chart matches
|
||||
* tonal elements elsewhere on the page.
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* // Simple single-series
|
||||
* <BarChart
|
||||
* categories={["Mon", "Tue", "Wed"]}
|
||||
* series={[{ name: "Requests", data: [120, 90, 150] }]}
|
||||
* />
|
||||
*
|
||||
* // Stacked multi-series (like portal AI commit chart)
|
||||
* <BarChart
|
||||
* categories={["Mon", "Tue", "Wed"]}
|
||||
* series={[
|
||||
* { name: "IDE", data: [120, 90, 150] },
|
||||
* { name: "CLI", data: [30, 40, 25] },
|
||||
* { name: "Cloud", data: [50, 60, 70] },
|
||||
* ]}
|
||||
* stacked
|
||||
* />
|
||||
*
|
||||
* // Semantic tones — "accepted" renders in the same green as
|
||||
* // <Stat tone="success"> elsewhere on the page.
|
||||
* <BarChart
|
||||
* categories={["Mon", "Tue", "Wed"]}
|
||||
* series={[
|
||||
* { name: "Accepted", data: [70, 80, 60], tone: "success" },
|
||||
* { name: "Rejected", data: [30, 20, 40], tone: "danger" },
|
||||
* ]}
|
||||
* stacked
|
||||
* />
|
||||
* ```
|
||||
*/
|
||||
export declare function BarChart({ categories, series, height, stacked, horizontal, normalized, valueSuffix, style }: BarChartProps): JSX.Element;
|
||||
/**
|
||||
* Multi-series line chart with optional area fill. Distilled from the
|
||||
* portal-website Highcharts analytics charts.
|
||||
*
|
||||
* Each series draws a polyline with dot markers at each data point.
|
||||
* Set `fill` to shade the area under every line. Hover over any category
|
||||
* column to see a tooltip with all series values at that point.
|
||||
*
|
||||
* This is **not** a time-series component — it does not parse dates.
|
||||
* Pass pre-formatted date strings as `categories` if plotting over time.
|
||||
*
|
||||
* Colors are auto-assigned from the chart palette. For semantic coloring,
|
||||
* pass `tone` on a series — it maps to the same palette entries used by
|
||||
* `Stat`, `Pill`, and `Table`.
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* // Single line
|
||||
* <LineChart
|
||||
* categories={["Jan", "Feb", "Mar", "Apr"]}
|
||||
* series={[{ name: "Revenue", data: [100, 140, 120, 180] }]}
|
||||
* />
|
||||
*
|
||||
* // Multi-series with area fill
|
||||
* <LineChart
|
||||
* categories={["Jan", "Feb", "Mar", "Apr"]}
|
||||
* series={[
|
||||
* { name: "Accepted", data: [50, 70, 60, 90] },
|
||||
* { name: "Suggested", data: [120, 140, 130, 160] },
|
||||
* ]}
|
||||
* fill
|
||||
* />
|
||||
*
|
||||
* // Semantic tones — "errors" renders in the same red as a
|
||||
* // <Pill tone="danger"> elsewhere on the page.
|
||||
* <LineChart
|
||||
* categories={["00:00", "06:00", "12:00", "18:00"]}
|
||||
* series={[
|
||||
* { name: "p95 latency", data: [80, 95, 110, 90], tone: "info" },
|
||||
* { name: "errors", data: [2, 4, 9, 3], tone: "danger" },
|
||||
* ]}
|
||||
* />
|
||||
* ```
|
||||
*/
|
||||
export declare function LineChart({ categories, series, height, fill, valueSuffix, style }: LineChartProps): JSX.Element;
|
||||
/**
|
||||
* Pie (or donut) chart with hover highlighting. Distilled from the
|
||||
* portal-website Highcharts analytics charts.
|
||||
*
|
||||
* Unlike `BarChart` and `LineChart`, `PieChart` takes a flat `data` array of
|
||||
* `{ label, value }` points — each slice is its own category. Colors are
|
||||
* auto-assigned from the chart palette; pass `tone` on a point to give a
|
||||
* slice a semantic color that matches other tonal elements on the page.
|
||||
*
|
||||
* Hovering a slice expands it outward and dims the others; hovering a legend
|
||||
* item does the same. A tooltip with value and percentage appears below the
|
||||
* chart. Set `donut` for a hollow center.
|
||||
*
|
||||
* **Do not** use for bar-style comparisons — use `BarChart` instead.
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* // Basic pie
|
||||
* <PieChart
|
||||
* data={[
|
||||
* { label: "IDE", value: 120 },
|
||||
* { label: "CLI", value: 30 },
|
||||
* { label: "Cloud", value: 50 },
|
||||
* ]}
|
||||
* />
|
||||
*
|
||||
* // Donut with semantic tones
|
||||
* <PieChart
|
||||
* data={[
|
||||
* { label: "Passing", value: 70, tone: "success" },
|
||||
* { label: "Failing", value: 30, tone: "danger" },
|
||||
* ]}
|
||||
* donut
|
||||
* />
|
||||
* ```
|
||||
*/
|
||||
export declare function PieChart({ data, size, donut, style }: PieChartProps): JSX.Element;
|
||||
//# sourceMappingURL=chart-primitives.d.ts.map
|
||||
65
skills-cursor/canvas/sdk/collapsible-section.d.ts
vendored
Normal file
65
skills-cursor/canvas/sdk/collapsible-section.d.ts
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* Borderless disclosure row — chevron + structured header (title, optional
|
||||
* leading slot, count, trailing slot) with a body that toggles open. Distilled
|
||||
* from baby-glass `ContextTreeRow`'s lightweight list-row chrome (no card
|
||||
* border, no background fill).
|
||||
*
|
||||
* For a bordered surface that collapses, use `<Card collapsible>` instead.
|
||||
*/
|
||||
import { type CSSProperties, type JSX, type ReactNode } from "react";
|
||||
export type CollapsibleSectionProps = {
|
||||
/** Plain-text title rendered next to the disclosure chevron. */
|
||||
title: string;
|
||||
/**
|
||||
* Optional leading visual (e.g. `<Swatch>`) shown between the chevron and
|
||||
* the title.
|
||||
*/
|
||||
leading?: ReactNode;
|
||||
/**
|
||||
* Optional small count rendered after the title (e.g. number of children).
|
||||
*/
|
||||
count?: number;
|
||||
/**
|
||||
* Optional trailing node, right-aligned (e.g. token readout, badge, button).
|
||||
* Rendered with `t.text.tertiary` color hint via the wrapper; the slot can
|
||||
* override.
|
||||
*/
|
||||
trailing?: ReactNode;
|
||||
/** Body shown when expanded. */
|
||||
children?: ReactNode;
|
||||
style?: CSSProperties;
|
||||
};
|
||||
/**
|
||||
* Borderless collapsible row with a structured header. Always starts closed
|
||||
* (uncontrolled, no `defaultOpen`).
|
||||
*
|
||||
* Compose with `<Swatch>` in the `leading` slot for a colored category icon,
|
||||
* and put a token readout / pill / button in `trailing`. Body content is
|
||||
* indented under the row so nested `CollapsibleSection`s read as a tree.
|
||||
*
|
||||
* For a bordered, card-shaped collapsible surface, use `<Card collapsible>`
|
||||
* instead — `CollapsibleSection` has no border or background and is meant to
|
||||
* sit in a list of similar rows.
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* // Basic
|
||||
* <CollapsibleSection title="Conversation">
|
||||
* <Text>Messages go here.</Text>
|
||||
* </CollapsibleSection>
|
||||
*
|
||||
* // With a colored category swatch + count + trailing token readout
|
||||
* <CollapsibleSection
|
||||
* title="Tools"
|
||||
* count={4}
|
||||
* leading={<Swatch color="purple" />}
|
||||
* trailing={<Text size="small" tone="tertiary">12.3k</Text>}
|
||||
* >
|
||||
* <CollapsibleSection title="Grep">
|
||||
* <Text>Search results.</Text>
|
||||
* </CollapsibleSection>
|
||||
* </CollapsibleSection>
|
||||
* ```
|
||||
*/
|
||||
export declare function CollapsibleSection({ title, leading, count, trailing, children, style }: CollapsibleSectionProps): JSX.Element;
|
||||
//# sourceMappingURL=collapsible-section.d.ts.map
|
||||
102
skills-cursor/canvas/sdk/dag-layout.d.ts
vendored
Normal file
102
skills-cursor/canvas/sdk/dag-layout.d.ts
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
/**
|
||||
* Pure layout math for directed acyclic graphs. Returns positioned node
|
||||
* coordinates, edge anchor points, rank bounding boxes, and back-edge flags.
|
||||
* Rendering is the caller's responsibility.
|
||||
*
|
||||
* Handles cycles gracefully: back-edges are detected via DFS, excluded from
|
||||
* ranking, and flagged in the output so the caller can render them differently
|
||||
* (e.g. dashed arcs).
|
||||
*/
|
||||
export type DAGLayoutOptions = {
|
||||
/** Nodes to lay out. Only `id` is required. */
|
||||
nodes: Array<{
|
||||
id: string;
|
||||
}>;
|
||||
/** Directed edges. */
|
||||
edges: Array<{
|
||||
from: string;
|
||||
to: string;
|
||||
}>;
|
||||
/** Flow direction. Default `"vertical"` (top-to-bottom). */
|
||||
direction?: "vertical" | "horizontal";
|
||||
/** Node box width in px. Default 160. */
|
||||
nodeWidth?: number;
|
||||
/** Node box height in px. Default 40. */
|
||||
nodeHeight?: number;
|
||||
/** Gap between ranks (layers) in px. Default 64. */
|
||||
rankGap?: number;
|
||||
/** Gap between sibling nodes in the same rank in px. Default 48. */
|
||||
nodeGap?: number;
|
||||
/** Padding around the bounding box in px. Default 24. */
|
||||
padding?: number;
|
||||
};
|
||||
export type DAGLayoutNode = {
|
||||
id: string;
|
||||
/** Left edge of the node box. */
|
||||
x: number;
|
||||
/** Top edge of the node box. */
|
||||
y: number;
|
||||
/** Layer index (0 = root). */
|
||||
rank: number;
|
||||
/** Position within the rank (0-indexed). */
|
||||
order: number;
|
||||
};
|
||||
export type DAGLayoutEdge = {
|
||||
from: string;
|
||||
to: string;
|
||||
/** Suggested source anchor point (center of the outgoing side). */
|
||||
sourceX: number;
|
||||
sourceY: number;
|
||||
/** Suggested target anchor point (center of the incoming side). */
|
||||
targetX: number;
|
||||
targetY: number;
|
||||
/** True when this edge was identified as a back-edge (part of a cycle). */
|
||||
isBackEdge: boolean;
|
||||
};
|
||||
export type DAGLayoutRank = {
|
||||
/** Rank index (0 = root). */
|
||||
rank: number;
|
||||
/** Left edge of the rank bounding box. */
|
||||
x: number;
|
||||
/** Top edge of the rank bounding box. */
|
||||
y: number;
|
||||
/** Width of the rank bounding box. */
|
||||
width: number;
|
||||
/** Height of the rank bounding box. */
|
||||
height: number;
|
||||
/** Node ids in this rank, in order. */
|
||||
nodeIds: string[];
|
||||
};
|
||||
export type DAGLayoutResult = {
|
||||
nodes: DAGLayoutNode[];
|
||||
edges: DAGLayoutEdge[];
|
||||
/** Bounding box per rank — useful for drawing layer bands. */
|
||||
ranks: DAGLayoutRank[];
|
||||
/** The direction used for this layout. */
|
||||
direction: "vertical" | "horizontal";
|
||||
/** Total width of the bounding box. */
|
||||
width: number;
|
||||
/** Total height of the bounding box. */
|
||||
height: number;
|
||||
};
|
||||
/**
|
||||
* Compute a hierarchical layout for a directed graph.
|
||||
*
|
||||
* Returns node positions, edge anchor points, rank bounding boxes, and
|
||||
* back-edge flags. The caller handles all rendering.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* const layout = computeDAGLayout({
|
||||
* nodes: [{ id: "a" }, { id: "b" }, { id: "c" }],
|
||||
* edges: [{ from: "a", to: "b" }, { from: "b", to: "c" }],
|
||||
* });
|
||||
*
|
||||
* // layout.nodes[i].x / .y → position your own SVG/HTML elements
|
||||
* // layout.edges[i].sourceX/Y, targetX/Y → draw lines between them
|
||||
* // layout.edges[i].isBackEdge → style cycle edges differently
|
||||
* // layout.ranks[i] → draw layer bands behind each rank
|
||||
* ```
|
||||
*/
|
||||
export declare function computeDAGLayout(options: DAGLayoutOptions): DAGLayoutResult;
|
||||
//# sourceMappingURL=dag-layout.d.ts.map
|
||||
130
skills-cursor/canvas/sdk/diff-view.d.ts
vendored
Normal file
130
skills-cursor/canvas/sdk/diff-view.d.ts
vendored
Normal file
@@ -0,0 +1,130 @@
|
||||
/**
|
||||
* Low-level diff primitives for the canvas SDK.
|
||||
*
|
||||
* The canvas diff surface is intentionally minimal — two components that
|
||||
* compose with the generic `Card` / `CardHeader` / `CardBody` / `Pill` /
|
||||
* `Text` primitives to build any diff layout an agent can imagine:
|
||||
*
|
||||
* - `DiffView` — a monospaced, syntax-highlighted unified diff renderer.
|
||||
* Drops into any container (a `Card`, a table cell, a bare layout,
|
||||
* nothing at all). No card chrome, no header, no path display. Pass
|
||||
* `path` to auto-detect the language for highlighting, or `language`
|
||||
* to override.
|
||||
*
|
||||
* - `DiffStats` — the canonical `+N` green / `-N` red glyph pair. Use
|
||||
* it anywhere a small "added/deleted" summary makes sense — in a
|
||||
* `CardHeader`'s `trailing` slot, next to a filename in a file tree,
|
||||
* inside a status row, etc.
|
||||
*
|
||||
* For file-level metadata the preferred composition is to use the
|
||||
* generic `Card` family:
|
||||
*
|
||||
* ```tsx
|
||||
* <Card collapsible>
|
||||
* <CardHeader trailing={<DiffStats additions={5} deletions={2} />}>
|
||||
* src/utils.ts
|
||||
* </CardHeader>
|
||||
* <CardBody style={{ padding: 0 }}>
|
||||
* <DiffView path="src/utils.ts" lines={lines} />
|
||||
* </CardBody>
|
||||
* </Card>
|
||||
* ```
|
||||
*/
|
||||
import type { CSSProperties, JSX } from "react";
|
||||
export type DiffStatsProps = {
|
||||
additions?: number;
|
||||
deletions?: number;
|
||||
style?: CSSProperties;
|
||||
};
|
||||
/**
|
||||
* Inline `+N` / `-N` glyph pair. Green additions, red deletions, with
|
||||
* tabular numerals so columns of stats line up. Renders nothing when
|
||||
* both counts are zero.
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* <CardHeader trailing={<DiffStats additions={12} deletions={3} />}>
|
||||
* src/utils.ts
|
||||
* </CardHeader>
|
||||
*
|
||||
* <Row gap={8}>
|
||||
* <Text>Refactor pass</Text>
|
||||
* <DiffStats additions={42} deletions={17} />
|
||||
* </Row>
|
||||
* ```
|
||||
*/
|
||||
export declare function DiffStats({ additions, deletions, style }: DiffStatsProps): JSX.Element | null;
|
||||
export type DiffLineType = "added" | "removed" | "unchanged";
|
||||
export type DiffLineData = {
|
||||
type: DiffLineType;
|
||||
content: string;
|
||||
lineNumber?: number;
|
||||
};
|
||||
export type DiffViewProps = {
|
||||
lines: DiffLineData[];
|
||||
/**
|
||||
* File path used to infer the syntax-highlighting language from the
|
||||
* extension (e.g. `"src/utils.ts"` → `typescript`). The most ergonomic
|
||||
* way to enable highlighting — pass the same path you show in the
|
||||
* enclosing card header. Unknown extensions silently render as plain
|
||||
* text.
|
||||
*
|
||||
* If both `path` and `language` are provided, `language` wins.
|
||||
*/
|
||||
path?: string;
|
||||
/**
|
||||
* Explicit language override for syntax highlighting (e.g.
|
||||
* `"typescript"`, `"python"`, `"tsx"`). Use this when no file path is
|
||||
* available, when the path's extension is misleading, or when the
|
||||
* content is a snippet rather than a real file. Accepts common
|
||||
* aliases (`ts`, `py`, `rs`, `md`, etc.). Unknown languages silently
|
||||
* fall back to plain text.
|
||||
*
|
||||
* Highlighting is applied per line, so multi-line constructs (block
|
||||
* comments, template literals) may not colorize perfectly across line
|
||||
* boundaries. For typical diff-sized inputs this is fine.
|
||||
*/
|
||||
language?: string;
|
||||
/** Show line numbers in the gutter. Default `true`. */
|
||||
showLineNumbers?: boolean;
|
||||
/** Color line numbers green/red for added/removed lines. Default `true`. */
|
||||
coloredLineNumbers?: boolean;
|
||||
/** Show a 3px accent strip on the left edge for changed lines. Default `true`. */
|
||||
showAccentStrip?: boolean;
|
||||
style?: CSSProperties;
|
||||
};
|
||||
/**
|
||||
* Unified diff body renderer with monospaced type, colored line
|
||||
* backgrounds, line-number gutter, accent strip, and optional Shiki
|
||||
* syntax highlighting.
|
||||
*
|
||||
* `DiffView` does not provide any surrounding chrome — place it inside
|
||||
* a `Card` + `CardBody` (with `padding: 0`) when you want the standard
|
||||
* bordered "file diff" look, or drop it anywhere else if you want the
|
||||
* bare renderer.
|
||||
*
|
||||
* Pass `path` to enable syntax highlighting from the file extension.
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* <Card>
|
||||
* <CardHeader trailing={<DiffStats additions={2} deletions={1} />}>
|
||||
* src/utils.ts
|
||||
* </CardHeader>
|
||||
* <CardBody style={{ padding: 0 }}>
|
||||
* <DiffView
|
||||
* path="src/utils.ts"
|
||||
* lines={[
|
||||
* { type: "unchanged", content: "export function add(a: number, b: number): number {", lineNumber: 1 },
|
||||
* { type: "removed", content: " return a + b;", lineNumber: 2 },
|
||||
* { type: "added", content: " const result = a + b;", lineNumber: 2 },
|
||||
* { type: "added", content: " return result;", lineNumber: 3 },
|
||||
* { type: "unchanged", content: "}", lineNumber: 4 },
|
||||
* ]}
|
||||
* />
|
||||
* </CardBody>
|
||||
* </Card>
|
||||
* ```
|
||||
*/
|
||||
export declare function DiffView({ lines, path, language, showLineNumbers, coloredLineNumbers, showAccentStrip, style }: DiffViewProps): JSX.Element;
|
||||
//# sourceMappingURL=diff-view.d.ts.map
|
||||
194
skills-cursor/canvas/sdk/form-primitives.d.ts
vendored
Normal file
194
skills-cursor/canvas/sdk/form-primitives.d.ts
vendored
Normal file
@@ -0,0 +1,194 @@
|
||||
/**
|
||||
* Form primitives for `cursor/canvas`. Provides themed, controlled form controls
|
||||
* for interactive canvas apps with persistent state. All `onChange` callbacks
|
||||
* receive the **value directly** (not a DOM event), so they pair naturally
|
||||
* with `useCanvasState`:
|
||||
*
|
||||
* ```tsx
|
||||
* const [name, setName] = useCanvasState("name", "");
|
||||
* <TextInput value={name} onChange={setName} placeholder="Enter name…" />
|
||||
* ```
|
||||
*/
|
||||
import { type CSSProperties, type JSX, type ReactNode } from "react";
|
||||
export type TextInputProps = {
|
||||
value?: string;
|
||||
/** Called with the new string value on every keystroke. */
|
||||
onChange?: (value: string) => void;
|
||||
placeholder?: string;
|
||||
disabled?: boolean;
|
||||
type?: "text" | "email" | "password" | "number" | "url" | "search";
|
||||
style?: CSSProperties;
|
||||
};
|
||||
/**
|
||||
* Single-line text input (28px height). Use for names, titles, search
|
||||
* queries, and short text fields.
|
||||
*
|
||||
* `onChange` receives the **string value**, not a DOM event — this pairs
|
||||
* directly with `useCanvasState` setters.
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* const [name, setName] = useCanvasState("name", "");
|
||||
*
|
||||
* <TextInput value={name} onChange={setName} placeholder="Task title…" />
|
||||
* ```
|
||||
*/
|
||||
export declare function TextInput({ value, onChange, placeholder, disabled, type, style }: TextInputProps): JSX.Element;
|
||||
export type TextAreaProps = {
|
||||
value?: string;
|
||||
/** Called with the new string value on every keystroke. */
|
||||
onChange?: (value: string) => void;
|
||||
placeholder?: string;
|
||||
disabled?: boolean;
|
||||
/** Minimum visible rows. Defaults to 3. */
|
||||
rows?: number;
|
||||
style?: CSSProperties;
|
||||
};
|
||||
/**
|
||||
* Multi-line text input that auto-resizes to fit its content.
|
||||
* Use for notes, descriptions, comments, and multi-line text fields.
|
||||
*
|
||||
* The textarea grows as the user types. Set `rows` for the minimum visible
|
||||
* height (defaults to 3). Override with `style={{ height: "100px" }}` for a
|
||||
* fixed size.
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* const [notes, setNotes] = useCanvasState("notes", "");
|
||||
*
|
||||
* <TextArea value={notes} onChange={setNotes} placeholder="Add notes…" rows={4} />
|
||||
* ```
|
||||
*/
|
||||
export declare function TextArea({ value, onChange, placeholder, disabled, rows, style }: TextAreaProps): JSX.Element;
|
||||
export type CheckboxProps = {
|
||||
checked?: boolean;
|
||||
/** Called with the new boolean value when toggled. */
|
||||
onChange?: (checked: boolean) => void;
|
||||
disabled?: boolean;
|
||||
/** Optional label rendered beside the checkbox. Clicking the label toggles the checkbox. */
|
||||
label?: ReactNode;
|
||||
style?: CSSProperties;
|
||||
};
|
||||
/**
|
||||
* Checkbox with optional label (accent blue when checked).
|
||||
*
|
||||
* Pass `label` to render a clickable text label beside the checkbox. Without a
|
||||
* label, provide `title` or wrap in your own `<label>` for accessibility.
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* const [agreed, setAgreed] = useCanvasState("agreed", false);
|
||||
*
|
||||
* <Checkbox checked={agreed} onChange={setAgreed} label="I agree to the terms" />
|
||||
* ```
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* // Checkbox in a list — no label, parent handles layout
|
||||
* <Checkbox checked={item.done} onChange={(v) => toggleItem(item.id, v)} />
|
||||
* ```
|
||||
*/
|
||||
export declare function Checkbox({ checked, onChange, disabled, label, style }: CheckboxProps): JSX.Element;
|
||||
export type ToggleProps = {
|
||||
checked?: boolean;
|
||||
/** Called with the new boolean value when toggled. */
|
||||
onChange?: (checked: boolean) => void;
|
||||
disabled?: boolean;
|
||||
/** `sm` = 16px track, `md` = 20px track (default `sm`). */
|
||||
size?: "sm" | "md";
|
||||
style?: CSSProperties;
|
||||
};
|
||||
/**
|
||||
* Boolean toggle switch. Uses the accent color for the "on" state and a
|
||||
* neutral fill for "off".
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* const [enabled, setEnabled] = useCanvasState("enabled", false);
|
||||
*
|
||||
* <Row gap={8} align="center">
|
||||
* <Text>Notifications</Text>
|
||||
* <Spacer />
|
||||
* <Toggle checked={enabled} onChange={setEnabled} />
|
||||
* </Row>
|
||||
* ```
|
||||
*/
|
||||
export declare function Toggle({ checked, onChange, disabled, size, style }: ToggleProps): JSX.Element;
|
||||
export type SelectOption = {
|
||||
value: string;
|
||||
label: string;
|
||||
disabled?: boolean;
|
||||
};
|
||||
export type SelectProps = {
|
||||
value?: string;
|
||||
/** Called with the new selected value. */
|
||||
onChange?: (value: string) => void;
|
||||
/** List of options. Each must have a unique `value`. */
|
||||
options: SelectOption[];
|
||||
/** Placeholder shown when no value is selected. */
|
||||
placeholder?: string;
|
||||
disabled?: boolean;
|
||||
style?: CSSProperties;
|
||||
};
|
||||
/**
|
||||
* Dropdown select (native `<select>` with themed styling).
|
||||
*
|
||||
* Uses a native `<select>` under the hood for reliable keyboard, screen-reader,
|
||||
* and mobile support. The dropdown list uses OS-native styling.
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* const [priority, setPriority] = useCanvasState("priority", "medium");
|
||||
*
|
||||
* <Select
|
||||
* value={priority}
|
||||
* onChange={setPriority}
|
||||
* options={[
|
||||
* { value: "low", label: "Low" },
|
||||
* { value: "medium", label: "Medium" },
|
||||
* { value: "high", label: "High" },
|
||||
* ]}
|
||||
* />
|
||||
* ```
|
||||
*/
|
||||
export declare function Select({ value, onChange, options, placeholder, disabled, style }: SelectProps): JSX.Element;
|
||||
export type IconButtonProps = {
|
||||
/** Icon content: an SVG element, emoji, or unicode character. */
|
||||
children: ReactNode;
|
||||
onClick?: () => void;
|
||||
disabled?: boolean;
|
||||
/** Tooltip text. Always provide for accessibility since there is no text label. */
|
||||
title?: string;
|
||||
/**
|
||||
* `"default"` is transparent until hovered; `"circle"` has a permanent
|
||||
* background fill.
|
||||
*/
|
||||
variant?: "default" | "circle";
|
||||
/** `sm` = 16px, `md` = 20px (default `md`). */
|
||||
size?: "sm" | "md";
|
||||
style?: CSSProperties;
|
||||
};
|
||||
/**
|
||||
* Compact icon-only button for inline actions on list items (delete, edit,
|
||||
* expand, etc.). Accepts **any** `children` as the icon — use an inline SVG,
|
||||
* an emoji, or a unicode character.
|
||||
*
|
||||
* Always provide `title` for accessibility (screen-reader label + tooltip).
|
||||
*
|
||||
* Canvas has no icon font, so pass icon content directly.
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* // Delete button on a card
|
||||
* <IconButton title="Delete" onClick={() => remove(id)}>✕</IconButton>
|
||||
*
|
||||
* // Edit button with an SVG icon
|
||||
* <IconButton title="Edit" variant="circle" size="sm" onClick={edit}>
|
||||
* <svg width={12} height={12} viewBox="0 0 12 12" fill="none">
|
||||
* <path d="M8.5 1.5l2 2L4 10H2V8z" stroke="currentColor" strokeWidth={1.2} />
|
||||
* </svg>
|
||||
* </IconButton>
|
||||
* ```
|
||||
*/
|
||||
export declare function IconButton({ children, onClick, disabled, title, variant, size, style }: IconButtonProps): JSX.Element;
|
||||
//# sourceMappingURL=form-primitives.d.ts.map
|
||||
141
skills-cursor/canvas/sdk/hooks.d.ts
vendored
Normal file
141
skills-cursor/canvas/sdk/hooks.d.ts
vendored
Normal file
@@ -0,0 +1,141 @@
|
||||
import type { CanvasPalette, CanvasTokens } from "./canvas-tokens.js";
|
||||
import { type CanvasAction } from "./internal/canvas-action-dispatch.js";
|
||||
/**
|
||||
* Host theme for the current canvas. Semantic color groups (`text`, `bg`,
|
||||
* `fill`, `stroke`, `accent`, `diff`) live at the top level for ergonomic
|
||||
* inline-style access; `tokens` is also present as a self-reference for
|
||||
* callers that prefer a namespaced form.
|
||||
*/
|
||||
export interface CanvasHostTheme extends CanvasTokens {
|
||||
readonly kind: string;
|
||||
readonly tokens: CanvasTokens;
|
||||
readonly palette: CanvasPalette;
|
||||
}
|
||||
/**
|
||||
* Returns the current host theme. Falls back to dark mode when no host
|
||||
* state is available.
|
||||
*
|
||||
* Semantic color groups are available directly on the returned object —
|
||||
* `accent`, `text`, `bg`, `fill`, `stroke`, `diff` — as well as `kind`
|
||||
* (`"dark"` | `"light"` | …) and `palette` (the flat color palette).
|
||||
*
|
||||
* Call `useHostTheme()` inside each component that needs theme access —
|
||||
* the returned object is scoped to that component, not shared across
|
||||
* function boundaries.
|
||||
*
|
||||
* Stable paths for `style={{ ... }}` usage:
|
||||
* - `text.primary / secondary / tertiary / quaternary` — text hierarchy
|
||||
* - `bg.editor / chrome / elevated` — surface backgrounds
|
||||
* - `fill.primary / secondary / tertiary / quaternary` — tinted fills
|
||||
* - `stroke.primary / secondary / tertiary` — borders and dividers
|
||||
* - `accent.primary / control` — accent blue and button background
|
||||
* - `text.link` — link color
|
||||
* - `text.onAccent` — text on accent-colored surfaces
|
||||
*
|
||||
* Prefer built-in components (`Card`, `Button`, `Text`, etc.) over raw
|
||||
* token usage. Reach for tokens only when no component covers the case,
|
||||
* and stick to flat solid colors — no gradients, no box-shadows.
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* function Overview() {
|
||||
* const theme = useHostTheme();
|
||||
* return (
|
||||
* <div style={{ background: theme.fill.tertiary, color: theme.text.secondary, padding: 8 }}>
|
||||
* <span style={{ color: theme.accent.primary }}>Accent text</span>
|
||||
* </div>
|
||||
* );
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
export declare function useHostTheme(): CanvasHostTheme;
|
||||
/**
|
||||
* Setter for `useCanvasState`. Accepts either a new value or an updater
|
||||
* function that receives the previous value.
|
||||
*/
|
||||
export type SetCanvasState<T> = (action: T | ((prev: T) => T)) => void;
|
||||
/**
|
||||
* Persistent state hook for canvas applications. Works like `React.useState`
|
||||
* but the value survives rebuilds, reloads, and IDE restarts — it is stored
|
||||
* in a `.canvas.data.json` sidecar file next to the canvas source.
|
||||
*
|
||||
* Each key is a unique string chosen by the canvas author. Keys are stable
|
||||
* regardless of hook call order or component tree structure.
|
||||
*
|
||||
* @param key - Unique string identifier for this piece of state.
|
||||
* @param defaultValue - Value returned when no persisted value exists for `key`.
|
||||
* @returns A `[value, setValue]` tuple, same shape as `React.useState`.
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* function Counter() {
|
||||
* const [count, setCount] = useCanvasState("count", 0);
|
||||
* return <Button onClick={() => setCount(c => c + 1)}>{count}</Button>;
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* interface Column { id: string; title: string; cardIds: string[] }
|
||||
* function KanbanBoard() {
|
||||
* const [columns, setColumns] = useCanvasState<Column[]>("columns", [
|
||||
* { id: "todo", title: "To Do", cardIds: [] },
|
||||
* { id: "doing", title: "In Progress", cardIds: [] },
|
||||
* { id: "done", title: "Done", cardIds: [] },
|
||||
* ]);
|
||||
* // ...
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
export declare function useCanvasState<T>(key: string, defaultValue: T): [T, SetCanvasState<T>];
|
||||
export type { CanvasAction };
|
||||
/**
|
||||
* Returns a stable `dispatch` function for triggering IDE actions from
|
||||
* canvas buttons. Actions are fire-and-forget — the canvas does not
|
||||
* receive a response.
|
||||
*
|
||||
* ## Available actions
|
||||
*
|
||||
* **`openAgent`** — Navigate the IDE to an agent conversation.
|
||||
* `agentId` is the conversation UUID (the filename stem from the
|
||||
* `agent-transcripts/` directory). Works for both local and
|
||||
* cloud/background agents in Glass and classic IDE modes.
|
||||
*
|
||||
* **`newComposerChat`** — Open a new local agent chat with the
|
||||
* dispatching canvas file as an @mention. Optional `userPrompt` is
|
||||
* appended after the mention. The canvas file is resolved from the
|
||||
* action route's `canvasId`; do not pass the path from canvas UI.
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* function AgentLink({ agentId, title }: { agentId: string; title: string }) {
|
||||
* const dispatch = useCanvasAction();
|
||||
* return (
|
||||
* <Button onClick={() => dispatch({ type: "openAgent", agentId })}>
|
||||
* {title}
|
||||
* </Button>
|
||||
* );
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* function AskAboutCanvas() {
|
||||
* const dispatch = useCanvasAction();
|
||||
* return (
|
||||
* <Button
|
||||
* onClick={() =>
|
||||
* dispatch({
|
||||
* type: "newComposerChat",
|
||||
* userPrompt: "please explain what is using the most context",
|
||||
* })
|
||||
* }
|
||||
* >
|
||||
* Ask in chat
|
||||
* </Button>
|
||||
* );
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
export declare function useCanvasAction(): (action: CanvasAction) => void;
|
||||
//# sourceMappingURL=hooks.d.ts.map
|
||||
59
skills-cursor/canvas/sdk/index.d.ts
vendored
Normal file
59
skills-cursor/canvas/sdk/index.d.ts
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* Public API for authoring `.canvas.tsx` files via `cursor/canvas`.
|
||||
*
|
||||
* Be creative with layout — use Grid, Row, cards, charts, tables, and raw SVG
|
||||
* in whatever combination serves the content. Read the canvas skill for full
|
||||
* design guidance. Key constraints:
|
||||
*
|
||||
* - Colors from `useHostTheme()` tokens. No hardcoded hex.
|
||||
* - No gradients, no box-shadows, no emojis as decoration.
|
||||
* - Don't wrap every section in Card — mix open sections with cards.
|
||||
* - Run the pre-delivery self-check before returning code.
|
||||
*/
|
||||
/** Shared category color palette used by `Swatch`, `UsageBar`, etc. */
|
||||
export type { Color } from "./canvas-tokens.js";
|
||||
export { colorPalette, usageColorSequence } from "./canvas-tokens.js";
|
||||
/** Charts. */
|
||||
export type { BarChartProps, ChartDataPoint, ChartSeries, ChartTone, LineChartProps, PieChartProps, } from "./chart-primitives.js";
|
||||
export { BarChart, LineChart, PieChart } from "./chart-primitives.js";
|
||||
/** Borderless collapsible disclosure row with a structured header. */
|
||||
export type { CollapsibleSectionProps } from "./collapsible-section.js";
|
||||
export { CollapsibleSection } from "./collapsible-section.js";
|
||||
/** DAG layout. */
|
||||
export type { DAGLayoutEdge, DAGLayoutNode, DAGLayoutOptions, DAGLayoutRank, DAGLayoutResult, } from "./dag-layout.js";
|
||||
export { computeDAGLayout } from "./dag-layout.js";
|
||||
/**
|
||||
* Diff rendering. Compose with the generic `Card` family for file-level
|
||||
* chrome: use `DiffView` inside a `CardBody` (with `padding: 0`) and put
|
||||
* `DiffStats` in the enclosing `CardHeader`'s `trailing` slot.
|
||||
*/
|
||||
export type { DiffLineData, DiffLineType, DiffStatsProps, DiffViewProps, } from "./diff-view.js";
|
||||
export { DiffStats, DiffView } from "./diff-view.js";
|
||||
/** Form controls. */
|
||||
export type { CheckboxProps, IconButtonProps, SelectOption, SelectProps, TextAreaProps, TextInputProps, ToggleProps, } from "./form-primitives.js";
|
||||
export { Checkbox, IconButton, Select, TextArea, TextInput, Toggle, } from "./form-primitives.js";
|
||||
/** Host state hooks. */
|
||||
export type { CanvasAction, CanvasHostTheme, SetCanvasState } from "./hooks.js";
|
||||
export { useCanvasAction, useCanvasState, useHostTheme } from "./hooks.js";
|
||||
/** Colored category swatch (uses the shared `Color` palette). */
|
||||
export type { SwatchProps } from "./swatch.js";
|
||||
export { Swatch } from "./swatch.js";
|
||||
/** Semantic design tokens for custom styling. */
|
||||
export type { CanvasPalette, CanvasTokens } from "./theme.js";
|
||||
export { canvasPaletteDark, canvasPaletteLight, canvasTokens, canvasTokensLight, } from "./theme.js";
|
||||
export type { TodoItem, TodoListCardProps, TodoListProps, TodoStatus, } from "./todo-list.js";
|
||||
export { TodoList, TodoListCard } from "./todo-list.js";
|
||||
/** Component props types. */
|
||||
export type { ButtonProps, CalloutProps, CalloutTone, CardBodyProps, CardHeaderProps, CardProps, CardSize, CardVariant, CodeProps, DividerProps, GridProps, H1Props, H2Props, H3Props, LinkProps, PillProps, PillSize, PillTone, RowProps, StackProps, StatProps, StatTone, TableColumnAlign, TableProps, TableRowTone, TextProps, TextWeight, } from "./ui-primitives.js";
|
||||
/** Layout. */
|
||||
/** Typography. */
|
||||
/** Surfaces. */
|
||||
/** Actions. */
|
||||
/** Feedback. */
|
||||
export { Button, Callout, Card, CardBody, CardHeader, Code, Divider, Grid, H1, H2, H3, Link,
|
||||
/** Shallow-merge two style objects. Useful for combining tokens with overrides. */
|
||||
mergeStyle, Pill, Row, Spacer, Stack, Stat, Table, Text, } from "./ui-primitives.js";
|
||||
/** Usage bar — segmented progress meter with optional labels above. */
|
||||
export type { UsageBarProps, UsageBarSegment } from "./usage-bar.js";
|
||||
export { UsageBar } from "./usage-bar.js";
|
||||
//# sourceMappingURL=index.d.ts.map
|
||||
40
skills-cursor/canvas/sdk/swatch.d.ts
vendored
Normal file
40
skills-cursor/canvas/sdk/swatch.d.ts
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* Colored category swatch — a small filled rounded box. Intended for inline
|
||||
* list/row decoration (category badges, the leading slot of
|
||||
* `CollapsibleSection`, etc.).
|
||||
*
|
||||
* Pulls colors from the shared `Color` palette so a category's swatch and
|
||||
* its `UsageBar` segment for the same `color` stay visually coherent.
|
||||
*/
|
||||
import type { CSSProperties, JSX } from "react";
|
||||
import { type Color } from "./canvas-tokens.js";
|
||||
export type SwatchProps = {
|
||||
/** One of the 7 shared category hues. Matches `UsageBar` segment colors. */
|
||||
color: Color;
|
||||
style?: CSSProperties;
|
||||
};
|
||||
/**
|
||||
* Filled, rounded category swatch (24px). Use as the leading visual on
|
||||
* category rows, list items, or as the `leading` slot of a
|
||||
* `CollapsibleSection`.
|
||||
*
|
||||
* Colors come from the shared 7-hue `Color` palette, so a category's swatch
|
||||
* matches its `UsageBar` segment for the same `color`.
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* // Standalone — purple "tools" swatch
|
||||
* <Swatch color="purple" />
|
||||
*
|
||||
* // As the `leading` slot on a CollapsibleSection
|
||||
* <CollapsibleSection
|
||||
* title="Tools"
|
||||
* count={4}
|
||||
* leading={<Swatch color="purple" />}
|
||||
* >
|
||||
* <Text>Tool calls go here.</Text>
|
||||
* </CollapsibleSection>
|
||||
* ```
|
||||
*/
|
||||
export declare function Swatch({ color, style }: SwatchProps): JSX.Element;
|
||||
//# sourceMappingURL=swatch.d.ts.map
|
||||
61
skills-cursor/canvas/sdk/theme.d.ts
vendored
Normal file
61
skills-cursor/canvas/sdk/theme.d.ts
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
export type { CanvasPalette, CanvasTokens } from "./canvas-tokens.js";
|
||||
export { canvasPaletteDark, canvasPaletteLight, canvasTokens, canvasTokensLight, } from "./canvas-tokens.js";
|
||||
/** Typography presets used by the built-in `cursor/canvas` components. */
|
||||
export declare const canvasTypography: {
|
||||
readonly h1: {
|
||||
readonly fontSize: "24px";
|
||||
readonly lineHeight: "30px";
|
||||
readonly fontWeight: 590;
|
||||
};
|
||||
readonly h2: {
|
||||
readonly fontSize: "18px";
|
||||
readonly lineHeight: "24px";
|
||||
readonly fontWeight: 590;
|
||||
};
|
||||
readonly h3: {
|
||||
readonly fontSize: "16px";
|
||||
readonly lineHeight: "22px";
|
||||
readonly fontWeight: 590;
|
||||
};
|
||||
readonly body: {
|
||||
readonly fontSize: "14px";
|
||||
readonly lineHeight: "20px";
|
||||
readonly fontWeight: 400;
|
||||
};
|
||||
readonly small: {
|
||||
readonly fontSize: "12px";
|
||||
readonly lineHeight: "16px";
|
||||
readonly fontWeight: 400;
|
||||
};
|
||||
};
|
||||
/** Spacing scale (px). */
|
||||
export declare const canvasSpacing: {
|
||||
readonly "0.5": 2;
|
||||
readonly "1": 4;
|
||||
readonly "1.5": 6;
|
||||
readonly "2": 8;
|
||||
readonly "2.5": 10;
|
||||
readonly "3": 12;
|
||||
readonly "3.5": 14;
|
||||
readonly "4": 16;
|
||||
readonly "4.5": 18;
|
||||
readonly "5": 20;
|
||||
readonly "6": 24;
|
||||
readonly "7": 28;
|
||||
readonly "8": 32;
|
||||
readonly "9": 36;
|
||||
readonly "10": 40;
|
||||
};
|
||||
export type CanvasSpacing = typeof canvasSpacing;
|
||||
/** Border radius (px). */
|
||||
export declare const canvasRadius: {
|
||||
readonly none: 0;
|
||||
readonly xs: 2;
|
||||
readonly sm: 4;
|
||||
readonly md: 6;
|
||||
readonly lg: 8;
|
||||
readonly xl: 12;
|
||||
readonly full: 9999;
|
||||
};
|
||||
export type CanvasRadius = typeof canvasRadius;
|
||||
//# sourceMappingURL=theme.d.ts.map
|
||||
49
skills-cursor/canvas/sdk/todo-list.d.ts
vendored
Normal file
49
skills-cursor/canvas/sdk/todo-list.d.ts
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
import type { CSSProperties, JSX } from "react";
|
||||
export type TodoStatus = "pending" | "in_progress" | "completed" | "cancelled";
|
||||
export interface TodoItem {
|
||||
readonly id: string;
|
||||
readonly content: string;
|
||||
readonly status: TodoStatus;
|
||||
}
|
||||
export type TodoListProps = {
|
||||
todos: readonly TodoItem[];
|
||||
dimmedTodoIds?: ReadonlySet<string>;
|
||||
/** Called when a todo row is clicked (entire row is a button). */
|
||||
onTodoClick?: (todo: TodoItem) => void;
|
||||
style?: CSSProperties;
|
||||
};
|
||||
/**
|
||||
* Task list with status icons and wrapping text. Each row is a **clickable**
|
||||
* button; use `onTodoClick` to handle selection or navigation.
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* <TodoList
|
||||
* todos={items}
|
||||
* onTodoClick={(todo) => setActiveId(todo.id)}
|
||||
* />
|
||||
* ```
|
||||
*/
|
||||
export declare function TodoList({ todos, dimmedTodoIds, onTodoClick, style }: TodoListProps): JSX.Element | null;
|
||||
export type TodoListCardProps = {
|
||||
todos: readonly TodoItem[];
|
||||
dimmedTodoIds?: ReadonlySet<string>;
|
||||
defaultExpanded?: boolean;
|
||||
onTodoClick?: (todo: TodoItem) => void;
|
||||
style?: CSSProperties;
|
||||
};
|
||||
/**
|
||||
* Bordered, collapsible todo list with summary header (N of M Done). Compose
|
||||
* with `onTodoClick` for row actions.
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* <TodoListCard
|
||||
* todos={items}
|
||||
* defaultExpanded
|
||||
* onTodoClick={(todo) => console.log(todo.id)}
|
||||
* />
|
||||
* ```
|
||||
*/
|
||||
export declare function TodoListCard({ todos, dimmedTodoIds, defaultExpanded, onTodoClick, style }: TodoListCardProps): JSX.Element | null;
|
||||
//# sourceMappingURL=todo-list.d.ts.map
|
||||
549
skills-cursor/canvas/sdk/ui-primitives.d.ts
vendored
Normal file
549
skills-cursor/canvas/sdk/ui-primitives.d.ts
vendored
Normal file
@@ -0,0 +1,549 @@
|
||||
/**
|
||||
* UI primitives for `cursor/canvas`. Styling follows the Cursor dark theme; no extra packages required.
|
||||
*/
|
||||
import { type CSSProperties, type JSX, type ReactNode } from "react";
|
||||
/**
|
||||
* Shallow-merge style objects with `override` taking precedence.
|
||||
*
|
||||
* Use for small tweaks on built-in components (e.g. extra padding or width).
|
||||
* **Do not** use this to build elaborate custom chrome — prefer the built-in
|
||||
* components and flat solid token colors. No gradients, no box-shadows.
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* // Good — minor override on a built-in component
|
||||
* <CardBody style={mergeStyle({ padding: 16 })}>…</CardBody>
|
||||
*
|
||||
* // Bad — hand-rolled decorative styling
|
||||
* <div style={mergeStyle(base, { background: "linear-gradient(…)" })}>…</div>
|
||||
* ```
|
||||
*/
|
||||
export declare function mergeStyle(base: CSSProperties, override?: CSSProperties): CSSProperties;
|
||||
export type StackProps = {
|
||||
children?: ReactNode;
|
||||
gap?: number;
|
||||
style?: CSSProperties;
|
||||
};
|
||||
/**
|
||||
* Vertical flex column. Use as the top-level page wrapper or to stack cards/sections.
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* <Stack gap={16}>
|
||||
* <H1>Dashboard</H1>
|
||||
* <Card>…</Card>
|
||||
* <Card>…</Card>
|
||||
* </Stack>
|
||||
* ```
|
||||
*/
|
||||
export declare function Stack({ children, gap, style }: StackProps): JSX.Element;
|
||||
export type RowProps = {
|
||||
children?: ReactNode;
|
||||
gap?: number;
|
||||
align?: "start" | "center" | "end" | "stretch";
|
||||
justify?: "start" | "center" | "end" | "space-between";
|
||||
wrap?: boolean;
|
||||
style?: CSSProperties;
|
||||
};
|
||||
/**
|
||||
* Horizontal flex row. Use for inline groups of buttons, badges, or metadata.
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* <Row gap={8} align="center">
|
||||
* <Button variant="primary">Save</Button>
|
||||
* <Button variant="ghost">Cancel</Button>
|
||||
* </Row>
|
||||
* ```
|
||||
*/
|
||||
export declare function Row({ children, gap, align, justify, wrap, style }: RowProps): JSX.Element;
|
||||
/**
|
||||
* CSS Grid with tokenized gap. Prefer this over `Row` + `wrap` when you need a
|
||||
* fixed number of equal-width columns: wrapped flex items can land on their
|
||||
* own row and grow to full width (`flex-grow`), which is often surprising for
|
||||
* boards and dashboards.
|
||||
*/
|
||||
export type GridProps = {
|
||||
children?: ReactNode;
|
||||
/**
|
||||
* Equal columns: pass a number (uses `repeat(n, minmax(0, 1fr))`), or a CSS
|
||||
* `grid-template-columns` string (e.g. `"1fr 2fr"` or `"minmax(0, 200px) 1fr"`).
|
||||
*/
|
||||
columns: number | string;
|
||||
gap?: number;
|
||||
align?: "start" | "center" | "end" | "stretch";
|
||||
style?: CSSProperties;
|
||||
};
|
||||
export declare function Grid({ children, columns, gap, align, style }: GridProps): JSX.Element;
|
||||
export type DividerProps = {
|
||||
style?: CSSProperties;
|
||||
};
|
||||
/**
|
||||
* Horizontal line for visually separating sections. Uses `stroke.tertiary`
|
||||
* to match the Card/Table hairline weight.
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* <Stack>
|
||||
* <Text>Section one</Text>
|
||||
* <Divider />
|
||||
* <Text>Section two</Text>
|
||||
* </Stack>
|
||||
* ```
|
||||
*/
|
||||
export declare function Divider({ style }: DividerProps): JSX.Element;
|
||||
/**
|
||||
* Flex spacer that pushes siblings apart. Place inside a `Row` to push
|
||||
* trailing content to the right edge.
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* <Row>
|
||||
* <Text>Title</Text>
|
||||
* <Spacer />
|
||||
* <Button variant="primary">Save</Button>
|
||||
* </Row>
|
||||
* ```
|
||||
*/
|
||||
export declare function Spacer(): JSX.Element;
|
||||
/** Horizontal alignment for a table column. */
|
||||
export type TableColumnAlign = "left" | "center" | "right";
|
||||
/** Semantic tone for a table row — renders a translucent tinted background. */
|
||||
export type TableRowTone = "success" | "danger" | "warning" | "info" | "neutral";
|
||||
export type TableProps = {
|
||||
/** Column titles, left to right. Column count is fixed by this array. */
|
||||
headers: ReactNode[];
|
||||
/**
|
||||
* Body rows. Each row is an array of cells in the same order as `headers`.
|
||||
* Shorter rows are padded with empty cells; extra cells are ignored.
|
||||
*/
|
||||
rows: ReactNode[][];
|
||||
/** Optional alignment per column index (headers/rows). Defaults to left. */
|
||||
columnAlign?: Array<TableColumnAlign | undefined>;
|
||||
/**
|
||||
* Optional semantic tone per row index. Applies a translucent tinted
|
||||
* background — use for status highlighting (e.g. failing services, warnings).
|
||||
* Sparse: `undefined` entries are uncolored.
|
||||
*/
|
||||
rowTone?: Array<TableRowTone | undefined>;
|
||||
/** When true (default), bordered rounded shell with horizontal scroll if needed. */
|
||||
framed?: boolean;
|
||||
/** Alternate subtle fill on even rows for easier scanning in large tables. */
|
||||
striped?: boolean;
|
||||
/** Stick the header row when the framed container scrolls vertically. */
|
||||
stickyHeader?: boolean;
|
||||
style?: CSSProperties;
|
||||
/** Shown in a single spanning cell when `rows` is empty. */
|
||||
emptyMessage?: ReactNode;
|
||||
};
|
||||
/**
|
||||
* Data table with column headers and rows. Framed by default with its own
|
||||
* bordered container — **do not wrap in a Card** unless the card itself is
|
||||
* a named entity that happens to contain a table. Render directly under a
|
||||
* heading in the normal case.
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* // Good — table directly under a heading
|
||||
* <H2>Active services</H2>
|
||||
* <Table
|
||||
* headers={["Service", "Status", "RPS"]}
|
||||
* rows={[
|
||||
* ["api-gateway", "Steady", "3.2k"],
|
||||
* ["workers", "Hot", "8.1k"],
|
||||
* ]}
|
||||
* columnAlign={["left", "left", "right"]}
|
||||
* />
|
||||
*
|
||||
* // Allowed — table inside a named-entity card
|
||||
* <Card>
|
||||
* <CardHeader>billing-service</CardHeader>
|
||||
* <CardBody><Table headers={…} rows={…} /></CardBody>
|
||||
* </Card>
|
||||
* ```
|
||||
*/
|
||||
export declare function Table({ headers, rows, columnAlign, rowTone, framed, striped, stickyHeader, style, emptyMessage }: TableProps): JSX.Element;
|
||||
export type TextWeight = "normal" | "medium" | "semibold" | "bold";
|
||||
export type TextProps = {
|
||||
children?: ReactNode;
|
||||
tone?: "primary" | "secondary" | "tertiary" | "quaternary";
|
||||
size?: "body" | "small";
|
||||
/**
|
||||
* Element tag to render. Defaults to `"p"` for top-level body copy and
|
||||
* automatically switches to `"span"` when nested inside another typography
|
||||
* container so inline emphasis stays valid HTML.
|
||||
*/
|
||||
as?: "p" | "span";
|
||||
/** Font weight. Default is `"normal"` (400). Use `"semibold"` or `"bold"` for emphasis. */
|
||||
weight?: TextWeight;
|
||||
/** Render as italic. */
|
||||
italic?: boolean;
|
||||
/**
|
||||
* Truncate overflowing text with an ellipsis on a single line.
|
||||
* - `true` / `"end"` — ellipsis at the end (default truncation).
|
||||
* - `"start"` — ellipsis at the start. Useful for file paths where the
|
||||
* filename matters more than the directory prefix.
|
||||
*
|
||||
* Requires the parent to have a bounded width (flex child with
|
||||
* `minWidth: 0`, fixed width, etc.) — otherwise the text just expands
|
||||
* and never overflows.
|
||||
*/
|
||||
truncate?: boolean | "start" | "end";
|
||||
style?: CSSProperties;
|
||||
};
|
||||
/**
|
||||
* Body text with tone, size, weight, and italic variants.
|
||||
*
|
||||
* Top-level `Text` renders a `<p>`. Nested `Text` automatically renders a
|
||||
* `<span>` so inline emphasis like `<Text>Use <Text weight="semibold">this</Text></Text>`
|
||||
* does not emit invalid nested paragraphs. Use `as` to override when needed.
|
||||
*
|
||||
* Compose with `<Code>` for inline code and `<Link>` for hyperlinks inside
|
||||
* the text flow.
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* <Text>Primary body text.</Text>
|
||||
* <Text weight="semibold">Important note.</Text>
|
||||
* <Text italic tone="secondary">Supplementary remark.</Text>
|
||||
* <Text>Run <Code>npm install</Code> to get started.</Text>
|
||||
* <Text>See the <Link href="https://example.com">docs</Link> for details.</Text>
|
||||
* ```
|
||||
*/
|
||||
export declare function Text({ children, tone, size, as, weight, italic, truncate, style }: TextProps): JSX.Element;
|
||||
export type H1Props = {
|
||||
children?: ReactNode;
|
||||
style?: CSSProperties;
|
||||
};
|
||||
/**
|
||||
* Page-level heading. Use once at the top of a canvas.
|
||||
* **Do not** place inside `CardHeader` — card headers use their own label.
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* <Stack>
|
||||
* <H1>Performance Report</H1>
|
||||
* <Card>…</Card>
|
||||
* </Stack>
|
||||
* ```
|
||||
*/
|
||||
export declare function H1({ children, style }: H1Props): JSX.Element;
|
||||
export type H2Props = {
|
||||
children?: ReactNode;
|
||||
style?: CSSProperties;
|
||||
};
|
||||
/**
|
||||
* Section heading. Use between groups of cards or sections.
|
||||
* **Do not** place inside `CardHeader` — card headers use their own label.
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* <Stack>
|
||||
* <H2>Recent activity</H2>
|
||||
* <Card>…</Card>
|
||||
* <Card>…</Card>
|
||||
* </Stack>
|
||||
* ```
|
||||
*/
|
||||
export declare function H2({ children, style }: H2Props): JSX.Element;
|
||||
export type H3Props = {
|
||||
children?: ReactNode;
|
||||
style?: CSSProperties;
|
||||
};
|
||||
/**
|
||||
* Sub-section heading. Use below `H2` for finer hierarchy.
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* <Stack>
|
||||
* <H2>API Reference</H2>
|
||||
* <H3>Authentication</H3>
|
||||
* <Text>All requests require a bearer token.</Text>
|
||||
* </Stack>
|
||||
* ```
|
||||
*/
|
||||
export declare function H3({ children, style }: H3Props): JSX.Element;
|
||||
export type CodeProps = {
|
||||
children?: ReactNode;
|
||||
style?: CSSProperties;
|
||||
};
|
||||
/**
|
||||
* Inline `<code>` span for identifiers, file names, or short snippets.
|
||||
* Uses `0.92em` so it scales with surrounding text (headings, body, etc.).
|
||||
*
|
||||
* Prefer writing backtick markdown inside `Text` — e.g. `` <Text>Run `npm install`</Text> `` —
|
||||
* which is automatically parsed. Use `<Code>` only when you need an explicit element.
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* <Text>Run <Code>npm install</Code> to get started.</Text>
|
||||
* ```
|
||||
*/
|
||||
export declare function Code({ children, style }: CodeProps): JSX.Element;
|
||||
export type LinkProps = {
|
||||
children?: ReactNode;
|
||||
href: string;
|
||||
style?: CSSProperties;
|
||||
};
|
||||
/**
|
||||
* Inline link that opens in the user's default browser.
|
||||
*
|
||||
* Prefer writing markdown links inside `Text` — e.g. `<Text>See the [docs](url)</Text>` —
|
||||
* which are automatically parsed. Use `<Link>` when you need an explicit anchor
|
||||
* outside of a text flow or when composing with other elements.
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* <Link href="https://docs.example.com">View documentation</Link>
|
||||
* ```
|
||||
*/
|
||||
export declare function Link({ children, href, style }: LinkProps): JSX.Element;
|
||||
export type CardSize = "base" | "lg";
|
||||
export type CardVariant = "default" | "borderless";
|
||||
/**
|
||||
* Inline chevron SVG used by disclosure-style controls (collapsible cards,
|
||||
* expandable list items, etc.). Shared by `Card` and `todo-list.tsx` so
|
||||
* every disclosure in the canvas SDK uses the same glyph.
|
||||
*/
|
||||
export declare function CanvasChevron({ expanded }: {
|
||||
expanded: boolean;
|
||||
}): JSX.Element;
|
||||
export type CardProps = {
|
||||
children?: ReactNode;
|
||||
/** Default: bordered surface with radius; `borderless` removes both. */
|
||||
variant?: CardVariant;
|
||||
/** `lg` uses a taller header and roomier title padding (matches packages/ui). */
|
||||
size?: CardSize;
|
||||
/**
|
||||
* When true, the header uses `position: sticky` so it stays visible while
|
||||
* the card body scrolls. Requires the card (or a parent) to have a
|
||||
* constrained height and `overflow: auto` — the canvas host controls this,
|
||||
* so sticky behavior depends on the host viewport.
|
||||
*/
|
||||
stickyHeader?: boolean;
|
||||
/**
|
||||
* Make the card collapsible. The header becomes a clickable toggle with
|
||||
* a leading chevron; `CardBody` renders nothing while the card is closed.
|
||||
*/
|
||||
collapsible?: boolean;
|
||||
/** Initial open state in uncontrolled mode. Ignored when `open` is set. */
|
||||
defaultOpen?: boolean;
|
||||
/** Controlled open state. Pair with `onOpenChange`. */
|
||||
open?: boolean;
|
||||
/** Fires on every toggle with the next open state. */
|
||||
onOpenChange?: (open: boolean) => void;
|
||||
style?: CSSProperties;
|
||||
};
|
||||
/**
|
||||
* Bordered surface for a **labeled, self-contained unit** — a file, a service,
|
||||
* a config block, or a table with a title. Compose with `CardHeader` + `CardBody`.
|
||||
*
|
||||
* **When to use Card:**
|
||||
* - Displaying a named entity (file path, service name, resource).
|
||||
* - Wrapping a `<Table>` or `<DiffView>` that needs a title.
|
||||
* - A distinct, bounded section the user might scan by header label.
|
||||
*
|
||||
* **When NOT to use Card:**
|
||||
* - General text sections — use `<H2>` + `<Text>` instead. Not every section
|
||||
* needs a border.
|
||||
* - Page-level layout — use `<Stack>` with headings. A canvas should not be a
|
||||
* wall of stacked cards.
|
||||
* - Nesting — do not put cards inside cards. Use `<Divider>` within a card body.
|
||||
*
|
||||
* Pass **plain text** as `CardHeader` children — the header provides its own
|
||||
* 12px font. Do **not** put `<H1>` or `<H2>` inside a card header.
|
||||
*
|
||||
* Set `collapsible` to make the header a toggle that shows/hides `CardBody`.
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* // Card wraps a titled diff
|
||||
* <Card>
|
||||
* <CardHeader trailing={<DiffStats additions={5} deletions={2} />}>
|
||||
* src/utils.ts
|
||||
* </CardHeader>
|
||||
* <CardBody style={{ padding: 0 }}>
|
||||
* <DiffView path="src/utils.ts" lines={lines} />
|
||||
* </CardBody>
|
||||
* </Card>
|
||||
*
|
||||
* // Collapsible card
|
||||
* <Card collapsible defaultOpen={false}>
|
||||
* <CardHeader>deploy-service.ts</CardHeader>
|
||||
* <CardBody>Service handles rolling deployments across regions.</CardBody>
|
||||
* </Card>
|
||||
*
|
||||
* // Bad — card wrapping plain text that should just be a heading
|
||||
* // Use <H2>Overview</H2><Text>…</Text> instead.
|
||||
* ```
|
||||
*/
|
||||
export declare function Card({ children, variant, size, stickyHeader, collapsible, defaultOpen, open: openProp, onOpenChange, style }: CardProps): JSX.Element;
|
||||
export type CardHeaderProps = {
|
||||
/** Plain text title. Do **not** pass headings, buttons, pills, or layout rows. */
|
||||
children?: ReactNode;
|
||||
/** Small trailing content aligned to the right edge — a status label, a
|
||||
* single pill, or a short metadata string. Keep it compact. */
|
||||
trailing?: ReactNode;
|
||||
style?: CSSProperties;
|
||||
};
|
||||
/**
|
||||
* 28px header row (32px at `size="lg"`). A compact label for the card.
|
||||
*
|
||||
* **`children`** — plain text only. This is a 12px label, not a toolbar.
|
||||
* Do **not** pass `<H1>`, `<H2>`, `<Text weight="bold">`, `<Pill>`,
|
||||
* `<Button>`, `<Row>`, or any interactive/layout elements as children.
|
||||
*
|
||||
* **`trailing`** — optional right-aligned slot for small status indicators
|
||||
* (a short label, a single `<Pill>`, a metadata string like a timestamp).
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* // Good — plain title
|
||||
* <CardHeader>config.yaml</CardHeader>
|
||||
*
|
||||
* // Good — title with trailing status
|
||||
* <CardHeader trailing={<Pill active>Healthy</Pill>}>
|
||||
* billing-service
|
||||
* </CardHeader>
|
||||
*
|
||||
* // Bad — heading in header (use CardHeader text, not H2)
|
||||
* // Bad — buttons in header (no room, wrong context)
|
||||
* // Bad — multiple pills in header (use trailing for one, or move to CardBody)
|
||||
* ```
|
||||
*/
|
||||
export declare function CardHeader({ children, trailing, style }: CardHeaderProps): JSX.Element;
|
||||
export type CardBodyProps = {
|
||||
children?: ReactNode;
|
||||
style?: CSSProperties;
|
||||
};
|
||||
/**
|
||||
* Padded content area inside a Card.
|
||||
* Override `style` to adjust padding for custom layouts.
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* <Card>
|
||||
* <CardHeader>Overview</CardHeader>
|
||||
* <CardBody>This service is currently healthy.</CardBody>
|
||||
* </Card>
|
||||
* ```
|
||||
*/
|
||||
export declare function CardBody({ children, style }: CardBodyProps): JSX.Element | null;
|
||||
export type ButtonProps = {
|
||||
children?: ReactNode;
|
||||
variant?: "primary" | "secondary" | "ghost";
|
||||
disabled?: boolean;
|
||||
type?: "button" | "submit" | "reset";
|
||||
style?: CSSProperties;
|
||||
onClick?: () => void;
|
||||
};
|
||||
/**
|
||||
* Action button (24px height, sized to its label). **Never stretch to full
|
||||
* width** — buttons are always inline and hug their text.
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* <Row gap={8}>
|
||||
* <Button variant="primary" onClick={handleSave}>Save</Button>
|
||||
* <Button variant="secondary">Export</Button>
|
||||
* <Button variant="ghost">Cancel</Button>
|
||||
* </Row>
|
||||
* ```
|
||||
*/
|
||||
export declare function Button({ children, variant, disabled, type, style, onClick }: ButtonProps): JSX.Element;
|
||||
export type PillTone = "neutral" | "added" | "deleted" | "renamed" | "success" | "warning" | "info";
|
||||
export type PillSize = "sm" | "md";
|
||||
export type PillProps = {
|
||||
children?: ReactNode;
|
||||
/** Whether the pill is in its selected/active state (filled background). */
|
||||
active?: boolean;
|
||||
/**
|
||||
* Semantic tone. Recolors the border and text. When `active` is also
|
||||
* set, fills the background with the tone color at low opacity.
|
||||
* Defaults to `neutral` (current stroke/text tokens).
|
||||
*/
|
||||
tone?: PillTone;
|
||||
/**
|
||||
* Visual size. `"md"` (default) is the standard pill. `"sm"` is a
|
||||
* compact variant with smaller text, tighter padding, and no border —
|
||||
* designed for tight spaces like `CardHeader` trailing slots.
|
||||
*/
|
||||
size?: PillSize;
|
||||
/** Shown before the label (icon, emoji, etc.). */
|
||||
leadingContent?: ReactNode;
|
||||
/** e.g. shortcut hint — matches ui `Pill` ghost keyboard hint (muted primary). */
|
||||
keyboardHint?: string;
|
||||
disabled?: boolean;
|
||||
title?: string;
|
||||
style?: CSSProperties;
|
||||
onClick?: () => void;
|
||||
};
|
||||
/**
|
||||
* Pill-shaped label or toggle button. Use for tab bars, filter groups, or
|
||||
* action suggestions. Set `active` for the selected state (filled background).
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* // Tab-style selector
|
||||
* <Row gap={8}>
|
||||
* {tabs.map(tab => (
|
||||
* <Pill key={tab} active={tab === selected} onClick={() => setSelected(tab)}>
|
||||
* {tab}
|
||||
* </Pill>
|
||||
* ))}
|
||||
* </Row>
|
||||
*
|
||||
* // Action suggestion with shortcut hint
|
||||
* <Pill onClick={handlePlan} keyboardHint="⇧Tab">Plan new idea</Pill>
|
||||
* ```
|
||||
*/
|
||||
export declare function Pill({ children, active, tone, size, leadingContent, keyboardHint, disabled, title, style, onClick }: PillProps): JSX.Element;
|
||||
export type StatTone = "success" | "danger" | "warning" | "info";
|
||||
export type StatProps = {
|
||||
/** The primary metric value (number, percentage, short string). */
|
||||
value: ReactNode;
|
||||
/** Label below the value. */
|
||||
label: string;
|
||||
/** Semantic color for the value. Omit for default primary text. */
|
||||
tone?: StatTone;
|
||||
style?: CSSProperties;
|
||||
};
|
||||
/**
|
||||
* Single metric display — a large value with a compact label beneath it.
|
||||
* Use inside `<Grid>` for dashboard summary strips.
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* <Grid columns={3} gap={16}>
|
||||
* <Stat value="4" label="Healthy" tone="success" />
|
||||
* <Stat value="1" label="Degraded" tone="warning" />
|
||||
* <Stat value="99.2%" label="Avg Uptime" />
|
||||
* </Grid>
|
||||
* ```
|
||||
*/
|
||||
export declare function Stat({ value, label, tone, style }: StatProps): JSX.Element;
|
||||
export type CalloutTone = "info" | "success" | "warning" | "danger" | "neutral";
|
||||
export type CalloutProps = {
|
||||
/** Body content. Plain strings, `<Text>`, `<Code>`, `<Link>`, or short lists. */
|
||||
children?: ReactNode;
|
||||
/** Semantic tone. Recolors the border, background tint, and title text. */
|
||||
tone?: CalloutTone;
|
||||
/** Optional bold title line, shown above the body in the tone color. */
|
||||
title?: ReactNode;
|
||||
/** Optional leading icon (emoji, inline SVG, or short text glyph). */
|
||||
icon?: ReactNode;
|
||||
style?: CSSProperties;
|
||||
};
|
||||
/**
|
||||
* Tinted, bordered notice block for warnings, tips, or short status messages
|
||||
* inline within a section.
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* <Callout tone="warning" title="Heads up">
|
||||
* Rolling deploy is in progress. Metrics may be noisy for 10 minutes.
|
||||
* </Callout>
|
||||
* ```
|
||||
*/
|
||||
export declare function Callout({ children, tone, title, icon, style }: CalloutProps): JSX.Element;
|
||||
//# sourceMappingURL=ui-primitives.d.ts.map
|
||||
2
skills-cursor/canvas/sdk/ui-primitives.test.d.ts
vendored
Normal file
2
skills-cursor/canvas/sdk/ui-primitives.test.d.ts
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
export {};
|
||||
//# sourceMappingURL=ui-primitives.test.d.ts.map
|
||||
56
skills-cursor/canvas/sdk/usage-bar.d.ts
vendored
Normal file
56
skills-cursor/canvas/sdk/usage-bar.d.ts
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Segmented usage bar primitive — proportional pills + remainder, with an
|
||||
* optional one-line label row above. Visually matches `packages/ui`
|
||||
* `ContextUsageTray`'s usage bar, themed for canvas via the shared `Color`
|
||||
* palette and `useHostTheme()` semantic tokens.
|
||||
*/
|
||||
import type { CSSProperties, JSX, ReactNode } from "react";
|
||||
import { type Color } from "./canvas-tokens.js";
|
||||
export interface UsageBarSegment {
|
||||
/** Stable identifier (used as React key). */
|
||||
readonly id: string;
|
||||
/** Proportional weight for this segment. Non-finite or `<= 0` is treated as 0. */
|
||||
readonly value: number;
|
||||
/**
|
||||
* Optional explicit color. Defaults to a rotation through
|
||||
* `usageColorSequence` by index, matching the original `packages/ui`
|
||||
* `ContextUsageTray` order so the same index lands on the same hue.
|
||||
*/
|
||||
readonly color?: Color;
|
||||
}
|
||||
export type UsageBarProps = {
|
||||
/** Segments rendered left-to-right; widths are proportional to `value`. */
|
||||
readonly segments: readonly UsageBarSegment[];
|
||||
/** Total weight of the bar. The remainder span fills `max(0, total - sum(values))`. */
|
||||
readonly total: number;
|
||||
/** Optional small label rendered above the bar, left-aligned. */
|
||||
readonly topLeftLabel?: ReactNode;
|
||||
/** Optional small label rendered above the bar, right-aligned. */
|
||||
readonly topRightLabel?: ReactNode;
|
||||
readonly style?: CSSProperties;
|
||||
};
|
||||
/**
|
||||
* Segmented horizontal usage bar — proportional category pills with a
|
||||
* remainder span. Use to visualize a fixed-budget breakdown (context window
|
||||
* tokens, storage usage, etc.).
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* <UsageBar
|
||||
* total={120_000}
|
||||
* topLeftLabel="64% Full"
|
||||
* topRightLabel="76.8K / 120K Tokens"
|
||||
* segments={[
|
||||
* { id: "system", value: 8_000, color: "gray" },
|
||||
* { id: "tools", value: 24_000, color: "purple" },
|
||||
* { id: "rules", value: 12_000, color: "green" },
|
||||
* { id: "skills", value: 6_000, color: "yellow" },
|
||||
* { id: "mcp", value: 4_000, color: "pink" },
|
||||
* { id: "subagents", value: 8_800, color: "blue" },
|
||||
* { id: "conversation", value: 14_000, color: "orange" },
|
||||
* ]}
|
||||
* />
|
||||
* ```
|
||||
*/
|
||||
export declare function UsageBar({ segments, total, topLeftLabel, topRightLabel, style }: UsageBarProps): JSX.Element;
|
||||
//# sourceMappingURL=usage-bar.d.ts.map
|
||||
Reference in New Issue
Block a user