plotagents 0.5.0 → 0.8.0

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 (67) hide show
  1. package/AGENTS.md +29 -5
  2. package/README.md +44 -15
  3. package/bin/plotagents.js +40 -14
  4. package/dist/plotagents-geo.js +1 -1
  5. package/dist/plotagents.js +6161 -757
  6. package/docs/api.md +23 -5
  7. package/docs/charts.md +229 -10
  8. package/docs/colorscales.md +46 -0
  9. package/docs/dashboards.md +79 -0
  10. package/docs/es/agents.md +102 -0
  11. package/docs/es/api.md +172 -0
  12. package/docs/es/charts.md +436 -0
  13. package/docs/es/colorscales.md +46 -0
  14. package/docs/es/dashboards.md +79 -0
  15. package/docs/es/getting-started.md +142 -0
  16. package/docs/es/rendering.md +47 -0
  17. package/docs/es/themes.md +116 -0
  18. package/docs/getting-started.md +6 -2
  19. package/docs/themes.md +39 -9
  20. package/index.d.ts +275 -20
  21. package/package.json +11 -4
  22. package/schema.json +1382 -53
  23. package/skills/plotagents/SKILL.md +105 -0
  24. package/src/axes.js +11 -3
  25. package/src/charts/bar.js +40 -21
  26. package/src/charts/categorical.js +31 -7
  27. package/src/charts/chord.js +6 -4
  28. package/src/charts/choropleth.js +287 -37
  29. package/src/charts/corr.js +512 -0
  30. package/src/charts/dist.js +39 -21
  31. package/src/charts/donut.js +4 -2
  32. package/src/charts/gantt.js +460 -0
  33. package/src/charts/heatmap.js +2 -2
  34. package/src/charts/kpi.js +11 -8
  35. package/src/charts/line.js +187 -43
  36. package/src/charts/network.js +557 -189
  37. package/src/charts/pointmap.js +602 -0
  38. package/src/charts/radar.js +7 -1
  39. package/src/charts/regplot.js +16 -4
  40. package/src/charts/sankey.js +42 -6
  41. package/src/charts/scatter.js +103 -23
  42. package/src/charts/sunburst.js +7 -6
  43. package/src/charts/table.js +882 -0
  44. package/src/charts/treemap.js +12 -9
  45. package/src/charts/wordcloud.js +177 -0
  46. package/src/colorscales.js +193 -0
  47. package/src/dashboard.js +451 -0
  48. package/src/dashed.js +1 -1
  49. package/src/data.js +4 -2
  50. package/src/facet.js +4 -3
  51. package/src/format.js +80 -25
  52. package/src/frame.js +101 -29
  53. package/src/geo/projection.js +76 -9
  54. package/src/geo/registry.js +87 -8
  55. package/src/hierarchy.js +6 -0
  56. package/src/i18n.js +107 -0
  57. package/src/index.js +92 -14
  58. package/src/infer.js +18 -1
  59. package/src/interact.js +157 -36
  60. package/src/lint.js +353 -11
  61. package/src/runtime.js +301 -101
  62. package/src/scale.js +82 -11
  63. package/src/schema.js +235 -36
  64. package/src/stats.js +76 -17
  65. package/src/svg.js +4 -1
  66. package/src/text.js +5 -0
  67. package/src/theme.js +101 -14
package/index.d.ts CHANGED
@@ -5,15 +5,46 @@ export type ChartType =
5
5
  | 'regplot' | 'residplot' | 'jointplot' | 'hist' | 'kde' | 'ecdf'
6
6
  | 'box' | 'violin' | 'strip' | 'swarm' | 'point' | 'radar'
7
7
  | 'treemap' | 'sunburst' | 'donut' | 'pie' | 'heatmap' | 'sankey' | 'kpi'
8
+ | 'network' | 'chord' | 'pyramid' | 'flowchart' | 'gantt' | 'wordcloud' | 'choropleth' | 'symbolmap' | 'pointmap' | 'table' | 'corr' | 'pairplot'
8
9
  // Aliases (seaborn and others)
9
10
  | 'barplot' | 'countplot' | 'lineplot' | 'scatterplot' | 'histplot' | 'kdeplot' | 'ecdfplot'
