@rho-workspace/rho 0.5.5 → 0.5.7

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 (250) hide show
  1. package/dist/agent-connect.d.ts +42 -0
  2. package/dist/agent-connect.js +68 -0
  3. package/dist/answer-board.js +3 -3
  4. package/dist/bridge.js +6 -1
  5. package/dist/browser-access.d.ts +1 -0
  6. package/dist/browser-access.js +5 -3
  7. package/dist/capabilities.d.ts +21 -5
  8. package/dist/capabilities.js +6 -4
  9. package/dist/cli.js +113 -18
  10. package/dist/composition.d.ts +1 -1
  11. package/dist/composition.js +13 -3
  12. package/dist/connect-cli.d.ts +50 -0
  13. package/dist/connect-cli.js +128 -0
  14. package/dist/contract.generated.d.ts +1437 -381
  15. package/dist/contract.generated.js +1 -1
  16. package/dist/contracts/owners.generated.js +1160 -267
  17. package/dist/conversation-presentation.d.ts +9 -2
  18. package/dist/conversation-presentation.js +3 -1
  19. package/dist/conversations.d.ts +306 -7
  20. package/dist/conversations.js +208 -22
  21. package/dist/discovery.js +3 -3
  22. package/dist/extension-contract.d.ts +19 -0
  23. package/dist/extension-contract.js +15 -6
  24. package/dist/extension-markets.d.ts +74 -0
  25. package/dist/extension-markets.js +166 -0
  26. package/dist/extensions.d.ts +29 -1
  27. package/dist/extensions.js +13 -4
  28. package/dist/external-work.d.ts +22 -0
  29. package/dist/external-work.js +91 -0
  30. package/dist/plugin-cli.js +75 -3
  31. package/dist/plugin-inventory.d.ts +56 -0
  32. package/dist/plugin-inventory.js +41 -0
  33. package/dist/plugin-inventory.json +1581 -102
  34. package/dist/plugin-presentation.d.ts +105 -2
  35. package/dist/plugin-presentation.js +59 -5
  36. package/dist/plugins.d.ts +14 -3
  37. package/dist/plugins.js +12 -6
  38. package/dist/project-notes.js +1 -1
  39. package/dist/protocol.d.ts +7 -0
  40. package/dist/protocol.js +40 -15
  41. package/dist/replay.js +4 -0
  42. package/dist/response-contracts.js +26 -11
  43. package/dist/running.d.ts +10 -0
  44. package/dist/running.js +45 -0
  45. package/dist/server.d.ts +4 -10
  46. package/dist/server.js +140 -14
  47. package/dist/state.d.ts +8 -0
  48. package/dist/state.js +8 -0
  49. package/dist/studio-layout.js +3 -3
  50. package/dist/task-frame.d.ts +1 -1
  51. package/dist/timeline-events.d.ts +1 -0
  52. package/dist/timeline-events.js +8 -1
  53. package/dist/ui-context.d.ts +73 -0
  54. package/dist/ui-context.js +98 -0
  55. package/dist/ui-contract.d.ts +23 -0
  56. package/dist/web/.vite/manifest.json +135 -76
  57. package/dist/web/assets/answer-board-CeYS8k8y.js +1 -0
  58. package/dist/web/assets/choices-D8vGwsl2.js +1 -0
  59. package/dist/web/assets/{console-BSjLGe0T.js → console-Dyuo1q4N.js} +4 -4
  60. package/dist/web/assets/{dist-Tzoe_zm-.js → dist-CSiCyBml.js} +1 -1
  61. package/dist/web/assets/{dist-Cw8hRIlT.js → dist-D9FLb9Hm.js} +1 -1
  62. package/dist/web/assets/{dist-foH9IKc6.js → dist-FXbTBwML.js} +1 -1
  63. package/dist/web/assets/{dist-Buk0lwzI.js → dist-l3DUhbw5.js} +1 -1
  64. package/dist/web/assets/{explore-in-BVUy3ZW_.js → explore-in-BfSFGRh2.js} +1 -1
  65. package/dist/web/assets/graph-BU2_o5uA.js +2 -0
  66. package/dist/web/assets/index-C16mXVvk.css +1 -0
  67. package/dist/web/assets/index-CWg9XYXx.js +952 -0
  68. package/dist/web/assets/markdown.reader-Ct2-e2Zt.png +0 -0
  69. package/dist/web/assets/{notes-meaning-pVbbQUGP.js → notes-meaning-T2m5zQfv.js} +1 -1
  70. package/dist/web/assets/overview-PzfLJCo-.js +6 -0
  71. package/dist/web/assets/preview-BguEdsza.js +1 -0
  72. package/dist/web/assets/previews-pWNik-2g.js +3 -0
  73. package/dist/web/assets/{review-CMxQlQ-C.js → review-Dy_85lcH.js} +1 -1
  74. package/dist/web/assets/rho.editor-CCJeyHma.png +0 -0
  75. package/dist/web/assets/rho.flow-WkMj6fRS.png +0 -0
  76. package/dist/web/assets/rho.media-Cc6amodO.png +0 -0
  77. package/dist/web/assets/rho.notebook-6vsZKGDq.png +0 -0
  78. package/dist/web/assets/rho.object-BGoeXjte.png +0 -0
  79. package/dist/web/assets/rho.plots-yIiISCkb.png +0 -0
  80. package/dist/web/assets/rho.scatter-DwHxesCs.png +0 -0
  81. package/dist/web/assets/rho.servers-DKf_mnNq.png +0 -0
  82. package/dist/web/assets/rho.table-DWOGaWDa.png +0 -0
  83. package/dist/web/assets/rho.variables-CKcWczhQ.png +0 -0
  84. package/dist/web/assets/{skills-BFNSyrnD.js → skills-Dyz7mBlc.js} +1 -1
  85. package/dist/web/assets/{skills-work-BGPSnF_I.js → skills-work-BEGqlCkx.js} +1 -1
  86. package/dist/web/assets/studio-process-D-ykbC4D.js +2 -0
  87. package/dist/web/assets/timeline-events-DKTho9fU.js +1 -0
  88. package/dist/web/assets/work-turns-DSabCogR.js +1 -0
  89. package/dist/web/assets/{workspace-CWlkjLNx.js → workspace-DfjBL--r.js} +2 -2
  90. package/dist/web/composition.json +135 -80
  91. package/dist/web/index.html +3 -3
  92. package/dist/web/renderer.json +1 -1
  93. package/dist/web-assets.js +2 -2
  94. package/dist/work-graph.d.ts +11 -1
  95. package/dist/work-graph.js +16 -5
  96. package/dist/workspace.d.ts +2 -2
  97. package/dist/workspace.js +8 -7
  98. package/docs/FRONTEND.md +71 -21
  99. package/docs/HEADLESS.md +127 -24
  100. package/docs/THIRD-PARTY-PLUGINS.md +75 -3
  101. package/node_modules/@rho-workspace/plugin-agent/README.md +34 -0
  102. package/node_modules/@rho-workspace/plugin-agent/dist/acp-command.d.ts +32 -0
  103. package/node_modules/@rho-workspace/plugin-agent/dist/acp-command.js +54 -11
  104. package/node_modules/@rho-workspace/plugin-agent/dist/acp-conversation.d.ts +1 -0
  105. package/node_modules/@rho-workspace/plugin-agent/dist/acp-conversation.js +29 -3
  106. package/node_modules/@rho-workspace/plugin-agent/dist/external-session-contract.js +11 -5
  107. package/node_modules/@rho-workspace/plugin-agent/dist/external-session.d.ts +12 -1
  108. package/node_modules/@rho-workspace/plugin-agent/dist/index.d.ts +8 -0
  109. package/node_modules/@rho-workspace/plugin-agent/dist/index.js +3 -2
  110. package/node_modules/@rho-workspace/plugin-agent/dist/mcp-entry.d.ts +13 -0
  111. package/node_modules/@rho-workspace/plugin-agent/dist/mcp-entry.js +13 -0
  112. package/node_modules/@rho-workspace/plugin-agent/dist/mcp.js +16 -8
  113. package/node_modules/@rho-workspace/plugin-agent/dist/native-sessions.d.ts +70 -0
  114. package/node_modules/@rho-workspace/plugin-agent/dist/native-sessions.js +538 -0
  115. package/node_modules/@rho-workspace/plugin-agent/package.json +2 -1
  116. package/node_modules/@rho-workspace/plugin-figures/LICENSE +661 -0
  117. package/node_modules/@rho-workspace/plugin-figures/README.md +191 -0
  118. package/node_modules/@rho-workspace/plugin-figures/dist/index.d.ts +236 -0
  119. package/node_modules/@rho-workspace/plugin-figures/dist/index.js +165 -0
  120. package/node_modules/@rho-workspace/plugin-figures/dist/operations.d.ts +44 -0
  121. package/node_modules/@rho-workspace/plugin-figures/dist/operations.js +39 -0
  122. package/node_modules/@rho-workspace/plugin-figures/dist/presentation.d.ts +19 -0
  123. package/node_modules/@rho-workspace/plugin-figures/dist/presentation.js +26 -0
  124. package/node_modules/@rho-workspace/plugin-figures/dist/record.d.ts +188 -0
  125. package/node_modules/@rho-workspace/plugin-figures/dist/record.js +143 -0
  126. package/node_modules/@rho-workspace/plugin-figures/dist/ui-styles.d.ts +1 -0
  127. package/node_modules/@rho-workspace/plugin-figures/dist/ui-styles.js +68 -0
  128. package/node_modules/@rho-workspace/plugin-figures/dist/ui.d.ts +56 -0
  129. package/node_modules/@rho-workspace/plugin-figures/dist/ui.js +363 -0
  130. package/node_modules/@rho-workspace/plugin-figures/package.json +41 -0
  131. package/node_modules/@rho-workspace/plugin-figures/py/figures.py +856 -0
  132. package/node_modules/@rho-workspace/plugin-figures/r/figures.R +775 -0
  133. package/node_modules/@rho-workspace/plugin-kernel/README.md +27 -3
  134. package/node_modules/@rho-workspace/plugin-kernel/dist/contract.d.ts +12 -0
  135. package/node_modules/@rho-workspace/plugin-kernel/dist/contract.js +8 -1
  136. package/node_modules/@rho-workspace/plugin-kernel/dist/index.d.ts +61 -0
  137. package/node_modules/@rho-workspace/plugin-kernel/dist/index.js +125 -9
  138. package/node_modules/@rho-workspace/plugin-kernel/dist/session-scope.d.ts +14 -0
  139. package/node_modules/@rho-workspace/plugin-kernel/dist/session-scope.js +9 -0
  140. package/node_modules/@rho-workspace/plugin-kernel/dist/ui-base.d.ts +23 -5
  141. package/node_modules/@rho-workspace/plugin-kernel/dist/ui-notebook-work.js +1 -1
  142. package/node_modules/@rho-workspace/plugin-kernel/dist/ui-notebook.d.ts +6 -4
  143. package/node_modules/@rho-workspace/plugin-kernel/dist/ui-notebook.js +44 -17
  144. package/node_modules/@rho-workspace/plugin-kernel/dist/ui-styles.js +6 -0
  145. package/node_modules/@rho-workspace/plugin-kernel/package.json +1 -1
  146. package/node_modules/@rho-workspace/plugin-kernel/runners/runner.R +144 -4
  147. package/node_modules/@rho-workspace/plugin-kernel/runners/runner.py +106 -1
  148. package/node_modules/@rho-workspace/plugin-tables/README.md +5 -0
  149. package/node_modules/@rho-workspace/plugin-tables/dist/index.d.ts +1 -0
  150. package/node_modules/@rho-workspace/plugin-tables/dist/index.js +19 -3
  151. package/node_modules/@rho-workspace/plugin-tables/dist/ui.js +1 -1
  152. package/node_modules/@rho-workspace/plugin-tables/package.json +1 -1
  153. package/node_modules/hono/dist/adapter/aws-lambda/handler.js +1 -1
  154. package/node_modules/hono/dist/cjs/adapter/aws-lambda/handler.js +1 -1
  155. package/node_modules/hono/dist/cjs/adapter/bun/serve-static.js +1 -1
  156. package/node_modules/hono/dist/cjs/adapter/bun/websocket.js +1 -1
  157. package/node_modules/hono/dist/cjs/client/fetch-result-please.js +1 -1
  158. package/node_modules/hono/dist/cjs/helper/accepts/accepts.js +2 -1
  159. package/node_modules/hono/dist/cjs/helper/ssg/ssg.js +5 -3
  160. package/node_modules/hono/dist/cjs/jsx/base.js +49 -30
  161. package/node_modules/hono/dist/cjs/jsx/components.js +2 -2
  162. package/node_modules/hono/dist/cjs/jsx/constants.js +2 -0
  163. package/node_modules/hono/dist/cjs/jsx/jsx-runtime.js +13 -17
  164. package/node_modules/hono/dist/cjs/middleware/etag/index.js +3 -1
  165. package/node_modules/hono/dist/cjs/middleware/pretty-json/index.js +1 -0
  166. package/node_modules/hono/dist/cjs/middleware/timing/timing.js +4 -3
  167. package/node_modules/hono/dist/cjs/utils/cookie.js +2 -2
  168. package/node_modules/hono/dist/cjs/utils/mime.js +1 -1
  169. package/node_modules/hono/dist/cjs/utils/url.js +1 -1
  170. package/node_modules/hono/dist/client/fetch-result-please.js +1 -1
  171. package/node_modules/hono/dist/helper/accepts/accepts.js +2 -1
  172. package/node_modules/hono/dist/helper/ssg/ssg.js +5 -3
  173. package/node_modules/hono/dist/jsx/base.js +49 -32
  174. package/node_modules/hono/dist/jsx/components.js +2 -2
  175. package/node_modules/hono/dist/jsx/constants.js +2 -1
  176. package/node_modules/hono/dist/jsx/jsx-runtime.js +15 -19
  177. package/node_modules/hono/dist/middleware/etag/index.js +3 -1
  178. package/node_modules/hono/dist/middleware/language/language.js +1 -1
  179. package/node_modules/hono/dist/middleware/pretty-json/index.js +1 -0
  180. package/node_modules/hono/dist/middleware/timing/timing.js +4 -3
  181. package/node_modules/hono/dist/utils/cookie.js +2 -2
  182. package/node_modules/hono/dist/utils/mime.js +1 -1
  183. package/node_modules/hono/dist/utils/url.js +1 -1
  184. package/node_modules/hono/package.json +1 -1
  185. package/node_modules/jose/dist/webapi/jwe/general/decrypt.js +3 -2
  186. package/node_modules/jose/dist/webapi/jwks/remote.js +1 -1
  187. package/node_modules/jose/dist/webapi/jws/general/verify.js +2 -8
  188. package/node_modules/jose/dist/webapi/lib/jwe_decrypt.js +11 -8
  189. package/node_modules/jose/dist/webapi/lib/key_management.js +0 -1
  190. package/node_modules/jose/package.json +1 -1
  191. package/package.json +6 -4
  192. package/protocol/index.json +106 -64
  193. package/protocol/operations/agent.sessions.list.json +57 -3
  194. package/protocol/operations/agent.sessions.read.json +61 -4
  195. package/protocol/operations/capability.list.json +382 -6
  196. package/protocol/operations/composition.apply.json +10 -2
  197. package/protocol/operations/composition.delete.json +845 -0
  198. package/protocol/operations/composition.read.json +10 -2
  199. package/protocol/operations/composition.undo.json +10 -2
  200. package/protocol/operations/conversation.agents.add.json +346 -0
  201. package/protocol/operations/conversation.agents.remove.json +340 -0
  202. package/protocol/operations/conversation.configure.json +29 -0
  203. package/protocol/operations/conversation.decide.json +225 -0
  204. package/protocol/operations/conversation.list.json +29 -0
  205. package/protocol/operations/conversation.permission.json +225 -0
  206. package/protocol/operations/conversation.read.json +225 -0
  207. package/protocol/operations/conversation.restore.json +29 -0
  208. package/protocol/operations/conversation.send.json +294 -0
  209. package/protocol/operations/conversation.settings.check.json +226 -416
  210. package/protocol/operations/conversation.settings.read.json +224 -411
  211. package/protocol/operations/conversation.settings.update.json +248 -475
  212. package/protocol/operations/conversation.start.json +313 -6
  213. package/protocol/operations/conversation.stop.json +225 -0
  214. package/protocol/operations/conversation.trash.json +29 -0
  215. package/protocol/operations/extension.describe.json +39 -0
  216. package/protocol/operations/extension.install.json +62 -0
  217. package/protocol/operations/extension.list.json +164 -1
  218. package/protocol/operations/extension.market.change.json +210 -0
  219. package/protocol/operations/figure.read.json +265 -0
  220. package/protocol/operations/figure.select.json +157 -0
  221. package/protocol/operations/kernel.interrupt.json +119 -0
  222. package/protocol/operations/kernel.read.json +119 -0
  223. package/protocol/operations/kernel.run.json +119 -0
  224. package/protocol/operations/observation.snapshot.json +445 -8
  225. package/protocol/operations/project.openFile.json +10 -2
  226. package/protocol/operations/session.grant.json +4 -0
  227. package/protocol/operations/session.instructions.json +43 -0
  228. package/protocol/operations/shared.json +1 -0
  229. package/protocol/operations/view.close.json +10 -2
  230. package/protocol/operations/view.protection.set.json +10 -2
  231. package/vendor/composition.json +174 -109
  232. package/vendor/rho-workspace-plugin-agent-0.4.33.tgz +0 -0
  233. package/vendor/rho-workspace-plugin-figures-0.5.1.tgz +0 -0
  234. package/vendor/rho-workspace-plugin-kernel-0.5.13.tgz +0 -0
  235. package/vendor/rho-workspace-plugin-tables-0.5.2.tgz +0 -0
  236. package/web/theme.css +17 -0
  237. package/dist/web/assets/answer-board-CBkGbSLD.js +0 -1
  238. package/dist/web/assets/canvas-D8rDdfDz.js +0 -1
  239. package/dist/web/assets/choices-b0XhrGQV.js +0 -1
  240. package/dist/web/assets/graph-1OdIJ9l7.js +0 -2
  241. package/dist/web/assets/index-CsC3sTRq.css +0 -1
  242. package/dist/web/assets/index-CxmItXqa.js +0 -891
  243. package/dist/web/assets/overview-B9UtVJ32.js +0 -6
  244. package/dist/web/assets/preview-CksD_5KS.js +0 -1
  245. package/dist/web/assets/studio-process-CsRoTHOh.js +0 -2
  246. package/dist/web/assets/timeline-events-BbuuFWHV.js +0 -1
  247. package/dist/web/assets/work-turns-BvJlIMmA.js +0 -1
  248. package/vendor/rho-workspace-plugin-agent-0.4.29.tgz +0 -0
  249. package/vendor/rho-workspace-plugin-kernel-0.5.5.tgz +0 -0
  250. package/vendor/rho-workspace-plugin-tables-0.5.0.tgz +0 -0
