@makinbakin/sdk 0.0.1-rc.2 → 0.0.1-rc.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/README.md +1 -0
  2. package/_internal/app/components/agent-select.d.ts +16 -2
  3. package/_internal/app/components/asset-picker.d.ts +25 -0
  4. package/_internal/app/components/charts/bar-chart.d.ts +16 -0
  5. package/_internal/app/components/charts/chart-data-table.d.ts +31 -0
  6. package/_internal/app/components/charts/chart-explainer.d.ts +9 -0
  7. package/_internal/app/components/charts/chart-tooltip.d.ts +8 -0
  8. package/_internal/app/components/charts/line-chart.d.ts +13 -0
  9. package/_internal/app/components/charts/palette.d.ts +24 -0
  10. package/_internal/app/components/charts/sparkline.d.ts +12 -0
  11. package/_internal/app/components/charts/stacked-column-chart.d.ts +40 -0
  12. package/_internal/app/components/confirm-dialog.d.ts +54 -0
  13. package/_internal/app/components/conversation/activity-group.d.ts +15 -0
  14. package/_internal/app/components/conversation/agent-turn.d.ts +36 -0
  15. package/_internal/app/components/conversation/attention.d.ts +56 -0
  16. package/_internal/app/components/conversation/composer.d.ts +35 -0
  17. package/_internal/app/components/conversation/conversation-empty-state.d.ts +8 -0
  18. package/_internal/app/components/conversation/conversation-panel.d.ts +33 -0
  19. package/_internal/app/components/conversation/conversation.d.ts +14 -0
  20. package/_internal/app/components/conversation/fold.d.ts +129 -0
  21. package/_internal/app/components/conversation/notification-sound.d.ts +8 -0
  22. package/_internal/app/components/conversation/relative-time.d.ts +8 -0
  23. package/_internal/app/components/conversation/reply-toast.d.ts +15 -0
  24. package/_internal/app/components/conversation/thread-id.d.ts +8 -0
  25. package/_internal/app/components/conversation/tool-call-drawer.d.ts +7 -0
  26. package/_internal/app/components/conversation/turn-recorder.d.ts +37 -0
  27. package/_internal/app/components/conversation/use-conversation-attention.d.ts +64 -0
  28. package/_internal/app/components/conversation/use-conversation-thread.d.ts +55 -0
  29. package/_internal/app/components/conversation/user-message.d.ts +11 -0
  30. package/_internal/app/components/danger-zone.d.ts +28 -0
  31. package/_internal/app/components/empty-state.d.ts +18 -6
  32. package/_internal/app/components/plugin-header.d.ts +4 -3
  33. package/_internal/app/components/save-bar.d.ts +32 -0
  34. package/_internal/app/components/score-overlay.d.ts +33 -0
  35. package/_internal/app/components/search-degraded-chip.d.ts +4 -0
  36. package/_internal/app/components/search-partial-chip.d.ts +13 -0
  37. package/_internal/app/components/search-unavailable.d.ts +12 -0
  38. package/_internal/app/components/section-card.d.ts +22 -0
  39. package/_internal/app/components/segmented-control.d.ts +28 -0
  40. package/_internal/app/components/stat-tile.d.ts +26 -0
  41. package/_internal/app/components/status-badge.d.ts +19 -0
  42. package/_internal/app/components/turn-output-view.d.ts +57 -0
  43. package/_internal/app/components/ui/badge.d.ts +1 -1
  44. package/_internal/app/components/ui/button.d.ts +1 -1
  45. package/_internal/app/components/underline-tabs.d.ts +6 -2
  46. package/_internal/app/components/unsaved-changes-guard.d.ts +34 -0
  47. package/_internal/app/core/conversation-turns.d.ts +148 -0
  48. package/_internal/app/core/logger.d.ts +1 -0
  49. package/_internal/app/hooks/use-available-models.d.ts +5 -0
  50. package/_internal/app/hooks/use-content-store.d.ts +0 -9
  51. package/_internal/app/hooks/use-file-drop.d.ts +25 -0
  52. package/_internal/app/hooks/use-history-back.d.ts +1 -0
  53. package/_internal/app/hooks/use-horizontal-resize.d.ts +22 -0
  54. package/_internal/app/hooks/use-json-fetch.d.ts +26 -0
  55. package/_internal/app/hooks/use-nav-badge.d.ts +13 -0
  56. package/_internal/app/hooks/use-plugin-event.d.ts +19 -0
  57. package/_internal/app/hooks/use-query-state.d.ts +2 -0
  58. package/_internal/app/hooks/use-resizable-pane.d.ts +35 -0
  59. package/_internal/app/hooks/use-schedule.d.ts +47 -1
  60. package/_internal/app/hooks/use-search.d.ts +27 -8
  61. package/_internal/app/hooks/use-task-run-history.d.ts +26 -0
  62. package/_internal/app/hooks/use-toast.d.ts +3 -3
  63. package/_internal/app/hooks/use-vertical-resize.d.ts +6 -7
  64. package/_internal/app/lib/browser-notify.d.ts +12 -1
  65. package/_internal/app/types/index.d.ts +1 -105
  66. package/_internal/core/adapters/runtime/concepts.d.ts +671 -99
  67. package/_internal/core/adapters/runtime/errors.d.ts +98 -0
  68. package/_internal/core/adapters/runtime/helpers.d.ts +19 -0
  69. package/_internal/core/adapters/runtime/index.d.ts +7 -2
  70. package/_internal/core/adapters/runtime/testing.d.ts +79 -0
  71. package/_internal/core/adapters/runtime/turn-activity.d.ts +23 -0
  72. package/_internal/core/adapters/shared.d.ts +122 -12
  73. package/_internal/core/content-dir.d.ts +9 -0
  74. package/_internal/core/docs/route.d.ts +1 -1
  75. package/_internal/core/format/structured.d.ts +44 -0
  76. package/_internal/core/format.d.ts +13 -0
  77. package/_internal/core/media/downscale.d.ts +18 -0
  78. package/_internal/core/media/sharp-loader.d.ts +36 -0
  79. package/_internal/core/plugin-types.d.ts +216 -499
  80. package/_internal/core/routing/define.d.ts +26 -3
  81. package/_internal/core/routing/dispatcher.d.ts +15 -6
  82. package/_internal/core/routing/index.d.ts +1 -1
  83. package/_internal/core/routing/types.d.ts +13 -70
  84. package/_internal/core/storage/atomic-write.d.ts +11 -0
  85. package/_internal/core/tasks/store.d.ts +129 -0
  86. package/_internal/core/tasks/testing.d.ts +2 -0
  87. package/_internal/{plugins/workflows/lib → core/workflows}/notification-channel-registry.d.ts +1 -1
  88. package/_internal/plugins/team/types.d.ts +61 -4
  89. package/_internal/plugins/workflows/hooks/use-notification-channels.d.ts +1 -1
  90. package/components/index.d.ts +111 -5
  91. package/components/index.js +61815 -30060
  92. package/hooks/index.d.ts +90 -9
  93. package/hooks/index.js +15181 -685
  94. package/hooks/router.d.ts +20 -4
  95. package/index.d.ts +20 -3
  96. package/index.js +297 -259
  97. package/internal/index.d.ts +70 -0
  98. package/internal/index.js +409 -0
  99. package/metadata/index.d.ts +14 -1
  100. package/package.json +9 -2
  101. package/register.d.ts +63 -9
  102. package/routing/index.d.ts +6 -1
  103. package/routing/index.js +187 -147
  104. package/slots/index.d.ts +16 -24
  105. package/slots/index.js +215 -30
  106. package/testing/index.d.ts +122 -0
  107. package/testing/index.js +21874 -0
  108. package/types/index.d.ts +19 -919
  109. package/types/index.js +16 -0
  110. package/ui/index.js +2 -1
  111. package/utils/index.d.ts +46 -6
  112. package/utils/index.js +322 -249
  113. package/_internal/app/components/integrated-brainstorm/activity.d.ts +0 -23
  114. package/_internal/app/components/integrated-brainstorm/collapsed-header.d.ts +0 -14
  115. package/_internal/app/components/integrated-brainstorm/empty-state.d.ts +0 -5
  116. package/_internal/app/components/integrated-brainstorm/index.d.ts +0 -8
  117. package/_internal/app/components/integrated-brainstorm/input-row.d.ts +0 -16
  118. package/_internal/app/components/integrated-brainstorm/message-list.d.ts +0 -8
  119. package/_internal/app/components/integrated-brainstorm/session.d.ts +0 -16
  120. package/_internal/app/components/integrated-brainstorm/sse.d.ts +0 -8
  121. package/_internal/app/components/integrated-brainstorm/thinking-indicator.d.ts +0 -19
  122. package/_internal/app/components/integrated-brainstorm/types.d.ts +0 -63
  123. package/_internal/app/components/integrated-brainstorm/use-auto-grow.d.ts +0 -6
  124. package/_internal/app/components/integrated-brainstorm/use-brainstorm-state.d.ts +0 -21
  125. package/_internal/app/hooks/use-assets.d.ts +0 -25