10
- | 'lmplot' | 'boxplot' | 'violinplot' | 'stripplot' | 'swarmplot' | 'beeswarm' | 'pointplot' | 'spider';
11
+ | 'lmplot' | 'boxplot' | 'violinplot' | 'stripplot' | 'swarmplot' | 'beeswarm' | 'pointplot' | 'spider'
12
+ | 'timeline' | 'roadmap' | 'schedule' | 'cronograma' | 'map' | 'mapa' | 'tabla' | 'datatable'
13
+ | 'correlation' | 'corrplot' | 'clustermap' | 'pairs' | 'splom' | 'scattermatrix';
14
+
15
+ export type Locale = 'es' | 'en' | 'pt' | 'fr' | 'de' | 'auto';
16
+
17
+ /** table: one column. A bare field name infers everything. */
18
+ export interface TableColumn {
19
+ field?: string;
20
+ label?: string;
21
+ /** Indicator. Inferred when omitted: bar on the main measure, delta on change fields, sparkline on lists of numbers, progress on 0–1 goals, badge on status words, check on booleans. */
22
+ type?: 'text' | 'number' | 'bar' | 'heat' | 'delta' | 'sparkline' | 'progress' | 'badge' | 'check' | 'date' | 'link' | 'rank';
23
+ format?: Format;
24
+ align?: 'left' | 'right' | 'center';
25
+ width?: number;
26
+ /** delta/progress: whether up is good (default) or down (costs). */
27
+ good?: 'up' | 'down';
28
+ /** progress: field or number to compare against. */
29
+ target?: string | number;
30
+ /** heat: matplotlib colormap or colors. */
31
+ colorScale?: string | string[] | { name?: string; colors?: string[]; reverse?: boolean; mid?: number };
32
+ /** Totals row for this column. */
33
+ total?: boolean | 'sum' | 'mean' | 'min' | 'max' | 'count';
34
+ /** Text: lines before truncating (default 2, 3 for long text). */
35
+ lines?: number;
36
+ /** link: field with the text shown instead of the URL. */
37
+ text?: string;
38
+ /** badge: { value: "#hex" }. */
39
+ colors?: Record<string, string>;
40
+ sortable?: boolean;
41
+ }
11
42
 
12
43
  export type Row = Record<string, string | number | Date | null | undefined>;
13
44
 
14
45
  export type Format =
15
46
  | 'number' | 'compact' | 'percent' | 'currency' | 'integer'
16
- | { type?: string; prefix?: string; suffix?: string; decimals?: number; currency?: string; scale?: number };
47
+ | { type?: 'number' | 'compact' | 'percent' | 'currency' | 'integer'; prefix?: string; suffix?: string; /** 0–20. */ decimals?: number; currency?: string; scale?: number };
17
48
 