@@ -0,0 +1,39 @@
1
+ import { objectSchema as obj, text } from '@rho-workspace/plugin-contracts';
2
+ // Owner business contracts. Application project/authentication fields are separate.
3
+ // A figure is named by the Notebook cell that drew it and the plot's number in that cell, or, for a
4
+ // plot a cell saved to a project file (ggsave), by the file: its path, read as it is now, or the
5
+ // SHA-256 of its bytes. A mark is "L.M": layer L of the figure, built row M of that layer, both
6
+ // counted from 0.
7
+ const cellId = { type: 'string', pattern: '^k-[a-f0-9]{16}$' };
8
+ const plot = { type: 'integer', minimum: 1, maximum: 64 };
9
+ const filePath = { type: 'string', minLength: 1, maxLength: 512 };
10
+ const sha256 = { type: 'string', pattern: '^[a-f0-9]{64}$' };
11
+ const mark = { type: 'string', pattern: '^\\d{1,4}\\.\\d{1,7}$' };
12
+ export const selectionId = { type: 'string', pattern: '^f-[a-f0-9]{16}$' };
13
+ const changeId = { type: 'string', pattern: '^[A-Za-z0-9._:@-]{1,128}$' };
14
+ const cell = { anyOf: [{ type: 'string' }, { type: 'number' }, { type: 'boolean' }, { type: 'null' }] };
15
+ const where = obj({ column: { type: 'string', minLength: 1, maxLength: 256 }, op: { enum: ['eq', 'ne', 'lt', 'le', 'gt', 'ge', 'in', 'contains'] }, value: { anyOf: [cell, { type: 'array', items: cell, maxItems: 500 }] }, layer: { type: 'integer', minimum: 0 } }, ['column', 'op', 'value']);
16
+ export const selectionSchema = obj({
17
+ selectionId, cellId, plot, path: filePath, sha256, digest: { type: 'string', pattern: '^[a-f0-9]{64}$' }, by: text, at: text, changeId, note: { type: 'string' },
18
+ count: { type: 'integer', minimum: 0 }, layers: { type: 'array', items: obj({ layer: { type: 'integer', minimum: 0 }, geom: { type: 'string' }, marks: { type: 'integer', minimum: 0 } }) },
19
+ marks: { type: 'array', items: mark },
20
+ }, ['selectionId', 'cellId', 'digest', 'by', 'at', 'changeId', 'note', 'count', 'layers']);
21
+ export const operationContracts = {
22
+ // summary (the default) says what was drawn; view adds the whole record a page draws from;
23
+ // selections reads only the kept selections, with their marks.
24
+ // marks, selection or where name marks whose rows to return, at most limit of them.
25
+ 'figure.read': {
26
+ inputSchema: obj({ cellId, plot, path: filePath, sha256, form: { enum: ['summary', 'view', 'selections'] }, marks: { type: 'array', items: mark, maxItems: 5000 }, selection: selectionId,
27
+ where: { type: 'array', items: where, minItems: 1, maxItems: 8 }, limit: { type: 'integer', minimum: 1, maximum: 500 } }, []),
28
+ outputSchema: obj({ figure: { type: 'object' }, summary: { type: 'object' }, record: { type: 'object' }, selections: { type: 'array', items: selectionSchema },
29
+ rows: { type: 'array', items: { type: 'object' } }, rowsTotal: { type: 'integer', minimum: 0 }, matched: { type: 'object' } }, ['figure', 'selections']),
30
+ requires: [], effect: 'read',
31
+ },
32
+ // Keeps a set of marks with a note, by whoever chose them: the person's selection that goes with a
33
+ // message, or the marks an Agent points the person to. It changes neither the plot nor its data.
34
+ 'figure.select': {
35
+ inputSchema: obj({ cellId, plot, path: filePath, sha256, marks: { type: 'array', items: mark, minItems: 1, maxItems: 5000 }, note: { type: 'string', maxLength: 500 }, changeId }, ['marks', 'changeId']),
36
+ outputSchema: obj({ selection: selectionSchema }),
37
+ requires: [], effect: 'metadata',
38
+ },
39
+ };
@@ -0,0 +1,19 @@
1
+ import type { EntryPresentation, PluginPresentation } from '@rho-workspace/plugin-contracts';
2
+ export declare const presentation: PluginPresentation;
3
+ export declare const operationPresentation: {
4
+ 'figure.read': {
5
+ order: number;
6
+ displayName: string;
7
+ description: string;
8
+ readOnly: true;
9
+ runsCode: false;
10
+ };
11
+ 'figure.select': {
12
+ order: number;
13
+ displayName: string;
14
+ description: string;
15
+ readOnly: false;
16
+ runsCode: false;
17
+ };
18
+ };
19
+ export declare const skillPresentation: EntryPresentation;
@@ -0,0 +1,26 @@
1
+ export const presentation = {
2
+ categoryOrder: 20,
3
+ order: 15,
4
+ description: "A ggplot drawn in the project's live R session, by you or the Agent, is kept with every point, bar, box, line and label bound to the row of data it was drawn from. It works for any plot built on ggplot2 (ggtree, enrichplot, Seurat, patchwork and the rest) with no setup. Point at a mark to read its row, select marks by clicking or dragging, and ask the Agent about them: your message carries the exact rows. The Agent reads what a plot actually drew and can mark points for you with a note.",
5
+ icon: { "background": "#E8F2EE", "color": "#2F6B57", "paths": ["M4.5 19.5h15", "M4.5 19.5v-15", "M8 15.5a1.25 1.25 0 1 0 0-.01", "M12 10.5a1.25 1.25 0 1 0 0-.01", "M16.5 13a1.25 1.25 0 1 0 0-.01", "M14.5 6.5h5v5h-5z"] },
6
+ dependencies: [{ "pluginId": "kernel", "purpose": "to describe the plots its live R session draws" }],
7
+ developer: "Rho",
8
+ license: "AGPL-3.0-only",
9
+ links: [{ "label": "Source", "url": "https://github.com/YuLab-SMU/Rho-plugins/tree/main/plugins/figures" }, { "label": "Privacy", "url": "https://github.com/YuLab-SMU/Rho-plugins/blob/main/PRIVACY.md" }],
10
+ displayName: 'Figures',
11
+ tagline: 'Plots whose marks know their data',
12
+ category: 'Figures & media',
13
+ examplePrompts: [
14
+ '“Draw the volcano plot in the notebook; I will select the genes I care about.”',
15
+ '“What do the points I selected have in common?”',
16
+ '“Mark the genes in this plot with padj below 0.01 and say why they stand out.”',
17
+ '“Did the last plot drop any rows? Check what it actually drew.”',
18
+ ],
19
+ viewNote: 'In the Notebook and Plots, on every ggplot',
20
+ readOnly: false, runsCode: false,
21
+ };
22
+ export const operationPresentation = {
23
+ 'figure.read': { order: 10, displayName: 'Read a figure', description: "Reads what a plot drew: its layers, mappings, panels and data, the rows behind marks, and the marks people selected.", readOnly: true, runsCode: false },
24
+ 'figure.select': { order: 20, displayName: 'Mark points in a figure', description: "Keeps a set of marks with a note, shown highlighted in the plot. It changes neither the plot nor its data.", readOnly: false, runsCode: false },
25
+ };
26
+ export const skillPresentation = { displayName: 'Figures', description: 'Teaches the Agent to read what a plot drew, the rows behind its marks and the person\'s selections, and to point at marks.' };
@@ -0,0 +1,188 @@
1
+ export type Cell = string | number | boolean | null;
2
+ export interface FigureColumn {
3
+ name: string;
4
+ type: 'number' | 'integer' | 'text' | 'logical' | 'list';
5
+ values: Cell[];
6
+ }
7
+ export interface FigureSource {
8
+ id: string;
9
+ rows: number;
10
+ columnsTotal: number;
11
+ key: string | null;
12
+ index: number[];
13
+ columns: FigureColumn[];
14
+ }
15
+ export interface FigureLayer {
16
+ plot: number;
17
+ layer: number;
18
+ geom: string;
19
+ stat: string;
20
+ position: string;
21
+ mapping: Record<string, string>;
22
+ constants: Record<string, string | number>;
23
+ source: string | null;
24
+ marks: number;
25
+ units: number;
26
+ bound: 'mark' | 'group' | 'none';
27
+ unbound?: string[];
28
+ notes?: string[];
29
+ }
30
+ export interface FigureMarks {
31
+ panel: number[];
32
+ group: number[];
33
+ row: number[] | null;
34
+ columns: FigureColumn[];
35
+ }
36
+ export interface FigureUnit {
37
+ layer: number;
38
+ panel: number;
39
+ marks: number[][];
40
+ }
41
+ export interface FigureScale {
42
+ aesthetic: string;
43
+ title: string;
44
+ breaks: string[];
45
+ values: string[];
46
+ }
47
+ export interface FigurePlot {
48
+ plot: number;
49
+ title?: string | null;
50
+ subtitle?: string | null;
51
+ caption?: string | null;
52
+ labels: Record<string, string>;
53
+ panels: Array<{
54
+ panel: number;
55
+ facets: Record<string, string>;
56
+ }>;
57
+ facet: string;
58
+ coord: string;
59
+ scales: FigureScale[];
60
+ positions: Partial<Record<'x' | 'y', {
61
+ discrete: boolean;
62
+ levels?: string[];
63
+ range?: number[];
64
+ }>>;
65
+ }
66
+ export interface FigureRecord {
67
+ schema: 'rho.figure/1';
68
+ describer: string;
69
+ size: {
70
+ width: number;
71
+ height: number;
72
+ units: string;
73
+ };
74
+ versions: Record<string, string>;
75
+ seconds: number;
76
+ svg: string;
77
+ problems: string[];
78
+ units: FigureUnit[];
79
+ figure: {
80
+ kind: string;
81
+ title?: string | null;
82
+ plots: FigurePlot[];
83
+ layers: FigureLayer[];
84
+ };
85
+ marks: FigureMarks[];
86
+ sources: FigureSource[];
87
+ }
88
+ export declare function parseRecord(bytes: Uint8Array | string): FigureRecord;
89
+ export interface MarkRef {
90
+ layer: number;
91
+ mark: number;
92
+ }
93
+ export declare const markName: (m: MarkRef) => string;
94
+ export declare function parseMark(name: string): MarkRef | null;
95
+ export declare function elementMarks(record: FigureRecord, attribute: string): MarkRef[];
96
+ export interface MarkRow {
97
+ mark: string;
98
+ layer: number;
99
+ geom: string;
100
+ plot: number;
101
+ facets: Record<string, string>;
102
+ built: Record<string, Cell>;
103
+ source?: string;
104
+ row?: number;
105
+ key?: {
106
+ column: string;
107
+ value: Cell;
108
+ };
109
+ values?: Record<string, Cell>;
110
+ }
111
+ export declare function markRow(record: FigureRecord, ref: MarkRef): MarkRow | null;
112
+ export type Op = 'eq' | 'ne' | 'lt' | 'le' | 'gt' | 'ge' | 'in' | 'contains';
113
+ export interface Where {
114
+ column: string;
115
+ op: Op;
116
+ value: Cell | Cell[];
117
+ layer?: number;
118
+ }
119
+ export declare function matchMarks(record: FigureRecord, where: Where[], maximum: number): {
120
+ marks: MarkRef[];
121
+ total: number;
122
+ };
123
+ export declare function figureSummary(record: FigureRecord): {
124
+ describer: string;
125
+ kind: string;
126
+ title: string | null;
127
+ size: {
128
+ width: number;
129
+ height: number;
130
+ units: string;
131
+ };
132
+ versions: Record<string, string>;
133
+ plots: {
134
+ plot: number;
135
+ title: string | null;
136
+ subtitle: string | null;
137
+ labels: Record<string, string>;
138
+ facet: string;
139
+ coord: string;
140
+ panels: number;
141
+ facets: Record<string, string>[] | undefined;
142
+ scales: {
143
+ aesthetic: string;
144
+ title: string;
145
+ breaks: string[];
146
+ }[];
147
+ positions: {
148
+ [k: string]: {
149
+ discrete: boolean;
150
+ levels: string[] | undefined;
151
+ levelCount: number | undefined;
152
+ range?: undefined;
153
+ } | {
154
+ discrete: boolean;
155
+ range: number[] | undefined;
156
+ levels?: undefined;
157
+ levelCount?: undefined;
158
+ };
159
+ };
160
+ }[];
161
+ layers: {
162
+ builtColumns: string[];
163
+ notes?: string[] | undefined;
164
+ notBound?: string[] | undefined;
165
+ layer: number;
166
+ plot: number;
167
+ geom: string;
168
+ stat: string;
169
+ position: string;
170
+ mapping: Record<string, string>;
171
+ constants: Record<string, string | number>;
172
+ source: string | null;
173
+ marks: number;
174
+ bound: "mark" | "group" | "none";
175
+ }[];
176
+ sources: {
177
+ id: string;
178
+ rows: number;
179
+ rowsWithMarks: number;
180
+ key: string | null;
181
+ columns: {
182
+ name: string;
183
+ type: "number" | "integer" | "text" | "logical" | "list";
184
+ }[];
185
+ columnsTotal: number;
186
+ }[];
187
+ problems: string[];
188
+ };
@@ -0,0 +1,143 @@
1
+ // A figure record as an R describer wrote it (r/figures.R): the picture as SVG whose drawn
2
+ // elements name the marks they stand for, each layer's built marks, and the rows of the plot's
3
+ // data those marks came from. Nothing here interprets a plot; it reads what was bound.
4
+ //
5
+ // A mark is named "L.M": layer L of the figure (counted from 0 over every plot of a
6
+ // composition) and built row M of that layer (from 0). A drawn element of unit U names itself
7
+ // data-rho="U.E": element E of the unit stands for the marks the unit lists at E (one row, or a
8
+ // group such as one box or one line).
9
+ // jsonlite writes a list or an empty named list as [], and some vectors of one as a scalar.
10
+ const list = (v) => Array.isArray(v) ? v : v === null || v === undefined ? [] : [v];
11
+ const named = (v) => v && typeof v === 'object' && !Array.isArray(v) ? v : {};
12
+ const columns = (v) => list(v).map(c => ({ name: String(c.name), type: c.type, values: list(c.values) }));
13
+ export function parseRecord(bytes) {
14
+ const raw = JSON.parse(typeof bytes === 'string' ? bytes : new TextDecoder().decode(bytes));
15
+ if (raw?.schema !== 'rho.figure/1' || typeof raw.svg !== 'string')
16
+ throw new Error('This is not a figure record this version reads.');
17
+ return {
18
+ ...raw, problems: list(raw.problems),
19
+ units: list(raw.units).map(u => ({ layer: u.layer, panel: u.panel, marks: list(u.marks).map(m => list(m)) })),
20
+ figure: {
21
+ ...raw.figure,
22
+ plots: list(raw.figure?.plots).map(p => ({ ...p, labels: named(p.labels), panels: list(p.panels).map(x => ({ panel: x.panel, facets: named(x.facets) })),
23
+ scales: list(p.scales).map(s => ({ ...s, breaks: list(s.breaks), values: list(s.values) })), positions: named(p.positions) })),
24
+ layers: list(raw.figure?.layers).map(l => ({ ...l, mapping: named(l.mapping), constants: named(l.constants), unbound: l.unbound ? list(l.unbound) : undefined, notes: l.notes ? list(l.notes) : undefined })),
25
+ },
26
+ marks: list(raw.marks).map(m => ({ panel: list(m.panel), group: list(m.group), row: m.row === null || m.row === undefined ? null : list(m.row), columns: columns(m.columns) })),
27
+ sources: list(raw.sources).map(s => ({ ...s, key: s.key ?? null, index: list(s.index), columns: columns(s.columns) })),
28
+ };
29
+ }
30
+ export const markName = (m) => `${m.layer}.${m.mark}`;
31
+ export function parseMark(name) {
32
+ const m = /^(\d{1,4})\.(\d{1,7})$/.exec(name);
33
+ return m ? { layer: Number(m[1]), mark: Number(m[2]) } : null;
34
+ }
35
+ // The marks one drawn element stands for.
36
+ export function elementMarks(record, attribute) {
37
+ const m = /^(\d+)\.(\d+)$/.exec(attribute);
38
+ if (!m)
39
+ return [];
40
+ const unit = record.units[Number(m[1])];
41
+ return (unit?.marks[Number(m[2])] ?? []).map(mark => ({ layer: unit.layer, mark }));
42
+ }
43
+ // The source row a mark came from, as its position in the source and in the kept rows.
44
+ function sourceRow(record, ref) {
45
+ const layer = record.figure.layers[ref.layer], marks = record.marks[ref.layer];
46
+ if (!layer?.source || !marks?.row)
47
+ return null;
48
+ const source = record.sources.find(s => s.id === layer.source);
49
+ const row = marks.row[ref.mark];
50
+ if (!source || row === undefined)
51
+ return null;
52
+ // index is sorted: the rows of the source that some mark stands for.
53
+ let lo = 0, hi = source.index.length - 1;
54
+ while (lo <= hi) {
55
+ const mid = (lo + hi) >> 1, v = source.index[mid];
56
+ if (v === row)
57
+ return { source, row, at: mid };
58
+ if (v < row)
59
+ lo = mid + 1;
60
+ else
61
+ hi = mid - 1;
62
+ }
63
+ return { source, row, at: -1 };
64
+ }
65
+ const valueAt = (column, at) => at >= 0 ? column.values[at] ?? null : null;
66
+ export function markRow(record, ref) {
67
+ const layer = record.figure.layers[ref.layer], marks = record.marks[ref.layer];
68
+ if (!layer || !marks || ref.mark < 0 || ref.mark >= layer.marks)
69
+ return null;
70
+ const plot = record.figure.plots.find(p => p.plot === layer.plot);
71
+ const panel = marks.panel[ref.mark];
72
+ const facets = plot?.panels.find(p => p.panel === panel)?.facets ?? {};
73
+ const built = {};
74
+ for (const c of marks.columns) {
75
+ let v = c.values[ref.mark] ?? null;
76
+ const axis = c.name === 'x' || c.name === 'y' ? plot?.positions[c.name] : undefined;
77
+ if (axis?.discrete && typeof v === 'number' && Number.isInteger(v) && axis.levels?.[v - 1] !== undefined)
78
+ v = axis.levels[v - 1];
79
+ built[c.name] = v;
80
+ }
81
+ const out = { mark: markName(ref), layer: ref.layer, geom: layer.geom, plot: layer.plot, facets, built };
82
+ const found = sourceRow(record, ref);
83
+ if (found) {
84
+ out.source = found.source.id;
85
+ out.row = found.row;
86
+ out.values = Object.fromEntries(found.source.columns.map(c => [c.name, valueAt(c, found.at)]));
87
+ if (found.source.key)
88
+ out.key = { column: found.source.key, value: out.values[found.source.key] ?? null };
89
+ }
90
+ return out;
91
+ }
92
+ export function matchMarks(record, where, maximum) {
93
+ const test = (v, w) => {
94
+ if (w.op === 'in')
95
+ return Array.isArray(w.value) && w.value.some(x => x === v || String(x) === String(v));
96
+ const target = w.value;
97
+ if (w.op === 'contains')
98
+ return v !== null && String(v).toLowerCase().includes(String(target).toLowerCase());
99
+ if (w.op === 'eq')
100
+ return v === target || (v !== null && target !== null && String(v) === String(target));
101
+ if (w.op === 'ne')
102
+ return !(v === target || (v !== null && target !== null && String(v) === String(target)));
103
+ if (v === null || target === null)
104
+ return false;
105
+ const a = typeof v === 'number' ? v : Number(v), b = typeof target === 'number' ? target : Number(target);
106
+ if (Number.isNaN(a) || Number.isNaN(b))
107
+ return false;
108
+ return w.op === 'lt' ? a < b : w.op === 'le' ? a <= b : w.op === 'gt' ? a > b : a >= b;
109
+ };
110
+ const found = [];
111
+ let total = 0;
112
+ const layers = record.figure.layers.map((_, i) => i).filter(i => where.every(w => w.layer === undefined || w.layer === i));
113
+ for (const layer of layers) {
114
+ const n = record.figure.layers[layer].marks;
115
+ for (let mark = 0; mark < n; mark++) {
116
+ const row = markRow(record, { layer, mark });
117
+ if (!row)
118
+ continue;
119
+ const read = (column) => row.values && column in row.values ? row.values[column] : column in row.built ? row.built[column] : undefined;
120
+ if (where.every(w => { const v = read(w.column); return v !== undefined && test(v, w); })) {
121
+ total++;
122
+ if (found.length < maximum)
123
+ found.push({ layer, mark });
124
+ }
125
+ }
126
+ }
127
+ return { marks: found, total };
128
+ }
129
+ // The figure as an Agent reads it first: what was drawn, from which data, and what was not bound.
130
+ export function figureSummary(record) {
131
+ return {
132
+ describer: record.describer, kind: record.figure.kind, title: record.figure.title ?? null, size: record.size, versions: record.versions,
133
+ plots: record.figure.plots.map(p => ({ plot: p.plot, title: p.title ?? null, subtitle: p.subtitle ?? null, labels: p.labels, facet: p.facet, coord: p.coord,
134
+ panels: p.panels.length, facets: p.panels.length > 1 ? p.panels.slice(0, 24).map(x => x.facets) : undefined,
135
+ scales: p.scales.map(s => ({ aesthetic: s.aesthetic, title: s.title, breaks: s.breaks.slice(0, 24) })),
136
+ positions: Object.fromEntries(Object.entries(p.positions).map(([k, v]) => [k, v?.discrete ? { discrete: true, levels: v.levels?.slice(0, 48), levelCount: v.levels?.length } : { discrete: false, range: v?.range }])) })),
137
+ layers: record.figure.layers.map((l, i) => ({ layer: i, plot: l.plot, geom: l.geom, stat: l.stat, position: l.position, mapping: l.mapping, constants: l.constants,
138
+ source: l.source, marks: l.marks, bound: l.bound, ...(l.unbound?.length ? { notBound: l.unbound } : {}), ...(l.notes?.length ? { notes: l.notes } : {}),
139
+ builtColumns: record.marks[i]?.columns.map(c => c.name) ?? [] })),
140
+ sources: record.sources.map(s => ({ id: s.id, rows: s.rows, rowsWithMarks: s.index.length, key: s.key, columns: s.columns.map(c => ({ name: c.name, type: c.type })), columnsTotal: s.columnsTotal })),
141
+ problems: record.problems,
142
+ };
143
+ }
@@ -0,0 +1 @@
1
+ export declare function ensureFigureStyles(): void;
@@ -0,0 +1,68 @@
1
+ // The figure's own styles, in the application's tokens. Highlights override the inline styles the
2
+ // R device writes on each element, so they carry !important.
3
+ const styles = `/* A figure whose marks are bound to their rows. */
4
+ .fig { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
5
+ .fig-canvas { position: relative; line-height: 0; user-select: none; -webkit-user-select: none; touch-action: none; cursor: crosshair; border-radius: 6px; }
6
+ .fig-canvas svg { display: block; width: 100%; height: auto; }
7
+ .fig.fit { height: 100%; }
8
+ .fig.fit .fig-canvas { flex: 1 1 auto; min-height: 0; display: flex; align-items: center; justify-content: center; }
9
+ .fig.fit .fig-canvas svg { width: 100%; height: 100%; }
10
+ /* Dimming changes paint, not opacity: an opacity on each of thousands of marks makes each its own layer. */
11
+ .fig-canvas [data-rho] { cursor: pointer; }
12
+ .fig-canvas.has-sel [data-rho]:not(.fig-on):not(.fig-tile) { fill-opacity: .13 !important; stroke-opacity: .13 !important; }
13
+ .fig-canvas [data-rho].fig-tile.fig-on { stroke-width: 2.2px !important; }
14
+ .fig-canvas [data-rho].fig-on { stroke: var(--color-accent-strong) !important; stroke-width: 1.6px !important; stroke-opacity: 1 !important; }
15
+ .fig-canvas text[data-rho].fig-on { fill: var(--color-accent-strong) !important; stroke: none !important; font-weight: 700; }
16
+ .fig-canvas [data-rho].fig-hover { stroke: var(--color-ink) !important; stroke-width: 1.4px !important; fill-opacity: 1 !important; stroke-opacity: 1 !important; }
17
+ .fig-canvas.agent [data-rho].fig-on { stroke: var(--color-amber-text) !important; }
18
+ .fig-canvas.agent text[data-rho].fig-on { fill: var(--color-amber-text) !important; stroke: none !important; }
19
+ .fig-canvas.arrived [data-rho].fig-on { animation: fig-arrive .9s ease-out 1; }
20
+ @keyframes fig-arrive { 0% { stroke-width: 6px; } 100% { stroke-width: 1.6px; } }
21
+ @media (prefers-reduced-motion: reduce) { .fig-canvas.arrived [data-rho].fig-on { animation: none; } }
22
+ .fig-brush { position: absolute; border: 1px solid var(--color-accent); background: color-mix(in srgb, var(--color-accent) 10%, transparent); pointer-events: none; border-radius: 2px; }
23
+ .fig-tip { position: absolute; z-index: 6; max-width: 280px; padding: 8px 10px; border-radius: 8px; background: var(--color-surface); color: var(--color-ink);
24
+ border: 1px solid var(--color-hairline-strong); box-shadow: 0 6px 22px rgba(15, 23, 42, .14); pointer-events: none; line-height: 1.35; font-size: 12px; }
25
+ .fig-tip b { display: block; font-size: 13px; font-weight: 650; overflow-wrap: anywhere; }
26
+ .fig-tip small { display: block; color: var(--color-meta); margin-bottom: 4px; }
27
+ .fig-tip dl { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 1px 10px; margin: 4px 0 0; }
28
+ .fig-tip dt { color: var(--color-meta); white-space: nowrap; }
29
+ .fig-tip dd { margin: 0; font-family: var(--font-mono); font-size: 11.5px; overflow-wrap: anywhere; }
30
+ .fig-hint { margin: 0; color: var(--color-meta); font-size: 12px; line-height: 1.4; }
31
+ .fig-hint b { color: var(--color-ink); font-weight: 600; }
32
+
33
+ /* Marks an Agent pointed to, with its note. */
34
+ .fig-marks { display: flex; flex-wrap: wrap; gap: 6px; }
35
+ .fig-mark-chip { display: inline-flex; align-items: center; gap: 6px; max-width: 100%; min-height: 26px; padding: 3px 10px; border-radius: 999px; border: 1px solid var(--color-amber-line);
36
+ background: var(--color-amber-soft); color: var(--color-ink); font: 12px var(--font-ui); text-align: left; cursor: pointer; }
37
+ .fig-mark-chip[aria-pressed="true"] { border-color: var(--color-amber-text); box-shadow: inset 0 0 0 1px var(--color-amber-text); }
38
+ .fig-mark-chip span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
39
+ .fig-mark-chip strong { font-weight: 650; white-space: nowrap; }
40
+
41
+ /* What is selected: the rows behind it, and asking about it. */
42
+ .fig-sel { display: flex; flex-direction: column; gap: 6px; padding: 10px 12px; border-radius: 8px; border: 1px solid var(--color-hairline); background: var(--color-well); line-height: 1.4; }
43
+ .fig-sel.agent { border-color: var(--color-amber-line); background: var(--color-amber-soft); }
44
+ .fig-sel-head { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; }
45
+ .fig-sel-head h4 { margin: 0; font-size: 13px; font-weight: 650; color: var(--color-ink); }
46
+ .fig-sel-head p { margin: 0; flex: 1 1 12rem; min-width: 0; color: var(--color-meta); font-size: 12px; }
47
+ .fig-sel-actions { display: flex; gap: 6px; margin-left: auto; }
48
+ .fig-sel-note { margin: 0; font-size: 13px; color: var(--color-ink); }
49
+ .fig-table-wrap { overflow: auto; max-height: 240px; border-radius: 6px; border: 1px solid var(--color-hairline); background: var(--color-surface); }
50
+ .fig-table { border-collapse: collapse; width: max-content; min-width: 100%; font-size: 12px; }
51
+ .fig-table th, .fig-table td { padding: 4px 10px; text-align: left; white-space: nowrap; border-bottom: 1px solid var(--color-hairline); }
52
+ .fig-table th { position: sticky; top: 0; background: var(--color-surface); color: var(--color-meta); font-weight: 600; }
53
+ .fig-table td { font-family: var(--font-mono); font-size: 11.5px; color: var(--color-ink); max-width: 18rem; overflow: hidden; text-overflow: ellipsis; }
54
+ .fig-table td.num { text-align: right; font-variant-numeric: tabular-nums; }
55
+ .fig-table tr:last-child td { border-bottom: 0; }
56
+ .fig-more { margin: 0; color: var(--color-meta); font-size: 12px; }
57
+ .fig-note { margin: 0; color: var(--color-meta); font-size: 12px; }
58
+ `;
59
+ let added = false;
60
+ export function ensureFigureStyles() {
61
+ if (added || typeof document === 'undefined')
62
+ return;
63
+ added = true;
64
+ const style = document.createElement('style');
65
+ style.dataset.owner = 'rho-plugins.figures';
66
+ style.textContent = styles;
67
+ document.head.appendChild(style);
68
+ }
@@ -0,0 +1,56 @@
1
+ import { type ReactNode } from 'react';
2
+ export interface UiClient {
3
+ call(method: string, input: any, signal?: AbortSignal): Promise<any>;
4
+ }
5
+ export interface FigureSelection {
6
+ selectionId: string;
7
+ by: string;
8
+ at: string;
9
+ note: string;
10
+ count: number;
11
+ layers: Array<{
12
+ layer: number;
13
+ geom: string;
14
+ marks: number;
15
+ }>;
16
+ marks?: string[];
17
+ }
18
+ export interface FigureFile {
19
+ path?: string;
20
+ sha256: string;
21
+ }
22
+ export interface FigureAsk {
23
+ selectionId: string;
24
+ cellId?: string;
25
+ plot?: number;
26
+ file?: FigureFile;
27
+ count: number;
28
+ label: string;
29
+ }
30
+ export interface FigureProps {
31
+ client: UiClient;
32
+ projectId: string;
33
+ cellId?: string;
34
+ plot?: number;
35
+ file?: FigureFile;
36
+ width?: number;
37
+ height?: number;
38
+ label: string;
39
+ name?: string;
40
+ fit?: boolean;
41
+ fallback?: ReactNode;
42
+ cursor?: number;
43
+ author?: (by: string) => {
44
+ name: string;
45
+ mine: boolean;
46
+ };
47
+ onAsk?: (ask: FigureAsk) => void;
48
+ }
49
+ export declare const figureViewLimits: {
50
+ tableRows: number;
51
+ tableColumns: number;
52
+ tipColumns: number;
53
+ brushPx: number;
54
+ cachedRecords: number;
55
+ };
56
+ export declare function SemanticFigure({ client, projectId, cellId, plot, file, width, label, name, fit, fallback, cursor, author, onAsk }: FigureProps): import("react").JSX.Element;