package/README.md CHANGED
@@ -86,6 +86,7 @@ component for a slot via `registerPlugin({ slots: { 'slot-name': Component } })`
86
86
  | `task-assets` | Task drawer, asset attachments section |
87
87
  | `task-sidebar` | Task drawer sidebar (custom panels for a plugin's tasks) |
88
88
  | `home-widget` | Dashboard home widget grid |
89
+ | `nav-badge-providers` | Background hook runners (render `null`) that drive `setNavBadge` |
89
90
  | `page:/<route>` | Full-page mount at `<route>` |
90
91
 
91
92
  ## Sub-path imports
@@ -1,6 +1,18 @@
1
- interface AgentSelectProps {
1
+ import type { AriaAttributes } from 'react';
2
+ /** Prefix marking a team selection in the select's string value (#189).
3
+ * Task surfaces split it back into {agent} vs {team} before talking to the
4
+ * API; workflow STEP definitions store the token verbatim (#611 — the step's
5
+ * team target, resolved sticky at dispatch). */
6
+ export declare const TEAM_VALUE_PREFIX = "team:";
7
+ export declare function isTeamValue(value: string): boolean;
8
+ export declare function teamIdFromValue(value: string): string;
9
+ interface AgentSelectProps extends Pick<AriaAttributes, 'aria-describedby' | 'aria-invalid'> {
10
+ id?: string;
2
11
  value: string;
3
12
  onValueChange: (value: string) => void;
13
+ /** Include the workflow/task runtime assignee token (`$assigned`) */
14
+ includeAssigned?: boolean;
15
+ assignedLabel?: string;
4
16
  /** Show a "None" / "Unassigned" option at the top (default: false) */
5
17
  allowNone?: boolean;
6
18
  /** Label for the none option (default: "Unassigned") */
@@ -9,7 +21,9 @@ interface AgentSelectProps {
9
21
  placeholder?: string;
10
22
  /** Restrict to a subset of agent IDs */
11
23
  agentIds?: string[];
24
+ /** Offer teams as assignment targets (`team:<id>` values, #189) */
25
+ includeTeams?: boolean;
12
26
  className?: string;
13
27
  }
14
- export declare function AgentSelect({ value, onValueChange, allowNone, noneLabel, placeholder, agentIds, className, }: AgentSelectProps): import("react/jsx-runtime").JSX.Element;
28
+ export declare function AgentSelect({ value, onValueChange, includeAssigned, assignedLabel, allowNone, noneLabel, placeholder, agentIds, includeTeams, className, id, 'aria-describedby': ariaDescribedBy, 'aria-invalid': ariaInvalid, }: AgentSelectProps): import("react/jsx-runtime").JSX.Element;
15
29
  export {};
@@ -0,0 +1,25 @@
1
+ export interface AssetPickerAsset {
2
+ assetId: string;
3
+ description: string;
4
+ type: string;
5
+ hasThumb: boolean;
6
+ }
7
+ export interface AssetPickerProps {
8
+ open: boolean;
9
+ onOpenChange: (open: boolean) => void;
10
+ /** Called with the chosen (or freshly uploaded) assetId; the dialog closes itself after. */
11
+ onPick: (assetId: string) => void;
12
+ /** Dialog heading (default "Choose an asset"). */
13
+ title?: string;
14
+ /** One-liner under the heading (e.g. what the asset will be used for). */
15
+ description?: string;
16
+ /** Narrow the grid (e.g. only images). Applied client-side over the library listing. */
17
+ filter?: (asset: AssetPickerAsset) => boolean;
18
+ }
19
+ /**
20
+ * Modal asset chooser over the assets plugin's library: search, thumbnail
21
+ * grid, and drag/drop or button upload-new (which picks the fresh asset).
22
+ * THE way any surface references a managed asset — never a raw id `<select>`.
23
+ * Engine-unreachable renders an honest error state, never a blank grid.
24
+ */
25
+ export declare function AssetPicker({ open, onOpenChange, onPick, title, description, filter }: AssetPickerProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,16 @@
1
+ import { type ChartDatum, type ChartSeries } from './chart-data-table';
2
+ export interface BarChartProps {
3
+ data: ChartDatum[];
4
+ series: ChartSeries[];
5
+ label: string;
6
+ description?: string;
7
+ height?: number;
8
+ /** Stack series within each x-axis bucket instead of grouping them. */
9
+ stacked?: boolean;
10
+ formatValue?: (value: number) => string;
11
+ emptyLabel?: string;
12
+ /** Hide the built-in collapsible table when the consumer renders equivalent data beside the chart. */
13
+ showDataTable?: boolean;
14
+ }
15
+ /** Dependency-free grouped/stacked bar chart with keyboard-equivalent marks. */
16
+ export declare function BarChart({ data, series, label, description, height, stacked, formatValue, emptyLabel, showDataTable, }: BarChartProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,31 @@
1
+ import type { ReactNode } from 'react';
2
+ export interface ChartDatum {
3
+ /** Stable x-axis key. */
4
+ x: string;
5
+ /** Human-readable x-axis label; defaults to `x`. */
6
+ xLabel?: string;
7
+ /** Values keyed by `ChartSeries.key`. */
8
+ values: Record<string, number>;
9
+ /** Per-series labels for intentionally absent cells. */
10
+ missingLabels?: Record<string, string>;
11
+ }
12
+ export interface ChartSeries {
13
+ key: string;
14
+ label: string;
15
+ /** CSS color. Defaults to the matching semantic `--chart-*` token. */
16
+ color?: string;
17
+ }
18
+ export interface ChartDataTableProps {
19
+ data: ChartDatum[];
20
+ series: ChartSeries[];
21
+ caption: string;
22
+ formatValue?: (value: number) => ReactNode;
23
+ /** Rendered when a series has no value for a bucket; defaults to formatted zero. */
24
+ missingValue?: ReactNode;
25
+ /** Visually hide the exact table when the chart is intentionally compact. */
26
+ visuallyHidden?: boolean;
27
+ }
28
+ export declare const CHART_TOKEN_COLORS: readonly ["var(--chart-1)", "var(--chart-2)", "var(--chart-3)", "var(--chart-4)", "var(--chart-5)"];
29
+ export declare function chartSeriesColor(series: ChartSeries, index: number): string;
30
+ /** Exact values for charts whose visual marks intentionally summarize data. */
31
+ export declare function ChartDataTable({ data, series, caption, formatValue, missingValue, visuallyHidden, }: ChartDataTableProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * ChartExplainer (#385) — the one-line "what am I looking at / when should I
3
+ * worry" footer every supervision chart carries. Plain language for users
4
+ * who aren't AI experts; keep it to one or two sentences.
5
+ */
6
+ import type { ReactNode } from 'react';
7
+ export declare function ChartExplainer({ children }: {
8
+ children: ReactNode;
9
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,8 @@
1
+ export interface ChartTooltipProps {
2
+ id: string;
3
+ text: string;
4
+ xPercent: number;
5
+ yPercent: number;
6
+ }
7
+ /** Shared non-animated tooltip used identically by pointer and keyboard focus. */
8
+ export declare function ChartTooltip({ id, text, xPercent, yPercent }: ChartTooltipProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,13 @@
1
+ import { type ChartDatum, type ChartSeries } from './chart-data-table';
2
+ export interface LineChartProps {
3
+ data: ChartDatum[];
4
+ series: ChartSeries[];
5
+ label: string;
6
+ description?: string;
7
+ height?: number;
8
+ formatValue?: (value: number) => string;
9
+ emptyLabel?: string;
10
+ }
11
+ /** Dependency-free multi-series line chart with keyboard-equivalent marks. */
12
+ export declare function LineChart({ data, series, label, description, height, formatValue, emptyLabel, }: LineChartProps): import("react/jsx-runtime").JSX.Element;
13
+ export type { ChartDatum, ChartSeries } from './chart-data-table';
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Chart series palette (#385) — the SDK chart kit's single source of series
3
+ * color. Bakin renders dark-only (host index.html pins color-scheme: dark on
4
+ * a #0f0e0e surface), so this is the dark-surface categorical set, validated
5
+ * with the dataviz six-checks script (lightness band, chroma floor, adjacent
6
+ * CVD ΔE, ≥3:1 contrast on the dark surface).
7
+ *
8
+ * Rules baked in here (do not "fix" them):
9
+ * - The slot ORDER is the colorblind-safety mechanism — never reorder or
10
+ * cycle. It maximizes worst-case adjacent CVD separation.
11
+ * - Color follows the entity: assign via assignSeriesColors over the full
12
+ * entity set so a filter that drops series never repaints the survivors.
13
+ * - A 9th series is never a new hue — fold into "Other" (CHART_OTHER_COLOR).
14
+ */
15
+ export declare const CHART_SERIES_COLORS: readonly ["#3987e5", "#199e70", "#c98500", "#008300", "#9085e9", "#e66767", "#d55181", "#d95926"];
16
+ /** Muted, low-chroma gray for the folded "Other" series — never a hue slot. */
17
+ export declare const CHART_OTHER_COLOR = "#6b6963";
18
+ export declare const CHART_MAX_SERIES: 8;
19
+ /**
20
+ * Deterministic entity → color map: entities sorted, slots assigned in fixed
21
+ * order. Pass the FULL entity set (not the filtered view) so colors are
22
+ * stable across filters and windows.
23
+ */
24
+ export declare function assignSeriesColors(keys: string[]): Map<string, string>;
@@ -0,0 +1,12 @@
1
+ export interface SparklineProps {
2
+ values: number[];
3
+ width?: number;
4
+ height?: number;
5
+ stroke?: string;
6
+ /** Accessible description, e.g. "input tokens over the last 10 runs". */
7
+ label: string;
8
+ /** Optional human-readable labels for each value. */
9
+ labels?: string[];
10
+ formatValue?: (value: number) => string;
11
+ }
12
+ export declare function Sparkline({ values, width, height, stroke, label, labels, formatValue, }: SparklineProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,40 @@
1
+ /**
2
+ * StackedColumnChart (#385) — hand-rolled div-based stacked columns for the
3
+ * SDK chart kit. One column per x bucket, segments stacked by series with a
4
+ * 2px surface gap between fills, legend with click-to-toggle when there are
5
+ * ≥2 series (a single series needs no legend), and a per-column pointer and
6
+ * keyboard tooltip carrying the full breakdown. Series beyond the palette
7
+ * fold into a gray "Other" — a 9th hue is never generated.
8
+ */
9
+ import { type ReactNode } from 'react';
10
+ export interface StackedColumnDatum {
11
+ /** Bucket key (e.g. a YYYY-MM-DD day). */
12
+ x: string;
13
+ /** Short display label for the bucket; defaults to x. */
14
+ xLabel?: string;
15
+ /** Per-series values for this bucket (missing series = 0). */
16
+ values: Record<string, number>;
17
+ /** Per-series labels for intentionally absent exact-table cells. */
18
+ missingLabels?: Record<string, string>;
19
+ }
20
+ export interface StackedColumnChartProps {
21
+ data: StackedColumnDatum[];
22
+ /** Series that should stay discoverable even when every value is missing. */
23
+ seriesKeys?: readonly string[];
24
+ /** Accessible name for the plot. */
25
+ label?: string;
26
+ /** Accessible name for the exact-values disclosure. */
27
+ dataLabel?: string;
28
+ /** Bucket keys that are still accumulating data. */
29
+ partialKeys?: readonly string[];
30
+ /** Plot height in px (columns area, excluding legend). */
31
+ height?: number;
32
+ formatValue?: (n: number) => string;
33
+ /** Exact-table label for a missing series value; defaults to formatted zero. */
34
+ missingValue?: ReactNode;
35
+ /** Plot/tooltip label for a bucket with no reported series values. */
36
+ missingBucketLabel?: string;
37
+ /** Shown when data is empty — honest empty state, never a fake chart. */
38
+ emptyLabel?: string;
39
+ }
40
+ export declare function StackedColumnChart({ data, seriesKeys, label, dataLabel, partialKeys, height, formatValue, missingValue, missingBucketLabel, emptyLabel, }: StackedColumnChartProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,54 @@
1
+ import { type ReactNode } from 'react';
2
+ export interface ConfirmDialogProps {
3
+ /** Whether the dialog is shown. Controlled by the caller (e.g. `open={!!target}`). */
4
+ open: boolean;
5
+ title: ReactNode;
6
+ /** Body copy. Rendered inside DialogDescription (a `<p>`) — pass inline content; use `<span className="block">` for secondary lines. */
7
+ description?: ReactNode;
8
+ /** Confirm button label (default "Delete"). */
9
+ confirmLabel?: string;
10
+ /** Confirm label while busy (default = confirmLabel); a spinner is prepended. */
11
+ busyLabel?: string;
12
+ /** Cancel button label (default "Cancel"). */
13
+ cancelLabel?: string;
14
+ /** Cancel button variant (default "outline"). */
15
+ cancelVariant?: 'outline' | 'ghost';
16
+ /**
17
+ * Confirm button variant (default "destructive"). Non-destructive
18
+ * confirm flows (repair, switch-with-preview) pass "default" so a
19
+ * healing action doesn't render as a red warning.
20
+ */
21
+ confirmVariant?: 'destructive' | 'default';
22
+ /** Disables both buttons and shows a spinner on confirm while the action is in flight. */
23
+ busy?: boolean;
24
+ /** Inline error shown above the footer. */
25
+ error?: string | null;
26
+ /** Test id forwarded to the confirm button. */
27
+ confirmTestId?: string;
28
+ /** DialogContent className override (default width is `sm:max-w-sm`). */
29
+ className?: string;
30
+ /**
31
+ * Typed confirmation: when set, an input is rendered and the confirm button
32
+ * stays disabled until the user types this exact value. For the truly
33
+ * destructive actions where one click is too easy.
34
+ */
35
+ confirmValue?: string;
36
+ /** Label above the typed-confirmation input (default: `Type "<confirmValue>" to confirm`). */
37
+ confirmPrompt?: ReactNode;
38
+ /**
39
+ * Optional body content between the description and the typed-confirmation
40
+ * input — for the options an action needs decided at confirm time
41
+ * (checkboxes, a preview trigger). Keeps action configuration IN the
42
+ * dialog instead of inline on the page.
43
+ */
44
+ children?: ReactNode;
45
+ onConfirm: () => void;
46
+ onCancel: () => void;
47
+ }
48
+ /**
49
+ * A controlled confirmation dialog for destructive actions — the consolidation of
50
+ * six near-identical hand-rolled delete dialogs. The caller owns visibility (`open`)
51
+ * and the busy/error state of the in-flight action; the dialog never closes itself
52
+ * while `busy` so an action can't be cancelled mid-flight.
53
+ */
54
+ export declare function ConfirmDialog({ open, title, description, confirmLabel, busyLabel, cancelLabel, cancelVariant, confirmVariant, busy, error, confirmTestId, className, confirmValue, confirmPrompt, children, onConfirm, onCancel, }: ConfirmDialogProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,15 @@
1
+ import type { ConversationToolCall } from './fold';
2
+ export declare function formatDuration(ms: number | undefined): string;
3
+ export declare function humanizeActivity(calls: ConversationToolCall[]): string;
4
+ export declare function ToolCallRow({ call, onOpen, }: {
5
+ call: ConversationToolCall;
6
+ onOpen?: (call: ConversationToolCall) => void;
7
+ }): import("react/jsx-runtime").JSX.Element;
8
+ export interface ActivityGroupProps {
9
+ calls: ConversationToolCall[];
10
+ /** Row click-through to the detail surface (ToolCallDrawer). */
11
+ onOpenCall?: (call: ConversationToolCall) => void;
12
+ /** Start expanded (default collapsed). */
13
+ defaultExpanded?: boolean;
14
+ }
15
+ export declare function ActivityGroup({ calls, onOpenCall, defaultExpanded }: ActivityGroupProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,36 @@
1
+ import type { ConversationToolCall, ConversationTurn } from './fold';
2
+ export declare function TurnTimestamp({ ts }: {
3
+ ts?: string;
4
+ }): import("react/jsx-runtime").JSX.Element | null;
5
+ export declare function CopyButton({ text, label }: {
6
+ text: string;
7
+ label?: string;
8
+ }): import("react/jsx-runtime").JSX.Element;
9
+ /**
10
+ * Standalone avatar + shimmer row for surfaces that render the indicator
11
+ * outside an AgentTurn. Inside a turn the shimmer renders under the header.
12
+ */
13
+ export declare function ThinkingIndicator({ agentId, label }: {
14
+ agentId?: string;
15
+ label?: string;
16
+ }): import("react/jsx-runtime").JSX.Element;
17
+ export interface AgentTurnProps {
18
+ turn: Extract<ConversationTurn, {
19
+ kind: 'agent';
20
+ }>;
21
+ /** Fallback author when the turn doesn't carry its own agentId. */
22
+ agentId?: string;
23
+ /** Re-send the last user message; renders "Try again" on error turns. */
24
+ onRetry?: () => void;
25
+ /** Tool-call row click-through (detail drawer). */
26
+ onOpenCall?: (call: ConversationToolCall) => void;
27
+ /**
28
+ * Hook for surfaces that post-process assistant text (e.g. the brainstorm
29
+ * proposal stripper). Returns the text to render plus optional extra nodes.
30
+ */
31
+ transformText?: (text: string) => {
32
+ text: string;
33
+ extras?: React.ReactNode;
34
+ };
35
+ }
36
+ export declare function AgentTurn({ turn, agentId, onRetry, onOpenCall, transformText }: AgentTurnProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Conversation attention rules — ONE set of pure decisions for every
3
+ * conversational surface's badge provider (#703): what a turn's done/error
4
+ * means given where the user is looking. Providers execute the returned
5
+ * actions (toast/sound/OS notification/seen); this module never touches
6
+ * the DOM so the rules stay unit-testable. Generalized verbatim from the
7
+ * chat plugin's attention module (chat re-exports from here).
8
+ *
9
+ * Suppression rules (chat spec S6, now kit-wide):
10
+ * - Reply lands while the user is VIEWING that thread → no toast, no
11
+ * sound, no OS notification (the conversation itself is the signal);
12
+ * unread is cleared (the view fires seen).
13
+ * - Reply lands elsewhere in the app → toast + sound; the OS notification
14
+ * is also requested — sendBrowserNotification suppresses itself when
15
+ * the tab has focus, so it only fires when the user is in another app.
16
+ * - Aborted turns notify nothing — the user stopped it themselves.
17
+ */
18
+ export interface ConversationDonePayload {
19
+ /** The thread key (chat: chatId; projects: projectId; …). */
20
+ key: string;
21
+ agentId: string;
22
+ preview?: string;
23
+ aborted?: boolean;
24
+ }
25
+ export interface ConversationAttentionContext {
26
+ /** The thread currently open in the UI, '' when none. */
27
+ visibleKey: string;
28
+ settings: {
29
+ sound: boolean;
30
+ toasts: boolean;
31
+ };
32
+ }
33
+ export interface AttentionActions {
34
+ toast: boolean;
35
+ sound: boolean;
36
+ /** Ask browser-notify (it self-suppresses while the tab is focused). */
37
+ browserNotification: boolean;
38
+ /** The user is looking at the thread — mark it seen instead of unread. */
39
+ markSeen: boolean;
40
+ }
41
+ export declare function attentionForDone(payload: ConversationDonePayload, ctx: ConversationAttentionContext): AttentionActions;
42
+ /**
43
+ * The entity id the user is currently viewing, derived from a
44
+ * `<base>/<id>` URL path (list and excluded ids — e.g. a `/new` draft
45
+ * route — view no conversation, so they never suppress attention).
46
+ */
47
+ export declare function visibleIdFromLocation(pathname: string, base: string, opts?: {
48
+ exclude?: readonly string[];
49
+ }): string;
50
+ /** Nav badge from unread totals + in-flight turns: count wins, dot while working. */
51
+ export declare function badgeFor(totalUnread: number, inflightCount: number): {
52
+ count?: number;
53
+ tone: 'attention' | 'info';
54
+ } | null;
55
+ /** `(N) ` tab-title prefix management (idempotent). */
56
+ export declare function withUnreadPrefix(title: string, totalUnread: number): string;
@@ -0,0 +1,35 @@
1
+ export interface ComposerAttachmentItem {
2
+ id: string;
3
+ name: string;
4
+ previewUrl?: string;
5
+ /** 'uploading' renders a progress chip; absent/'ready' renders the thumbnail. */
6
+ status?: 'uploading' | 'ready';
7
+ }
8
+ export interface ComposerAttachments {
9
+ /** Whether this agent/model accepts image input (capability-gated by the caller). */
10
+ enabled: boolean;
11
+ /** Honest explanation shown on the disabled affordance. */
12
+ disabledReason?: string;
13
+ items: ComposerAttachmentItem[];
14
+ onAdd: (files: File[]) => void;
15
+ onRemove: (id: string) => void;
16
+ }
17
+ export interface ComposerProps {
18
+ /** Thread identity: keys drafts, history, and the resize persistence. */
19
+ storageKey: string;
20
+ onSend: (content: string) => void | Promise<void>;
21
+ /** A turn is streaming: send is held (typing stays live), stop shows. */
22
+ busy?: boolean;
23
+ onAbort?: () => void;
24
+ /** Hard-disabled surface (read-only/archived). */
25
+ disabled?: boolean;
26
+ placeholder?: string;
27
+ maxLength?: number;
28
+ attachments?: ComposerAttachments;
29
+ /** Rendered left of the textarea (e.g. an agent switcher). */
30
+ leadingSlot?: React.ReactNode;
31
+ autoFocus?: boolean;
32
+ minHeight?: number;
33
+ maxHeight?: number;
34
+ }
35
+ export declare function Composer({ storageKey, onSend, busy, onAbort, disabled, placeholder, maxLength, attachments, leadingSlot, autoFocus, minHeight, maxHeight, }: ComposerProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,8 @@
1
+ export interface ConversationEmptyStateProps {
2
+ icon?: React.ReactNode;
3
+ title: string;
4
+ description?: string;
5
+ suggestions?: string[];
6
+ onSuggestion?: (suggestion: string) => void;
7
+ }
8
+ export declare function ConversationEmptyState({ icon, title, description, suggestions, onSuggestion, }: ConversationEmptyStateProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,33 @@
1
+ import type { ChatChunk as RuntimeChatChunk } from '../../../core/adapters/runtime';
2
+ import { type ComposerAttachments } from './composer';
3
+ import { type ConversationMessage } from './fold';
4
+ import type { AgentTurnProps } from './agent-turn';
5
+ export interface ConversationPanelProps {
6
+ /** Persisted rows (the caller owns storage; map local shapes onto ConversationMessage). */
7
+ messages: ConversationMessage[];
8
+ /** In-flight turn chunks (from useConversationThread); null/undefined when idle. */
9
+ liveChunks?: RuntimeChatChunk[] | null;
10
+ streaming?: boolean;
11
+ agentId?: string;
12
+ /** Renders an agent switcher next to the composer. */
13
+ onAgentChange?: (agentId: string) => void;
14
+ onSend: (content: string) => void | Promise<void>;
15
+ onAbort?: () => void;
16
+ onRetry?: AgentTurnProps['onRetry'];
17
+ transformText?: AgentTurnProps['transformText'];
18
+ /** Keys drafts/history/resize persistence. */
19
+ storageKey: string;
20
+ title?: React.ReactNode;
21
+ /** Default true; embedded surfaces with their own chrome pass false. */
22
+ showHeader?: boolean;
23
+ /** Fill the host container instead of a fixed resizable height. */
24
+ fitParent?: boolean;
25
+ readOnly?: boolean;
26
+ readOnlyNotice?: React.ReactNode;
27
+ placeholder?: string;
28
+ emptyState?: React.ReactNode;
29
+ maxLength?: number;
30
+ attachments?: ComposerAttachments;
31
+ className?: string;
32
+ }
33
+ export declare function ConversationPanel({ messages, liveChunks, streaming, agentId, onAgentChange, onSend, onAbort, onRetry, transformText, storageKey, title, showHeader, fitParent, readOnly, readOnlyNotice, placeholder, emptyState, maxLength, attachments, className, }: ConversationPanelProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,14 @@
1
+ import { type AgentTurnProps } from './agent-turn';
2
+ import type { ConversationTurn } from './fold';
3
+ export interface ConversationProps {
4
+ turns: ConversationTurn[];
5
+ /** Fallback author for agent turns that don't carry their own agentId. */
6
+ agentId?: string;
7
+ /** Rendered centered when there are no turns (use ConversationEmptyState). */
8
+ emptyState?: React.ReactNode;
9
+ onRetry?: AgentTurnProps['onRetry'];
10
+ onOpenCall?: AgentTurnProps['onOpenCall'];
11
+ transformText?: AgentTurnProps['transformText'];
12
+ className?: string;
13
+ }
14
+ export declare function Conversation({ turns, agentId, emptyState, onRetry, onOpenCall, transformText, className, }: ConversationProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,129 @@
1
+ /**
2
+ * foldConversation — THE single folding engine for conversation surfaces.
3
+ *
4
+ * Consumes persisted `ConversationMessage` rows plus the in-flight turn's
5
+ * raw `RuntimeChatChunk`s and produces the renderable turn model
6
+ * (`ConversationTurn[]`). Every conversational surface (chat plugin,
7
+ * embedded brainstorm panels, task/workflow turn output) folds through
8
+ * here — never hand-roll chunk heuristics in a component.
9
+ *
10
+ * Semantics (pinned by tests/sdk/conversation-fold.test.ts):
11
+ * - Item ORDER inside a turn is preserved: text and tool-activity items
12
+ * interleave in arrival order. Consecutive tool chunks group into ONE
13
+ * activity item; a text chunk closes the group and later tools start a
14
+ * new one.
15
+ * - Tool call/result pairs match by callId ACROSS group boundaries (a
16
+ * result settles its original call even if text arrived in between).
17
+ * A callId-less result closes the most recent RUNNING call of the same
18
+ * tool; an orphan result settles as its own call.
19
+ * - Consecutive same-format text chunks coalesce; a format change starts
20
+ * a new text item.
21
+ * - The newest status chunk is the streaming label. `done` → complete,
22
+ * `error` → error (with a typed error item). Aborted turns come from
23
+ * persisted `aborted` rows — the stream itself ends aborts with a clean
24
+ * `done` (runtime contract).
25
+ */
26
+ import type { ChatChunk as RuntimeChatChunk, ChatTextFormat } from '../../../core/adapters/runtime';
27
+ /** Attachment as displayed in a conversation (URL-addressed, not path). */
28
+ export interface DisplayAttachment {
29
+ name: string;
30
+ mimeType: string;
31
+ url: string;
32
+ }
33
+ /**
34
+ * One persisted conversation row — the kit's storable message shape.
35
+ * The chat plugin's transcript rows serialize to exactly this (plus its
36
+ * own storage concerns); embedded surfaces map their local shapes onto it.
37
+ * `turnId` groups the rows of one agent turn; rows without it (legacy)
38
+ * group by adjacency between user rows.
39
+ */
40
+ export type ConversationMessage = {
41
+ kind: 'user';
42
+ ts: string;
43
+ content: string;
44
+ attachments?: DisplayAttachment[];
45
+ } | {
46
+ kind: 'assistant';
47
+ ts: string;
48
+ turnId?: string;
49
+ agentId?: string;
50
+ content: string;
51
+ } | {
52
+ kind: 'tool';
53
+ ts: string;
54
+ turnId?: string;
55
+ agentId?: string;
56
+ callId?: string;
57
+ toolName: string;
58
+ status?: 'running' | 'completed' | 'failed' | string;
59
+ summary?: string;
60
+ inputPreview?: string;
61
+ outputPreview?: string;
62
+ durationMs?: number;
63
+ metadata?: Record<string, unknown>;
64
+ } | {
65
+ kind: 'error';
66
+ ts: string;
67
+ turnId?: string;
68
+ message: string;
69
+ errorKind?: string;
70
+ } | {
71
+ kind: 'aborted';
72
+ ts: string;
73
+ turnId?: string;
74
+ };
75
+ /** One tool invocation inside an activity group. */
76
+ export interface ConversationToolCall {
77
+ /** Stable render key (callId when present). */
78
+ key: string;
79
+ callId?: string;
80
+ toolName: string;
81
+ status: 'running' | 'completed' | 'failed';
82
+ summary?: string;
83
+ inputPreview?: string;
84
+ outputPreview?: string;
85
+ durationMs?: number;
86
+ metadata?: Record<string, unknown>;
87
+ }
88
+ export type TurnItem = {
89
+ type: 'text';
90
+ format: ChatTextFormat;
91
+ content: string;
92
+ } | {
93
+ type: 'activity';
94
+ calls: ConversationToolCall[];
95
+ } | {
96
+ type: 'error';
97
+ message: string;
98
+ errorKind?: string;
99
+ };
100
+ export type TurnStatus = 'streaming' | 'complete' | 'error' | 'aborted';
101
+ export type ConversationTurn = {
102
+ kind: 'user';
103
+ key: string;
104
+ ts: string;
105
+ content: string;
106
+ attachments?: DisplayAttachment[];
107
+ } | {
108
+ kind: 'agent';
109
+ key: string;
110
+ ts?: string;
111
+ /** Author agent, when known (multi-agent embedded threads switch mid-conversation). */
112
+ agentId?: string;
113
+ items: TurnItem[];
114
+ status: TurnStatus;
115
+ /** Latest runtime status label ('thinking', …) — meaningful while streaming. */
116
+ statusLabel?: string;
117
+ };
118
+ export interface FoldOptions {
119
+ /** Raw chunks of the in-flight turn; presence (even empty) appends a streaming turn. */
120
+ liveChunks?: readonly RuntimeChatChunk[];
121
+ /** Author of the live turn, when known. */
122
+ liveAgentId?: string;
123
+ }
124
+ /**
125
+ * Fold persisted rows + optional live chunks into the renderable turn list.
126
+ * Pure — same inputs, same output (keys are derived from row position, so
127
+ * they're stable across re-folds).
128
+ */
129
+ export declare function foldConversation(messages: readonly ConversationMessage[], opts?: FoldOptions): ConversationTurn[];
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Reply chime — a soft two-tone WebAudio blip shared by every
3
+ * conversational surface's attention provider (moved from the chat plugin
4
+ * in #703; chat re-exports from here). Generated, not an asset: zero
5
+ * bundle weight, no file to embed, and the volume stays deliberately low
6
+ * (this is a nudge, not an alarm).
7
+ */
8
+ export declare function playReplyChime(): void;
@@ -0,0 +1,8 @@
1
+ /** Compact relative timestamps for conversation surfaces ('now', '5m', '3h', '2d', then a date). */
2
+ export declare function formatRelativeTime(iso: string, now?: number): string;
3
+ /** Full timestamp for tooltips. */
4
+ export declare function formatAbsoluteTime(iso: string): string;
5
+ /** Day-separator label ('Jul 10, 2026'). */
6
+ export declare function formatDayLabel(iso: string): string;
7
+ /** Calendar-day bucket for separator comparisons (local time). */
8
+ export declare function dayKey(iso: string | undefined): string;