18
49
  export interface KpiItem {
19
50
  label: string;
@@ -49,8 +80,31 @@ export interface Theme {
49
80
  }
50
81
 
51
82
  type DeepPartial<T> = { [K in keyof T]?: T[K] extends object ? (T[K] extends any[] ? T[K] | string : DeepPartial<T[K]>) : T[K] };
52
- /** JSON theme: deep-merged over `extends` (default "papel"). */
53
- export type ThemeInput = 'papel' | 'noche' | 'light' | 'dark' | (DeepPartial<Theme> & { extends?: 'papel' | 'noche' })
83
+ /** Simple theme tokens, mapped onto the full theme. */
84
+ export interface ThemeTokens {
85
+ /** Alias of surface. */
86
+ background?: string;
87
+ /** Alias of ink. */
88
+ text?: string;
89
+ /** First series color. */
90
+ accent?: string;
91
+ /** Grid color, or { color, dash, width }. */
92
+ grid?: string | { color?: string; dash?: string; width?: number };
93
+ axis?: string;
94
+ tooltip?: { bg?: string; ink?: string };
95
+ /** Corner radius of bars and tiles. */
96
+ radius?: number;
97
+ barRadius?: number;
98
+ font?: string | { family?: string; mono?: string; import?: string };
99
+ }
100
+ /** JSON theme: deep-merged over `extends` (default "papel"). Strings: built-in or registerTheme() names. */
101
+ export type ThemeInput = 'papel' | 'noche' | 'light' | 'dark' | (string & {}) | (Omit<DeepPartial<Theme>, 'grid' | 'font'> & ThemeTokens & { extends?: 'papel' | 'noche' | (string & {}) })
102
+
103
+ /** matplotlib colormap name (case-insensitive, `_r` reverses), a list of hex colors, or { name | colors, reverse, mid }. */
104
+ export type ColorScale = string | string[] | { name?: string; colors?: string[]; reverse?: boolean; mid?: number };
105
+ export type LegendPosition = 'top' | 'bottom' | 'left' | 'right';
106
+ export type TileProvider = 'osm' | 'esri-gray' | 'esri-dark' | 'carto-light' | 'carto-dark' | 'mapbox-light' | 'mapbox-dark';
107
+ export type NetworkLayout = 'force' | 'circular' | 'radial' | 'concentric' | 'clusters' | 'tree' | 'grid' | 'circle';
54
108
 
55
109
  export interface Spec {
56
110
  type?: ChartType;
@@ -75,7 +129,7 @@ export interface Spec {
75
129
  yFormat?: Format;
76
130
  stack?: boolean | 'percent';
77
131
  horizontal?: boolean;
78
- sort?: 'desc' | 'asc' | 'none' | 'alpha';
132
+ sort?: 'desc' | 'asc' | 'none' | 'alpha' | 'start';
79
133
  top?: number;
80
134
  highlight?: string | string[];
81
135
  /** Dashed shapes (hatched fill + dashed outline): names, a data field, { field, equals } or true. */
@@ -86,10 +140,10 @@ export interface Spec {
86
140
  dashedLabel?: string | false;
87
141
  labels?: boolean | 'auto' | number | string[];
88
142
  labelsFor?: Record<string, string>;
89
- refLines?: RefLine[];
143
+ refLines?: RefLine[] | RefLine;
90
144
  annotations?: Annotation[];
91
145
  index?: boolean;
92
- curve?: 'linear' | 'smooth';
146
+ curve?: 'linear' | 'smooth' | 'step';
93
147
  zero?: boolean;
94
148
  points?: boolean;
95
149
  xScale?: 'linear' | 'log';
@@ -100,6 +154,7 @@ export interface Spec {
100
154
  aggregate?: 'sum' | 'mean' | 'max' | 'min' | 'count' | 'last' | 'first';
101
155
  colors?: Record<string, string>;
102
156
  theme?: ThemeInput;
157
+ /** Palette name ("okabe-ito", "tab10", "Set2"…, or any colormap, sampled) or a list of colors. */
103
158
  palette?: string | string[];
104
159
  ramp?: string | string[];
105
160
  hue?: string;
@@ -110,8 +165,6 @@ export interface Spec {
110
165
  panelHeight?: number;
111
166
  time?: string;
112
167
  timeValue?: string | number;
113
- slider?: boolean;
114
- play?: boolean;
115
168
  compare?: 'previous' | 'first' | string | number | false;
116
169
  compareData?: Row[];
117
170
  colorBy?: 'group' | 'change' | 'label';
@@ -141,15 +194,42 @@ export interface Spec {
141
194
  lowess?: boolean;
142
195
  logx?: boolean;
143
196
  annotate?: boolean;
197
+ /** jointplot: center plot. pairplot: "reg" adds a fit line to every scatter panel. */
144
198
  kind?: 'scatter' | 'reg';
199
+ /** corr/pairplot: numeric fields to relate (default: all numeric; pairplot: first 6). */
200
+ vars?: string[];
201
+ /** corr: "pearson" (default) or "spearman". */
202
+ method?: 'pearson' | 'spearman';
203
+ /** corr: "lower" (default) or "full" (default with `cluster`). */
204
+ triangle?: 'lower' | 'full' | boolean;
205
+ /** corr: hierarchical clustering order + dendrogram (clustermap). */
206
+ cluster?: boolean;
207
+ dendrogram?: boolean;
208
+ /** corr: grey out cells with p ≥ alpha. */
209
+ alpha?: number;
210
+ cellSize?: number;
211
+ /** pairplot: diagonal panels ("kde" by default with hue). */
212
+ diag?: 'hist' | 'kde';
213
+ /** pairplot: above the diagonal. */
214
+ upper?: 'corr' | 'scatter' | false;
215
+ corner?: boolean;
216
+ panelSize?: number;
145
217
  marginal?: 'hist' | 'kde';
146
- inner?: 'box' | 'quartiles' | 'points' | 'none';
218
+ inner?: 'box' | 'quartiles' | 'points' | 'stick' | 'none';
147
219
  split?: boolean;
148
220
  axis?: string;
149
221
  axes?: string[];
150
222
  normalize?: boolean;
151
- legend?: boolean;
152
- locale?: 'es' | 'en';
223
+ /** Legend on/off or position (default top; left/right fall back to bottom under 520px). */
224
+ legend?: boolean | LegendPosition | { position?: LegendPosition };
225
+ legendTitle?: string;
226
+ /** Drop legend entries (series, first level, group); colors stay fixed and the entries stay in the legend, faded. */
227
+ exclude?: string | string[];
228
+ /** Continuous color scale. Aliases: cmap, colormap. */
229
+ colorScale?: ColorScale;
230
+ cmap?: ColorScale;
231
+ colormap?: ColorScale;
232
+ locale?: Locale;
153
233
  width?: number;
154
234
  height?: number;
155
235
  padding?: number;
@@ -161,11 +241,136 @@ export interface Spec {
161
241
  centerLabel?: string;
162
242
  midpoint?: number;
163
243
  diverging?: boolean;
164
- /** choropleth/symbolmap: "chile" (default), "usa", "world", a registered name or a GeoJSON FeatureCollection. */
165
- geo?: 'chile' | 'usa' | 'world' | string | object;
244
+ /** choropleth/symbolmap: "chile" (default), "usa", "world", a registered name, your own GeoJSON (FeatureCollection, Feature, Feature[] or geometry) or TopoJSON. In the browser, render() also accepts a URL. */
245
+ geo?: 'chile' | 'usa' | 'world' | string | object | object[];
246
+ /** TopoJSON: object to draw (default: the first). */
247
+ geoObject?: string;
166
248
  key?: string;
167
- projection?: 'mercator' | 'equalEarth' | 'albersUsa';
168
- columns?: number;
249
+ /** Feature property matched against `key` (auto-detected when omitted). */
250
+ featureKey?: string;
251
+ /** Feature property with the display name. */
252
+ nameKey?: string;
253
+ projection?: 'mercator' | 'equalEarth' | 'albersUsa' | 'equirectangular' | 'conic' | 'identity' | 'planar' | { type: string; parallels?: [number, number]; rotate?: number; center?: [number, number] };
254
+ /** Zoom to regions, a [lonMin, latMin, lonMax, latMax] box, or "markers". */
255
+ fitTo?: string | string[] | [number, number, number, number];
256
+ markers?: Array<{ lon: number; lat: number; label?: string; value?: number; color?: string }> | { data: Row[]; lon?: string; lat?: string; label?: string; size?: string; color?: string; legend?: string; maxRadius?: number; radius?: number; labels?: boolean };
257
+ layers?: Array<{ geo: object | string; label?: string; stroke?: string; width?: number; fill?: string; dash?: boolean | string; opacity?: number; below?: boolean; object?: string }>;
258
+ borderColor?: string;
259
+ borderWidth?: number;
260
+ pointRadius?: number;
261
+ /** network: node rows (id, group, size). flowchart: steps (id, label, type, lane). */
262
+ nodes?: Row[];
263
+ /** flowchart: connections (from, to, label). Same as `data`. */
264
+ edges?: Row[];
265
+ layout?: NetworkLayout;
266
+ /** network: edge curvature, 0 straight (default 0.3). */
267
+ curveness?: number;
268
+ nodeId?: string;
269
+ nodeLabel?: string;
270
+ /** Largest node / circle radius in px. */
271
+ maxRadius?: number;
272
+ /** network: force-layout iterations. */
273
+ iterations?: number;
274
+ /** chord: square flow matrix with `names`. */
275
+ matrix?: number[][];
276
+ names?: string[];
277
+ directed?: boolean;
278
+ ribbonColor?: 'source' | 'smaller' | 'larger';
279
+ labelOrientation?: 'horizontal' | 'radial';
280
+ direction?: 'TB' | 'LR';
281
+ /** pyramid */
282
+ age?: string;
283
+ sex?: string;
284
+ percent?: boolean;
285
+ /** pointmap: tile basemap with lat/lon dots. */
286
+ lat?: string;
287
+ lon?: string;
288
+ tiles?: TileProvider | { url: string; attribution?: string; subdomains?: string; maxZoom?: number; retina?: boolean } | false;
289
+ /** Public token / API key for the tile provider (a secret Mapbox "sk." token is rejected). */
290
+ tilesKey?: string;
291
+ tileStyle?: 'muted' | 'original';
292
+ tileOpacity?: number;
293
+ zoom?: number;
294
+ /** [lon, lat] */
295
+ center?: [number, number];
296
+ /** choropleth */
297
+ missing?: 'hatch' | 'plain';
298
+ thresholds?: number[];
299
+ classes?: number;
300
+ scale?: 'quantile' | 'equal' | 'continuous' | 'categorical' | number[] | string;
301
+ values?: boolean;
302
+ tall?: boolean;
303
+ /** Seaborn-style options */
304
+ orient?: 'v' | 'h';
305
+ valueDomain?: [number, number];
306
+ bandwidth?: number;
307
+ bwAdjust?: number;
308
+ cut?: number;
309
+ jitter?: number | boolean;
310
+ dodge?: boolean;
311
+ hueOrder?: string[];
312
+ showMeans?: boolean;
313
+ cumulative?: boolean;
314
+ rug?: boolean;
315
+ complementary?: boolean;
316
+ radius?: number;
317
+ endLabels?: boolean;
318
+ /** treemap/sunburst */
319
+ showValues?: boolean;
320
+ hole?: number;
321
+ thickness?: number;
322
+ cellHeight?: number;
323
+ facetOrder?: string[];
324
+ /** gantt */
325
+ task?: string;
326
+ start?: string;
327
+ end?: string;
328
+ duration?: string;
329
+ progress?: string;
330
+ dependsOn?: string;
331
+ milestone?: string;
332
+ today?: string | number | boolean;
333
+ groupHeaders?: boolean | 'compact';
334
+ rowHeight?: number;
335
+ /** gantt: phases drawn collapsed into a summary row; true for all. Click toggles in the browser. */
336
+ collapsed?: boolean | string | string[];
337
+ collapsible?: boolean;
338
+ /** gantt: highlight the zero-slack chain along dependsOn. */
339
+ critical?: boolean;
340
+ criticalColor?: string;
341
+ /** gantt: shade weekends on day plans of up to 120 days (default true). */
342
+ weekends?: boolean;
343
+ todayColor?: string;
344
+ /** Browser time controls, off by default: true (buttons or slider), "buttons" or "slider". */
345
+ slider?: boolean | 'buttons' | 'slider';
346
+ play?: boolean;
347
+ /** wordcloud: words field, or raw text to count. */
348
+ text?: string | string[];
349
+ textField?: string;
350
+ /** facet/kpi: panels or tiles per row. table: the columns. */
351
+ columns?: number | Array<string | TableColumn>;
352
+ /** table: column to sort by (field or label). */
353
+ sortBy?: string;
354
+ sortOrder?: 'asc' | 'desc';
355
+ /** table: rows per page (default: all up to 15, then 10). false shows every row. */
356
+ pageSize?: number | false;
357
+ page?: number;
358
+ /** table: keep rows containing these words (accent- and case-insensitive). */
359
+ query?: string;
360
+ /** table: browser search box (default: on above 20 rows). */
361
+ search?: boolean;
362
+ /** table: totals row. */
363
+ total?: boolean | 'sum' | 'mean' | 'min' | 'max' | Record<string, string | boolean>;
364
+ totalLabel?: string;
365
+ /** table: "#" column with the position. */
366
+ rank?: boolean;
367
+ /** table: one card per row. "auto" (default) when the columns do not fit. */
368
+ cards?: boolean | 'auto';
369
+ density?: 'compact' | 'normal' | 'comfortable';
370
+ striped?: boolean;
371
+ /** table: false disables the automatic data bar. */
372
+ bars?: boolean;
373
+ sortable?: boolean;
169
374
  [key: string]: unknown;
170
375
  }
171
376
 
@@ -194,19 +399,69 @@ export declare function resolve(spec: Spec): Spec;
194
399
  export declare const schema: Record<string, unknown>;
195
400
  /** Library-wide defaults (font, textScale, locale, theme, palette…). The spec always wins. `configure(null)` resets. */
196
401
  export declare function configure(options?: Partial<Spec> | null): Partial<Spec>;
197
- export declare function registerGeo(name: string, featureCollection: object, aliases?: string[]): object;
402
+ export interface DashboardSpec {
403
+ title?: string; subtitle?: string; source?: string; updated?: string; note?: string;
404
+ locale?: Locale; theme?: Spec['theme']; font?: Spec['font']; palette?: string | string[];
405
+ data?: Row[];
406
+ kpis?: Array<{ label: string; value?: number; delta?: number; period?: string; previous?: number; display?: string; trend?: number[]; good?: 'up' | 'down'; format?: Format;
407
+ field?: string; agg?: 'sum' | 'mean' | 'median' | 'min' | 'max' | 'count' | 'distinct' | 'ratio'; over?: string; scale?: number;
408
+ compare?: { field: string; current: string | number; previous: string | number }; trendBy?: string }>;
409
+ /** Optional when there are `kpis`. */
410
+ charts?: Array<Spec & { primary?: boolean; size?: 'full' | 'large' | 'medium' | 'small'; span?: number }>;
411
+ filters?: Array<string | { field: string; label?: string; control?: 'buttons' | 'select'; value?: string }>;
412
+ layout?: 'auto' | 'executive' | 'grid';
413
+ colors?: Record<string, string>;
414
+ /** "given" keeps the charts in the order written (otherwise the main time series goes first). */
415
+ order?: 'given';
416
+ ramp?: string | string[];
417
+ textScale?: number;
418
+ }
419
+ /** Self-contained HTML dashboard with best-practice layout, shared colors, KPIs and filters. */
420
+ export declare function dashboard(spec: DashboardSpec): string;
421
+ /** Never throws: { ok, html, plan, errors, warnings, suggestions }. */
422
+ export declare function safeDashboard(spec: DashboardSpec): { ok: boolean; html: string | null; plan: object | null; errors: Issue[]; warnings: Issue[]; suggestions: Issue[] };
423
+ export declare function lintDashboard(spec: DashboardSpec): { ok: boolean; errors: Issue[]; warnings: Issue[]; suggestions: Issue[] };
424
+ export declare function planDashboard(spec: DashboardSpec): object;
425
+ /** Browser: draws a dashboard into an element. */
426
+ /** Browser: wires the filters and charts of a dashboard already in the DOM. */
427
+ export declare function mountDashboard(root: Element, plan: object): { plan: object; update(): void; destroy(): void };
428
+ export declare function packRows(spans: number[]): Array<Array<{ i: number; span: number }>>;
429
+ export declare function balancedRows(spans: number[], hasPrimary?: boolean): Array<Array<{ i: number; span: number }>>;
430
+ export declare function renderDashboard(target: string | Element, spec: DashboardSpec): { update(): void; destroy(): void };
431
+ export declare const dashboardSchema: Record<string, unknown>;
432
+ /** Raw text → [{ text, value }] word counts without stopwords. */
433
+ export declare function countWords(text: string | string[], opts?: { minLength?: number; stopwords?: string[] }): { text: string; value: number }[];
434
+ export declare function getGeo(geo: string | object, objectName?: string): object;
435
+ export declare function registeredGeo(): string[];
436
+ export declare function registerGeo(name: string, geo: object, aliases?: string[]): object;
437
+ /** Any GeoJSON / TopoJSON shape → FeatureCollection. */
438
+ export declare function toFeatureCollection(geo: object | object[], objectName?: string): object;
439
+ /** Browser: downloads (once per URL) a GeoJSON or TopoJSON. */
440
+ export declare function loadGeo(url: string): Promise<object>;
198
441
  export declare const palettes: Record<string, string[]>;
199
442
  export declare const ramps: Record<string, string[]>;
200
443
  export declare function themeFor(spec: Spec): Theme;
201
444
  export declare function timeValues(spec: Spec): (string | number)[];
202
445
  export declare function validatePalette(colors: string[], opts?: { mode?: 'light' | 'dark'; surface?: string; pairs?: 'adjacent' | 'all' }): { ok: boolean; checks: { name: string; status: 'pass' | 'warn' | 'fail'; detail: string }[] };
203
- export declare function bundleSource(): string | null;
204
- export declare function toolDefinition(opts?: { name?: string; flavor?: 'anthropic' | 'openai' }): Record<string, unknown>;
205
- export declare const themes: Record<'papel' | 'noche' | 'light' | 'dark', Theme>;
446
+ export declare function bundleSource(file?: string): string | null;
447
+ export declare function toolDefinition(opts?: { name?: string; flavor?: 'anthropic' | 'openai'; kind?: 'chart' | 'dashboard' }): Record<string, unknown>;
448
+ export declare const themes: Record<'papel' | 'noche' | 'light' | 'dark', Theme> & Record<string, Theme>;
206
449
  export declare function getTheme(t?: Spec['theme']): Theme;
450
+ /** Registers a named theme (merged over `extends`, default papel); use it as theme: "name" or configure({ theme: "name" }). */
451
+ export declare function registerTheme(name: string, theme: ThemeInput): Theme;
452
+ /** Resolves a color scale to its stops, or null when the name is unknown. */
453
+ export declare function resolveColorScale(v: ColorScale): { name: string; stops: string[]; kind: 'sequential' | 'diverging' | 'cyclic' | 'qualitative' } | null;
454
+ /** Available colormap and palette names by kind. */
455
+ export declare function colorScaleNames(): { sequential: string[]; diverging: string[]; cyclic: string[]; qualitative: string[] };
456
+ /** Color at t ∈ [0, 1] along `stops` (OKLab). */
457
+ export declare function interpolateColor(stops: string[], t: number): string;
458
+ export declare const COLORMAPS: Record<string, string>;
459
+ export declare const QUALITATIVE: Record<string, string>;
207
460
  export declare const TYPES: ChartType[];
208
461
  export declare function squarify<T extends { value: number }>(items: T[], x: number, y: number, w: number, h: number): (T & { x: number; y: number; w: number; h: number })[];
209
462
  export declare function makeFormat(fmt?: Format, locale?: string, values?: number[]): ((v: number) => string) & { type: string };
463
+ /** Most likely language of some texts ('es' | 'en' | 'pt' | 'fr' | 'de'), or null. */
464
+ export declare function detectLocale(texts: string | string[]): 'es' | 'en' | 'pt' | 'fr' | 'de' | null;
210
465
  export declare function formatNumber(v: number, decimals?: number, locale?: string, trim?: boolean): string;
211
466
  export declare function formatCompact(v: number, locale?: string, decimals?: number): string;
212
467
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "plotagents",
3
- "version": "0.5.0",
4
- "description": "Beautiful charts from one JSON spec, built for AI agents: bars, lines, multi-level treemaps, sunbursts, sankeys and seaborn-style plots (regplot, hist, kde, box, violin…). Accessible SVG, time sliders, JSON themes, zero dependencies.",
3
+ "version": "0.8.0",
4
+ "description": "The chart protocol for AI agents: one JSON spec in, a finished accessible SVG out. Bars, lines, Gantt charts, treemaps, sankeys, maps from any GeoJSON/TopoJSON, networks and seaborn-style plots. Zero dependencies.",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
7
7
  "module": "./src/index.js",
@@ -25,6 +25,7 @@
25
25
  "src",
26
26
  "dist",
27
27
  "docs",
28
+ "skills",
28
29
  "bin",
29
30
  "index.d.ts",
30
31
  "schema.json",
@@ -38,7 +39,7 @@
38
39
  "bench": "node scripts/bench.js",
39
40
  "prepublishOnly": "node scripts/bundle.js && node --test test/*.test.js",
40
41
  "examples": "node examples/build.js",
41
- "site": "node scripts/build-site.js",
42
+ "site": "node scripts/build-site.js && node scripts/build-site.js --lang es",
42
43
  "schema": "node -e \"import('./src/index.js').then(m=>process.stdout.write(JSON.stringify(m.schema,null,2)))\" > schema.json"
43
44
  },
44
45
  "keywords": [
@@ -57,7 +58,13 @@
57
58
  "ai",
58
59
  "agents",
59
60
  "llm",
60
- "tool-use"
61
+ "tool-use",
62
+ "gantt",
63
+ "timeline",
64
+ "geojson",
65
+ "topojson",
66
+ "choropleth",
67
+ "map"
61
68
  ],
62
69
  "author": "Carlos Navarrete <cnavarreteliz@gmail.com>",
63
70
  "license": "MIT",