@monkey-mini-app/dsh-mini-app 0.1.0 → 0.1.4

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 (317) hide show
  1. package/README.md +59 -0
  2. package/assets/apps-list.png +0 -0
  3. package/assets/complex-demo-app.png +0 -0
  4. package/assets/demo-app.png +0 -0
  5. package/assets/home.png +0 -0
  6. package/assets/sidebar-mode.png +0 -0
  7. package/lib/client.js +2024 -783
  8. package/lib/index.d.ts +5 -2
  9. package/lib/index.js +29 -16
  10. package/package.json +12 -10
  11. package/skills/monkey-mini-app/SKILL.md +182 -106
  12. package/skills/monkey-mini-app/references/catalog.md +236 -99
  13. package/skills/monkey-mini-app/references/contracts/accordion.md +30 -0
  14. package/skills/monkey-mini-app/references/contracts/activity-feed.md +12 -2
  15. package/skills/monkey-mini-app/references/contracts/alert-dialog.md +38 -0
  16. package/skills/monkey-mini-app/references/contracts/alert.md +38 -0
  17. package/skills/monkey-mini-app/references/contracts/app-shell.md +2 -2
  18. package/skills/monkey-mini-app/references/contracts/aspect-ratio.md +25 -0
  19. package/skills/monkey-mini-app/references/contracts/attachment-gallery.md +12 -2
  20. package/skills/monkey-mini-app/references/contracts/attachment.md +35 -0
  21. package/skills/monkey-mini-app/references/contracts/autocomplete.md +12 -2
  22. package/skills/monkey-mini-app/references/contracts/avatar.md +24 -0
  23. package/skills/monkey-mini-app/references/contracts/badge.md +26 -0
  24. package/skills/monkey-mini-app/references/contracts/breadcrumb.md +33 -0
  25. package/skills/monkey-mini-app/references/contracts/bubble.md +30 -0
  26. package/skills/monkey-mini-app/references/contracts/button-group.md +36 -0
  27. package/skills/monkey-mini-app/references/contracts/button.md +26 -0
  28. package/skills/monkey-mini-app/references/contracts/calendar.md +20 -0
  29. package/skills/monkey-mini-app/references/contracts/card.md +41 -0
  30. package/skills/monkey-mini-app/references/contracts/cascader.md +12 -2
  31. package/skills/monkey-mini-app/references/contracts/chart.md +32 -0
  32. package/skills/monkey-mini-app/references/contracts/checkbox.md +19 -0
  33. package/skills/monkey-mini-app/references/contracts/code-block.md +20 -2
  34. package/skills/monkey-mini-app/references/contracts/code-editor.md +30 -4
  35. package/skills/monkey-mini-app/references/contracts/collapsible.md +21 -0
  36. package/skills/monkey-mini-app/references/contracts/color-picker.md +12 -2
  37. package/skills/monkey-mini-app/references/contracts/combobox.md +34 -0
  38. package/skills/monkey-mini-app/references/contracts/command.md +41 -0
  39. package/skills/monkey-mini-app/references/contracts/comment-thread.md +12 -2
  40. package/skills/monkey-mini-app/references/contracts/commit-graph.md +50 -0
  41. package/skills/monkey-mini-app/references/contracts/confirm-dialog.md +20 -2
  42. package/skills/monkey-mini-app/references/contracts/context-menu.md +41 -0
  43. package/skills/monkey-mini-app/references/contracts/copyable.md +12 -2
  44. package/skills/monkey-mini-app/references/contracts/currency-input.md +12 -2
  45. package/skills/monkey-mini-app/references/contracts/dashboard-shell.md +41 -0
  46. package/skills/monkey-mini-app/references/contracts/data-grid.md +13 -6
  47. package/skills/monkey-mini-app/references/contracts/date-picker.md +20 -2
  48. package/skills/monkey-mini-app/references/contracts/date-range-picker.md +10 -2
  49. package/skills/monkey-mini-app/references/contracts/date-time-picker.md +20 -2
  50. package/skills/monkey-mini-app/references/contracts/date-time-range-picker.md +20 -2
  51. package/skills/monkey-mini-app/references/contracts/description-list.md +12 -2
  52. package/skills/monkey-mini-app/references/contracts/detail-panel.md +10 -2
  53. package/skills/monkey-mini-app/references/contracts/dialog.md +44 -0
  54. package/skills/monkey-mini-app/references/contracts/diff-viewer.md +21 -2
  55. package/skills/monkey-mini-app/references/contracts/donut-chart.md +14 -2
  56. package/skills/monkey-mini-app/references/contracts/drawer.md +29 -0
  57. package/skills/monkey-mini-app/references/contracts/dropdown-menu.md +49 -0
  58. package/skills/monkey-mini-app/references/contracts/duration-input.md +20 -2
  59. package/skills/monkey-mini-app/references/contracts/empty.md +40 -0
  60. package/skills/monkey-mini-app/references/contracts/env-badge.md +12 -2
  61. package/skills/monkey-mini-app/references/contracts/env-table.md +46 -0
  62. package/skills/monkey-mini-app/references/contracts/event-calendar.md +28 -20
  63. package/skills/monkey-mini-app/references/contracts/field.md +34 -0
  64. package/skills/monkey-mini-app/references/contracts/file-dropzone.md +20 -2
  65. package/skills/monkey-mini-app/references/contracts/file-tree.md +12 -2
  66. package/skills/monkey-mini-app/references/contracts/filter-bar.md +2 -2
  67. package/skills/monkey-mini-app/references/contracts/form-sheet.md +51 -0
  68. package/skills/monkey-mini-app/references/contracts/gantt.md +20 -2
  69. package/skills/monkey-mini-app/references/contracts/gauge.md +14 -2
  70. package/skills/monkey-mini-app/references/contracts/hover-card.md +21 -0
  71. package/skills/monkey-mini-app/references/contracts/input-group.md +24 -0
  72. package/skills/monkey-mini-app/references/contracts/input.md +33 -0
  73. package/skills/monkey-mini-app/references/contracts/item.md +36 -0
  74. package/skills/monkey-mini-app/references/contracts/jira-wiki.md +3 -4
  75. package/skills/monkey-mini-app/references/contracts/jql-input.md +15 -8
  76. package/skills/monkey-mini-app/references/contracts/json-viewer.md +20 -2
  77. package/skills/monkey-mini-app/references/contracts/kanban-issue-panel.md +12 -2
  78. package/skills/monkey-mini-app/references/contracts/kanban.md +10 -2
  79. package/skills/monkey-mini-app/references/contracts/kbd.md +20 -0
  80. package/skills/monkey-mini-app/references/contracts/label.md +33 -0
  81. package/skills/monkey-mini-app/references/contracts/list-detail.md +46 -0
  82. package/skills/monkey-mini-app/references/contracts/log-viewer.md +45 -4
  83. package/skills/monkey-mini-app/references/contracts/markdown-editor.md +20 -2
  84. package/skills/monkey-mini-app/references/contracts/markdown.md +12 -2
  85. package/skills/monkey-mini-app/references/contracts/marker.md +30 -0
  86. package/skills/monkey-mini-app/references/contracts/menubar.md +34 -0
  87. package/skills/monkey-mini-app/references/contracts/message-scroller.md +24 -0
  88. package/skills/monkey-mini-app/references/contracts/message.md +24 -0
  89. package/skills/monkey-mini-app/references/contracts/mini-calendar.md +20 -2
  90. package/skills/monkey-mini-app/references/contracts/native-select.md +21 -0
  91. package/skills/monkey-mini-app/references/contracts/navigation-menu.md +27 -0
  92. package/skills/monkey-mini-app/references/contracts/notification-center.md +12 -2
  93. package/skills/monkey-mini-app/references/contracts/number-field.md +20 -2
  94. package/skills/monkey-mini-app/references/contracts/page-header.md +2 -2
  95. package/skills/monkey-mini-app/references/contracts/pagination.md +33 -0
  96. package/skills/monkey-mini-app/references/contracts/password-field.md +12 -2
  97. package/skills/monkey-mini-app/references/contracts/phone-input.md +12 -2
  98. package/skills/monkey-mini-app/references/contracts/popover.md +32 -0
  99. package/skills/monkey-mini-app/references/contracts/progress-ring.md +14 -2
  100. package/skills/monkey-mini-app/references/contracts/progress.md +39 -0
  101. package/skills/monkey-mini-app/references/contracts/questionnaire.md +33 -0
  102. package/skills/monkey-mini-app/references/contracts/radar-chart.md +14 -2
  103. package/skills/monkey-mini-app/references/contracts/radio-group.md +20 -0
  104. package/skills/monkey-mini-app/references/contracts/rating.md +12 -2
  105. package/skills/monkey-mini-app/references/contracts/relative-date-picker.md +20 -2
  106. package/skills/monkey-mini-app/references/contracts/request-inspector.md +12 -2
  107. package/skills/monkey-mini-app/references/contracts/resizable.md +29 -0
  108. package/skills/monkey-mini-app/references/contracts/reveal.md +31 -0
  109. package/skills/monkey-mini-app/references/contracts/rich-text-editor.md +14 -2
  110. package/skills/monkey-mini-app/references/contracts/run-timeline.md +20 -2
  111. package/skills/monkey-mini-app/references/contracts/scroll-area.md +20 -0
  112. package/skills/monkey-mini-app/references/contracts/scrollspy.md +20 -2
  113. package/skills/monkey-mini-app/references/contracts/search-input.md +12 -2
  114. package/skills/monkey-mini-app/references/contracts/select.md +36 -0
  115. package/skills/monkey-mini-app/references/contracts/separator.md +27 -0
  116. package/skills/monkey-mini-app/references/contracts/settings-split.md +53 -0
  117. package/skills/monkey-mini-app/references/contracts/severity-chip.md +12 -2
  118. package/skills/monkey-mini-app/references/contracts/sheet.md +34 -0
  119. package/skills/monkey-mini-app/references/contracts/sidebar.md +42 -0
  120. package/skills/monkey-mini-app/references/contracts/skeleton.md +33 -0
  121. package/skills/monkey-mini-app/references/contracts/slider-range.md +12 -2
  122. package/skills/monkey-mini-app/references/contracts/slider.md +25 -0
  123. package/skills/monkey-mini-app/references/contracts/sortable-list.md +20 -2
  124. package/skills/monkey-mini-app/references/contracts/sparkline.md +13 -2
  125. package/skills/monkey-mini-app/references/contracts/spinner.md +31 -0
  126. package/skills/monkey-mini-app/references/contracts/stacked-bar-chart.md +17 -2
  127. package/skills/monkey-mini-app/references/contracts/stat-card.md +2 -2
  128. package/skills/monkey-mini-app/references/contracts/status-badge.md +2 -2
  129. package/skills/monkey-mini-app/references/contracts/stepper-item.md +39 -0
  130. package/skills/monkey-mini-app/references/contracts/stepper.md +38 -11
  131. package/skills/monkey-mini-app/references/contracts/switch.md +25 -0
  132. package/skills/monkey-mini-app/references/contracts/table-page.md +41 -0
  133. package/skills/monkey-mini-app/references/contracts/table.md +42 -0
  134. package/skills/monkey-mini-app/references/contracts/tabs.md +31 -0
  135. package/skills/monkey-mini-app/references/contracts/tag-input.md +12 -2
  136. package/skills/monkey-mini-app/references/contracts/terminal.md +13 -2
  137. package/skills/monkey-mini-app/references/contracts/test-step-list.md +12 -2
  138. package/skills/monkey-mini-app/references/contracts/textarea.md +25 -0
  139. package/skills/monkey-mini-app/references/contracts/time-picker.md +18 -2
  140. package/skills/monkey-mini-app/references/contracts/time-range-picker.md +20 -2
  141. package/skills/monkey-mini-app/references/contracts/time-wheel.md +6 -2
  142. package/skills/monkey-mini-app/references/contracts/timeline.md +20 -2
  143. package/skills/monkey-mini-app/references/contracts/timezone-select.md +20 -2
  144. package/skills/monkey-mini-app/references/contracts/toast.md +39 -0
  145. package/skills/monkey-mini-app/references/contracts/toggle-group.md +28 -0
  146. package/skills/monkey-mini-app/references/contracts/toggle.md +26 -0
  147. package/skills/monkey-mini-app/references/contracts/tooltip.md +30 -0
  148. package/skills/monkey-mini-app/references/contracts/transfer.md +12 -2
  149. package/skills/monkey-mini-app/references/contracts/tree-view.md +20 -2
  150. package/skills/monkey-mini-app/references/contracts/trend-card.md +12 -2
  151. package/skills/monkey-mini-app/references/contracts/user-picker.md +12 -2
  152. package/skills/monkey-mini-app/references/contracts/wizard-shell.md +56 -0
  153. package/skills/monkey-mini-app/references/ctx.md +123 -53
  154. package/skills/monkey-mini-app/references/eval.md +115 -0
  155. package/skills/monkey-mini-app/references/examples/alert/alert-01.tsx +17 -0
  156. package/skills/monkey-mini-app/references/examples/aspect-ratio/aspect-ratio-01.tsx +16 -0
  157. package/skills/monkey-mini-app/references/examples/attachment/attachment-01.tsx +19 -0
  158. package/skills/monkey-mini-app/references/examples/breadcrumb/breadcrumb-01.tsx +31 -0
  159. package/skills/monkey-mini-app/references/examples/bubble/bubble-01.tsx +16 -0
  160. package/skills/monkey-mini-app/references/examples/button-group/button-group-01.tsx +23 -0
  161. package/skills/monkey-mini-app/references/examples/card/card-01.tsx +19 -0
  162. package/skills/monkey-mini-app/references/examples/charts-blocks.md +15 -0
  163. package/skills/monkey-mini-app/references/examples/code-block/code-block-01.tsx +14 -0
  164. package/skills/monkey-mini-app/references/examples/code-editor/code-editor-01.tsx +15 -0
  165. package/skills/monkey-mini-app/references/examples/command/command-01.tsx +30 -0
  166. package/skills/monkey-mini-app/references/examples/confirm-dialog/confirm-dialog-01.tsx +33 -0
  167. package/skills/monkey-mini-app/references/examples/context-menu/context-menu-01.tsx +29 -0
  168. package/skills/monkey-mini-app/references/examples/dashboard-shell/dashboard-shell-01.tsx +78 -0
  169. package/skills/monkey-mini-app/references/examples/data-grid/data-grid-01.tsx +34 -0
  170. package/skills/monkey-mini-app/references/examples/data-grid/data-grid-02.tsx +88 -0
  171. package/skills/monkey-mini-app/references/examples/date-picker/date-picker-01.tsx +14 -0
  172. package/skills/monkey-mini-app/references/examples/date-range-picker/date-range-picker-01.tsx +14 -0
  173. package/skills/monkey-mini-app/references/examples/date-time-picker/date-time-picker-01.tsx +16 -0
  174. package/skills/monkey-mini-app/references/examples/date-time-range-picker/date-time-range-picker-01.tsx +15 -0
  175. package/skills/monkey-mini-app/references/examples/detail-panel/detail-panel-01.tsx +21 -0
  176. package/skills/monkey-mini-app/references/examples/dialog/dialog-01.tsx +30 -0
  177. package/skills/monkey-mini-app/references/examples/diff-viewer/diff-viewer-01.tsx +10 -0
  178. package/skills/monkey-mini-app/references/examples/dropdown-menu/dropdown-menu-01.tsx +31 -0
  179. package/skills/monkey-mini-app/references/examples/duration-input/duration-input-01.tsx +20 -0
  180. package/skills/monkey-mini-app/references/examples/editors.md +11 -0
  181. package/skills/monkey-mini-app/references/examples/empty/empty-01.tsx +19 -0
  182. package/skills/monkey-mini-app/references/examples/event-calendar/event-calendar-01.tsx +53 -0
  183. package/skills/monkey-mini-app/references/examples/file-dropzone/file-dropzone-01.tsx +14 -0
  184. package/skills/monkey-mini-app/references/examples/form-sheet/form-sheet-01.tsx +85 -0
  185. package/skills/monkey-mini-app/references/examples/forms.md +16 -0
  186. package/skills/monkey-mini-app/references/examples/gantt/gantt-01.tsx +29 -0
  187. package/skills/monkey-mini-app/references/examples/input/input-01.tsx +10 -0
  188. package/skills/monkey-mini-app/references/examples/item/item-01.tsx +19 -0
  189. package/skills/monkey-mini-app/references/examples/jql-input/jql-input-01.tsx +33 -0
  190. package/skills/monkey-mini-app/references/examples/json-viewer/json-viewer-01.tsx +10 -0
  191. package/skills/monkey-mini-app/references/examples/kanban/kanban-01.tsx +60 -0
  192. package/skills/monkey-mini-app/references/examples/label/label-01.tsx +10 -0
  193. package/skills/monkey-mini-app/references/examples/list-detail/list-detail-01.tsx +117 -0
  194. package/skills/monkey-mini-app/references/examples/log-viewer/log-viewer-01.tsx +20 -0
  195. package/skills/monkey-mini-app/references/examples/markdown-editor/markdown-editor-01.tsx +18 -0
  196. package/skills/monkey-mini-app/references/examples/marker/marker-01.tsx +16 -0
  197. package/skills/monkey-mini-app/references/examples/mini-calendar/mini-calendar-01.tsx +14 -0
  198. package/skills/monkey-mini-app/references/examples/misc-charts-blocks/misc-charts-blocks-01.tsx +20 -0
  199. package/skills/monkey-mini-app/references/examples/misc-charts-blocks/misc-charts-blocks-02.tsx +32 -0
  200. package/skills/monkey-mini-app/references/examples/misc-charts-blocks/misc-charts-blocks-03.tsx +47 -0
  201. package/skills/monkey-mini-app/references/examples/misc-charts-blocks/misc-charts-blocks-04.tsx +20 -0
  202. package/skills/monkey-mini-app/references/examples/misc-charts-blocks/misc-charts-blocks-05.tsx +24 -0
  203. package/skills/monkey-mini-app/references/examples/misc-charts-blocks/misc-charts-blocks-06.tsx +89 -0
  204. package/skills/monkey-mini-app/references/examples/misc-editors/misc-editors-01.tsx +114 -0
  205. package/skills/monkey-mini-app/references/examples/misc-editors/misc-editors-02.tsx +33 -0
  206. package/skills/monkey-mini-app/references/examples/misc-forms/misc-forms-01.tsx +22 -0
  207. package/skills/monkey-mini-app/references/examples/misc-forms/misc-forms-02.tsx +37 -0
  208. package/skills/monkey-mini-app/references/examples/misc-forms/misc-forms-03.tsx +42 -0
  209. package/skills/monkey-mini-app/references/examples/misc-forms/misc-forms-04.tsx +25 -0
  210. package/skills/monkey-mini-app/references/examples/misc-forms/misc-forms-05.tsx +27 -0
  211. package/skills/monkey-mini-app/references/examples/misc-forms/misc-forms-06.tsx +33 -0
  212. package/skills/monkey-mini-app/references/examples/misc-forms/misc-forms-07.tsx +44 -0
  213. package/skills/monkey-mini-app/references/examples/misc-overlays/misc-overlays-01.tsx +43 -0
  214. package/skills/monkey-mini-app/references/examples/misc-overlays/misc-overlays-02.tsx +38 -0
  215. package/skills/monkey-mini-app/references/examples/misc-primitives/misc-primitives-01.tsx +21 -0
  216. package/skills/monkey-mini-app/references/examples/misc-primitives/misc-primitives-02.tsx +52 -0
  217. package/skills/monkey-mini-app/references/examples/misc-primitives/misc-primitives-03.tsx +44 -0
  218. package/skills/monkey-mini-app/references/examples/number-field/number-field-01.tsx +22 -0
  219. package/skills/monkey-mini-app/references/examples/overlays.md +11 -0
  220. package/skills/monkey-mini-app/references/examples/pagination/pagination-01.tsx +51 -0
  221. package/skills/monkey-mini-app/references/examples/primitives.md +12 -0
  222. package/skills/monkey-mini-app/references/examples/progress/progress-01.tsx +10 -0
  223. package/skills/monkey-mini-app/references/examples/relative-date-picker/relative-date-picker-01.tsx +19 -0
  224. package/skills/monkey-mini-app/references/examples/rich-text-editor/rich-text-editor-01.tsx +15 -0
  225. package/skills/monkey-mini-app/references/examples/run-timeline/run-timeline-01.tsx +17 -0
  226. package/skills/monkey-mini-app/references/examples/scrollspy/scrollspy-01.tsx +29 -0
  227. package/skills/monkey-mini-app/references/examples/separator/separator-01.tsx +10 -0
  228. package/skills/monkey-mini-app/references/examples/settings-split/settings-split-01.tsx +84 -0
  229. package/skills/monkey-mini-app/references/examples/shared/jira-wiki-sample.ts +38 -0
  230. package/skills/monkey-mini-app/references/examples/skeleton/skeleton-01.tsx +10 -0
  231. package/skills/monkey-mini-app/references/examples/slider/slider-01.tsx +22 -0
  232. package/skills/monkey-mini-app/references/examples/sortable-list/sortable-list-01.tsx +18 -0
  233. package/skills/monkey-mini-app/references/examples/spinner/spinner-01.tsx +10 -0
  234. package/skills/monkey-mini-app/references/examples/stepper/stepper-01.tsx +41 -0
  235. package/skills/monkey-mini-app/references/examples/table/table-01.tsx +25 -0
  236. package/skills/monkey-mini-app/references/examples/table-page/table-page-01.tsx +103 -0
  237. package/skills/monkey-mini-app/references/examples/time-picker/time-picker-01.tsx +19 -0
  238. package/skills/monkey-mini-app/references/examples/time-range-picker/time-range-picker-01.tsx +14 -0
  239. package/skills/monkey-mini-app/references/examples/timeline/timeline-01.tsx +18 -0
  240. package/skills/monkey-mini-app/references/examples/timezone-select/timezone-select-01.tsx +15 -0
  241. package/skills/monkey-mini-app/references/examples/toggle/toggle-01.tsx +20 -0
  242. package/skills/monkey-mini-app/references/examples/toggle-group/toggle-group-01.tsx +22 -0
  243. package/skills/monkey-mini-app/references/examples/tree-view/tree-view-01.tsx +25 -0
  244. package/skills/monkey-mini-app/references/examples/wizard-shell/wizard-shell-01.tsx +58 -0
  245. package/skills/monkey-mini-app/references/history.md +23 -7
  246. package/skills/monkey-mini-app/references/icons.md +99 -69
  247. package/skills/monkey-mini-app/references/llm-json.md +39 -26
  248. package/skills/monkey-mini-app/references/loader.md +47 -20
  249. package/skills/monkey-mini-app/references/looks/aurora-bento.md +88 -0
  250. package/skills/monkey-mini-app/references/looks/desk-split.md +89 -0
  251. package/skills/monkey-mini-app/references/looks/editorial.md +78 -0
  252. package/skills/monkey-mini-app/references/looks/glass-island.md +90 -0
  253. package/skills/monkey-mini-app/references/looks/index.md +18 -0
  254. package/skills/monkey-mini-app/references/looks/signage.md +74 -0
  255. package/skills/monkey-mini-app/references/looks/tape.md +22 -0
  256. package/skills/monkey-mini-app/references/looks/terminal.md +88 -0
  257. package/skills/monkey-mini-app/references/looks/void.md +22 -0
  258. package/skills/monkey-mini-app/references/styling.md +189 -0
  259. package/skills/monkey-mini-app/references/test.md +12 -12
  260. package/skills/monkey-mini-app/references/theme.md +197 -0
  261. package/skills/monkey-mini-app/references/tools.md +12 -12
  262. package/skills/monkey-mini-app/references/troubleshoot.md +165 -12
  263. package/skills/monkey-mini-app/templates/README.md +33 -21
  264. package/skills/monkey-mini-app/templates/{jira → board}/main.api.ts +11 -11
  265. package/skills/monkey-mini-app/templates/board/manifest.json +8 -0
  266. package/skills/monkey-mini-app/templates/board/theme.css +46 -0
  267. package/skills/monkey-mini-app/templates/board/ui.tsx +546 -0
  268. package/skills/monkey-mini-app/templates/chores/main.api.ts +35 -0
  269. package/skills/monkey-mini-app/templates/chores/manifest.json +8 -0
  270. package/skills/monkey-mini-app/templates/chores/theme.css +46 -0
  271. package/skills/monkey-mini-app/templates/chores/ui.tsx +117 -0
  272. package/skills/monkey-mini-app/templates/minimal/main.api.ts +5 -5
  273. package/skills/monkey-mini-app/templates/minimal/manifest.json +1 -2
  274. package/skills/monkey-mini-app/templates/minimal/ui.tsx +17 -8
  275. package/skills/monkey-mini-app/templates/radar/api/scan.ts +79 -0
  276. package/skills/monkey-mini-app/templates/radar/main.api.ts +29 -0
  277. package/skills/monkey-mini-app/templates/radar/manifest.json +8 -0
  278. package/skills/monkey-mini-app/templates/radar/shared/events.ts +25 -0
  279. package/skills/monkey-mini-app/templates/{insights/lib → radar/shared}/sample.ts +1 -1
  280. package/skills/monkey-mini-app/templates/radar/theme.css +47 -0
  281. package/skills/monkey-mini-app/templates/radar/ui/brief.tsx +31 -0
  282. package/skills/monkey-mini-app/templates/radar/ui.tsx +131 -0
  283. package/skills/monkey-mini-app/templates/runner/main.api.ts +91 -0
  284. package/skills/monkey-mini-app/templates/runner/manifest.json +8 -0
  285. package/skills/monkey-mini-app/templates/runner/shared/events.ts +14 -0
  286. package/skills/monkey-mini-app/templates/runner/theme.css +46 -0
  287. package/skills/monkey-mini-app/templates/runner/ui.tsx +213 -0
  288. package/skills/monkey-mini-app/templates/sheets/main.api.ts +276 -0
  289. package/skills/monkey-mini-app/templates/sheets/manifest.json +8 -0
  290. package/skills/monkey-mini-app/templates/sheets/theme.css +46 -0
  291. package/skills/monkey-mini-app/templates/sheets/ui.tsx +419 -0
  292. package/skills/monkey-mini-app/templates/{todo → today}/main.api.ts +8 -8
  293. package/skills/monkey-mini-app/templates/today/manifest.json +8 -0
  294. package/skills/monkey-mini-app/templates/today/theme.css +45 -0
  295. package/skills/monkey-mini-app/templates/today/ui/item-row.tsx +25 -0
  296. package/skills/monkey-mini-app/templates/today/ui.tsx +406 -0
  297. package/skills/monkey-mini-app/templates/{monitor → watch}/main.api.ts +8 -8
  298. package/skills/monkey-mini-app/templates/watch/manifest.json +8 -0
  299. package/skills/monkey-mini-app/templates/watch/ui.tsx +187 -0
  300. package/skills/monkey-mini-app/tsconfig.json +31 -0
  301. package/skills/monkey-mini-app/types/cdn.d.ts +1 -0
  302. package/tsup.config.ts +1 -0
  303. package/skills/monkey-mini-app/templates/agentrun/main.api.ts +0 -78
  304. package/skills/monkey-mini-app/templates/agentrun/manifest.json +0 -9
  305. package/skills/monkey-mini-app/templates/agentrun/ui.tsx +0 -125
  306. package/skills/monkey-mini-app/templates/insights/main.api.ts +0 -101
  307. package/skills/monkey-mini-app/templates/insights/manifest.json +0 -9
  308. package/skills/monkey-mini-app/templates/insights/ui.tsx +0 -138
  309. package/skills/monkey-mini-app/templates/jira/manifest.json +0 -9
  310. package/skills/monkey-mini-app/templates/jira/ui.tsx +0 -318
  311. package/skills/monkey-mini-app/templates/monitor/manifest.json +0 -9
  312. package/skills/monkey-mini-app/templates/monitor/ui.tsx +0 -176
  313. package/skills/monkey-mini-app/templates/review/main.api.ts +0 -68
  314. package/skills/monkey-mini-app/templates/review/manifest.json +0 -9
  315. package/skills/monkey-mini-app/templates/review/ui.tsx +0 -159
  316. package/skills/monkey-mini-app/templates/todo/manifest.json +0 -8
  317. package/skills/monkey-mini-app/templates/todo/ui.tsx +0 -177
@@ -0,0 +1,46 @@
1
+ /* name: 终端等宽 */
2
+ /* Look-owned palette: phosphor-on-black CRT is the identity — a host palette would turn the
3
+ well pink. Light mode is a paper well with deep green ink; dark is near-black with green
4
+ phosphor (#3dff6e). Radius is squared: rounds read as "chat app", not as a console. */
5
+ :root[data-mode="light"] {
6
+ --bg: #ecefe4;
7
+ --fg: #12290f;
8
+ --surface: #f7faf1;
9
+ --surface-fg: #12290f;
10
+ --border: #ccd5c0;
11
+ --muted: #dfe6d4;
12
+ --muted-fg: #4c5f44;
13
+ --primary: #157a24;
14
+ --primary-fg: #ffffff;
15
+ --secondary: #dfe6d4;
16
+ --secondary-fg: #12290f;
17
+ --accent: #e2ecd6;
18
+ --accent-fg: #12290f;
19
+ --destructive: #b42318;
20
+ --destructive-fg: #ffffff;
21
+ --ring: #157a24;
22
+ --input: #ccd5c0;
23
+ --radius: 8px;
24
+ --shadow: rgba(20, 40, 25, 0.12);
25
+ }
26
+ :root[data-mode="dark"] {
27
+ --bg: #0a0d08;
28
+ --fg: #3dff6e;
29
+ --surface: #060904;
30
+ --surface-fg: #3dff6e;
31
+ --border: #1d2a18;
32
+ --muted: #10180d;
33
+ --muted-fg: #5f8a55;
34
+ --primary: #3dff6e;
35
+ --primary-fg: #0a0d08;
36
+ --secondary: #10180d;
37
+ --secondary-fg: #3dff6e;
38
+ --accent: #12200f;
39
+ --accent-fg: #3dff6e;
40
+ --destructive: #ff5341;
41
+ --destructive-fg: #0a0d08;
42
+ --ring: #3dff6e;
43
+ --input: #1d2a18;
44
+ --radius: 8px;
45
+ --shadow: rgba(0, 0, 0, 0.55);
46
+ }
@@ -0,0 +1,213 @@
1
+ import { useCallback, useEffect, useState } from "react";
2
+
3
+ import {
4
+ Badge,
5
+ Button,
6
+ Icon,
7
+ Input,
8
+ RunTimeline,
9
+ Terminal,
10
+ useApp,
11
+ } from "@monkey-mini-app/ui";
12
+
13
+ import { EV, type Run, type Step } from "./shared/events";
14
+
15
+ type AgentEvent =
16
+ | { type: "status"; status: string }
17
+ | { type: "text-delta"; text: string }
18
+ | { type: "tool"; phase: string; name: string }
19
+ | { type: "turn"; phase: string; turn: number }
20
+ | { type: "done"; text: string }
21
+ | { type: "error"; message: string };
22
+ type TimelineItem = {
23
+ id: string;
24
+ title: string;
25
+ description?: string;
26
+ time?: string;
27
+ status?: "pass" | "fail" | "running" | "skipped";
28
+ };
29
+
30
+ // Token hues only: under this look's phosphor palette a literal `bg-emerald-400` fights the
31
+ // ground, and the rule is colour = state, nothing else.
32
+ const LAMP: Record<string, string> = {
33
+ idle: "bg-muted-foreground/40",
34
+ running: "bg-primary/50",
35
+ done: "bg-primary",
36
+ cancelled: "bg-muted-foreground/70",
37
+ error: "bg-destructive",
38
+ };
39
+
40
+ export default function Ui() {
41
+ const { call, on, onAny } = useApp();
42
+ const [goal, setGoal] = useState("");
43
+ const [run, setRun] = useState<Run | null>(null);
44
+ const [running, setRunning] = useState(false);
45
+ const [steps, setSteps] = useState<Step[]>([]);
46
+ const [live, setLive] = useState("");
47
+ const [error, setError] = useState<string | null>(null);
48
+
49
+ const applyRun = useCallback((next: Run) => {
50
+ setRun(next);
51
+ setRunning(next?.status === "running");
52
+ if (next?.status !== "running") {
53
+ // finished: the persisted snapshot is authoritative, drop the optimistic feed
54
+ setSteps(next.steps ?? []);
55
+ setLive(next.result ?? "");
56
+ }
57
+ }, []);
58
+
59
+ // ⭐ key: fetch the snapshot ONCE, then let ctx.push events keep it current — no interval polling.
60
+ useEffect(() => {
61
+ void (call("runStatus", {}) as Promise<Run>).then(applyRun).catch(() => {});
62
+ }, [call, applyRun]);
63
+
64
+ useEffect(() => {
65
+ const offRun = on(EV.run, (data) => applyRun(data as Run));
66
+ const offAgent = on(EV.agent, (data) => {
67
+ const ev = data as AgentEvent;
68
+ const at = Date.now();
69
+ if (ev.type === "text-delta") setLive((prev) => prev + ev.text);
70
+ else if (ev.type === "tool" && ev.phase === "start")
71
+ setSteps((p) => [...p, { phase: "tool", name: ev.name, at }]);
72
+ else if (ev.type === "turn" && ev.phase === "start")
73
+ setSteps((p) => [...p, { phase: "turn", turn: ev.turn, at }]);
74
+ else if (ev.type === "done")
75
+ setSteps((p) => [...p, { phase: "done", at }]);
76
+ else if (ev.type === "error")
77
+ setSteps((p) => [...p, { phase: "error", text: ev.message, at }]);
78
+ });
79
+ // Events dropped from the host replay buffer (long disconnect): refetch, don't guess.
80
+ const offAny = onAny((e) => {
81
+ if (e.name === "*" && (e.data as { gap?: boolean })?.gap) {
82
+ void (call("runStatus", {}) as Promise<Run>)
83
+ .then(applyRun)
84
+ .catch(() => {});
85
+ }
86
+ });
87
+ return () => {
88
+ offRun();
89
+ offAgent();
90
+ offAny();
91
+ };
92
+ }, [on, onAny, call, applyRun]);
93
+
94
+ async function start() {
95
+ setError(null);
96
+ setSteps([]);
97
+ setLive("");
98
+ try {
99
+ await call("start", { goal });
100
+ } catch (e) {
101
+ setError(String((e as Error)?.message || e));
102
+ }
103
+ }
104
+
105
+ // ⭐ key: a run's phases on a time axis = RunTimeline. Plain ordered events = Timeline.
106
+ const items: TimelineItem[] = steps.map((s, i) => ({
107
+ id: String(i),
108
+ title:
109
+ s.phase === "tool"
110
+ ? `调用工具 ${s.name ?? ""}`
111
+ : s.phase === "turn"
112
+ ? `第 ${s.turn} 轮`
113
+ : s.phase === "done"
114
+ ? "完成"
115
+ : s.phase,
116
+ description: s.text ?? (s.phase === "tool" ? "结束" : undefined),
117
+ time: new Date(s.at).toLocaleTimeString("zh-CN"),
118
+ status:
119
+ s.phase === "error"
120
+ ? "fail"
121
+ : s.phase === "done"
122
+ ? "pass"
123
+ : running && i === steps.length - 1
124
+ ? "running"
125
+ : "skipped",
126
+ }));
127
+
128
+ const status = run?.status ?? "idle";
129
+
130
+ return (
131
+ // ⭐ Look: terminal — lamp header, a command bar, mono wells. Colour is state, nothing else.
132
+ <div className="flex h-full min-h-0 flex-col bg-background font-mono text-sm">
133
+ <div className="border-border text-muted-foreground flex items-center gap-2 border-b px-4 py-2.5 text-xs">
134
+ <span className={`size-2 rounded-full ${LAMP[status] ?? LAMP.idle}`} />
135
+ runner · {goal.trim() || "未指定目标"}
136
+ <Badge
137
+ variant={status === "error" ? "destructive" : "outline"}
138
+ className="ml-auto"
139
+ >
140
+ {status}
141
+ </Badge>
142
+ </div>
143
+
144
+ <div className="border-border flex flex-wrap items-center gap-2 border-b px-4 py-3">
145
+ <Icon.ChevronRight className="text-muted-foreground size-4 shrink-0" />
146
+ <Input
147
+ value={goal}
148
+ placeholder="读 packages/ui/src 下组件,总结导出清单写到 storage"
149
+ onChange={(e) => setGoal(e.target.value)}
150
+ onKeyDown={(e) => {
151
+ if (e.key === "Enter" && !running && goal.trim()) void start();
152
+ }}
153
+ className="h-8 min-w-52 flex-1 border-0 bg-transparent px-0 font-mono text-sm shadow-none focus-visible:ring-0"
154
+ />
155
+ <Button
156
+ size="sm"
157
+ variant="outline"
158
+ onClick={() => void start()}
159
+ disabled={running || !goal.trim()}
160
+ >
161
+ <Icon.Play size={14} strokeWidth={2} /> 运行
162
+ </Button>
163
+ {running ? (
164
+ <Button
165
+ size="sm"
166
+ variant="ghost"
167
+ onClick={() => void call("cancel", {})}
168
+ >
169
+ <Icon.Square size={14} strokeWidth={2} /> 取消
170
+ </Button>
171
+ ) : null}
172
+ </div>
173
+ {error ? (
174
+ <p className="text-destructive px-4 py-2 text-xs">{error}</p>
175
+ ) : null}
176
+
177
+ <div className="border-border grid min-h-0 flex-1 grid-rows-[auto_1fr]">
178
+ <div className="border-border max-h-56 min-h-0 overflow-y-auto border-b px-4 py-3">
179
+ {items.length ? (
180
+ <RunTimeline items={items} />
181
+ ) : (
182
+ <p className="text-muted-foreground text-xs">等待运行…</p>
183
+ )}
184
+ </div>
185
+ <div className="min-h-0 p-4">
186
+ {/* ⭐ Phosphor well: token surfaces (not the kit's hard zinc), green glow, scanlines
187
+ and a corner vignette on top. Square-ish corners — rounds read as a chat app. */}
188
+ <div
189
+ className="border-border relative h-full min-h-0 overflow-hidden rounded-lg border"
190
+ style={{
191
+ textShadow:
192
+ "0 0 6px color-mix(in oklch, var(--primary) 65%, transparent)",
193
+ }}
194
+ >
195
+ <Terminal
196
+ className="border-border bg-card text-card-foreground h-full rounded-lg"
197
+ lines={live ? live.split("\n") : ["$ 输出会实时写到这里", "$ █"]}
198
+ />
199
+ <div
200
+ aria-hidden
201
+ className="pointer-events-none absolute inset-0"
202
+ style={{
203
+ backgroundImage:
204
+ "repeating-linear-gradient(0deg, color-mix(in oklch, var(--foreground) 7%, transparent) 0 1px, transparent 1px 3px)," +
205
+ "radial-gradient(120% 90% at 50% 40%, transparent 62%, var(--shadow))",
206
+ }}
207
+ />
208
+ </div>
209
+ </div>
210
+ </div>
211
+ </div>
212
+ );
213
+ }
@@ -0,0 +1,276 @@
1
+ // ⭐ This template needs ONE library the platform does not ship. Before `mini_app_reload`:
2
+ // mini_app_install({ appId: "com.example.sheets", packages: [{ name: "exceljs" }] })
3
+ // It lands in this app's own node_modules (--ignore-scripts, lockfile committed,
4
+ // node_modules not). `ui.tsx` still cannot import it — the browser bundle has its own
5
+ // closed surface, so the workbook is parsed here and the UI only sees JSON.
6
+ import ExcelJS from "exceljs";
7
+
8
+ // ⭐ Platform module: full lodash on both sides. Aggregates below are the case it pays for.
9
+ import { mean, sum } from "lodash";
10
+
11
+ import { defineApp } from "@monkey-mini-app/api";
12
+
13
+ type SheetData = {
14
+ name: string;
15
+ headers: string[];
16
+ /** Capped preview rows; aggregates are computed over every row. */
17
+ rows: Record<string, string | number>[];
18
+ rowCount: number;
19
+ columns: {
20
+ header: string;
21
+ numeric: boolean;
22
+ count: number;
23
+ min?: number;
24
+ max?: number;
25
+ total?: number;
26
+ avg?: number;
27
+ }[];
28
+ };
29
+
30
+ type Report = {
31
+ id: string;
32
+ fileName: string;
33
+ createdAt: number;
34
+ sheetCount: number;
35
+ rowCount: number;
36
+ digest?: { headline: string; bullets: string[] };
37
+ };
38
+
39
+ const PREVIEW_CAP = 300;
40
+
41
+ /**
42
+ * An `.xlsx` cell is not always a primitive: formulas carry `{ result }`, rich text
43
+ * carries `richText[]`, dates are `Date`, hyperlinks wrap `{ text }`. Passing those
44
+ * straight to the UI gives `[object Object]` in half the columns.
45
+ */
46
+ function cellText(value: unknown): string | number | null {
47
+ if (value === null || value === undefined) return null;
48
+ if (typeof value === "number" || typeof value === "boolean")
49
+ return typeof value === "boolean" ? String(value) : value;
50
+ if (value instanceof Date) return value.toISOString().slice(0, 10);
51
+ if (typeof value === "object") {
52
+ const v = value as Record<string, unknown>;
53
+ if ("result" in v) return cellText(v.result);
54
+ if ("text" in v) return cellText(v.text);
55
+ if (Array.isArray(v.richText)) {
56
+ return (v.richText as { text?: string }[])
57
+ .map((p) => p.text ?? "")
58
+ .join("");
59
+ }
60
+ }
61
+ return String(value);
62
+ }
63
+
64
+ function toNumberOrNull(value: string | number | null): number | null {
65
+ if (typeof value === "number") return Number.isFinite(value) ? value : null;
66
+ if (value === null) return null;
67
+ const cleaned = String(value).replace(/[,\s%]/g, "");
68
+ if (!cleaned || !/^-?\d+(\.\d+)?$/.test(cleaned)) return null;
69
+ const n = Number(cleaned);
70
+ return Number.isFinite(n) ? n : null;
71
+ }
72
+
73
+ /**
74
+ * ⭐ exceljs re-declares a **global** `interface Buffer extends ArrayBuffer`, which poisons the
75
+ * `Buffer` *type name* everywhere it is imported — so the app works in `Uint8Array` and hands
76
+ * the reader a plain ArrayBuffer. (`as any` would hide the next real mismatch.)
77
+ */
78
+ function toArrayBuffer(b: Uint8Array): ArrayBuffer {
79
+ return b.buffer.slice(
80
+ b.byteOffset,
81
+ b.byteOffset + b.byteLength,
82
+ ) as ArrayBuffer;
83
+ }
84
+
85
+ async function parseWorkbook(
86
+ data: Uint8Array,
87
+ ): Promise<{ sheets: SheetData[] }> {
88
+ const wb = new ExcelJS.Workbook();
89
+ // exceljs parses the bytes in-process: no temp file on disk, nothing uploaded.
90
+ await wb.xlsx.load(toArrayBuffer(data));
91
+ const sheets: SheetData[] = [];
92
+ wb.worksheets.forEach((ws) => {
93
+ if (!ws.rowCount) return;
94
+ const headerRow = ws.getRow(1);
95
+ const width = headerRow.cellCount;
96
+ const headers: string[] = [];
97
+ for (let c = 1; c <= width; c++) {
98
+ headers.push(String(cellText(headerRow.getCell(c).value) ?? `列${c}`));
99
+ }
100
+
101
+ const matrix: (string | number | null)[][] = [];
102
+ ws.eachRow((row, rowNumber) => {
103
+ if (rowNumber === 1) return;
104
+ const line: (string | number | null)[] = [];
105
+ for (let c = 1; c <= width; c++)
106
+ line.push(cellText(row.getCell(c).value));
107
+ if (line.some((x) => x !== null && x !== "")) matrix.push(line);
108
+ });
109
+
110
+ const columns = headers.map((header, i) => {
111
+ const nums = matrix
112
+ .map((r) => toNumberOrNull(r[i] ?? null))
113
+ .filter((n): n is number => n !== null);
114
+ // A column is numeric when most of its cells parse as numbers: one stray text
115
+ // cell in an amount column must not demote the whole column to text.
116
+ const numeric = nums.length > 0 && nums.length >= matrix.length * 0.6;
117
+ return {
118
+ header,
119
+ numeric,
120
+ count: matrix.length,
121
+ min: numeric ? Math.min(...nums) : undefined,
122
+ max: numeric ? Math.max(...nums) : undefined,
123
+ total: numeric ? Number(sum(nums).toFixed(2)) : undefined,
124
+ avg: numeric ? Number(mean(nums).toFixed(2)) : undefined,
125
+ };
126
+ });
127
+
128
+ sheets.push({
129
+ name: ws.name,
130
+ headers,
131
+ rowCount: matrix.length,
132
+ columns,
133
+ rows: matrix.slice(0, PREVIEW_CAP).map((r) => {
134
+ const obj: Record<string, string | number> = {};
135
+ headers.forEach((h, i) => {
136
+ obj[h] = (r[i] ?? "") as string | number;
137
+ });
138
+ return obj;
139
+ }),
140
+ });
141
+ });
142
+ return { sheets };
143
+ }
144
+
145
+ function digestPrompt(sheets: SheetData[]): string {
146
+ const lines: string[] = [];
147
+ for (const s of sheets.slice(0, 6)) {
148
+ lines.push(`### ${s.name}(${s.rowCount} 行)`);
149
+ for (const c of s.columns.slice(0, 12)) {
150
+ lines.push(
151
+ c.numeric
152
+ ? `- ${c.header}: n=${c.count} 合计=${c.total} 均值=${c.avg} 最小=${c.min} 最大=${c.max}`
153
+ : `- ${c.header}: 文本列,${c.count} 行`,
154
+ );
155
+ }
156
+ }
157
+ return [
158
+ "下面是用户本机一份 Excel 的结构与数值汇总(已抽样,未逐行列出)。",
159
+ "用中文写业务结论,不要复述列名清单,不要提 lodash / exceljs / storage 这些实现细节。",
160
+ "",
161
+ lines.join("\n"),
162
+ "",
163
+ "返回 JSON:{ headline: 一句话结论, bullets: 3-5 条值得关注的点(含具体数字) }",
164
+ ].join("\n");
165
+ }
166
+
167
+ async function loadSheets(ctx, id: string): Promise<SheetData[]> {
168
+ const stored = await ctx.storage.table("reports").get(id);
169
+ if (!stored || !Array.isArray(stored.sheets)) {
170
+ throw new Error("找不到该报表,请重新拖入文件");
171
+ }
172
+ return stored.sheets as SheetData[];
173
+ }
174
+
175
+ export default defineApp({
176
+ name: "表格台",
177
+ description: "文件进,格子上干活,哪里变了",
178
+ api: {
179
+ /** ⭐ History survives reload: the parse result lives on disk, not in a tab. */
180
+ async list(ctx) {
181
+ const index = await ctx.storage.get("index");
182
+ return Array.isArray(index) ? index : [];
183
+ },
184
+
185
+ /** Full report (incl. sheets) for a history row — index alone has no payload. */
186
+ async get(ctx, args) {
187
+ const id = String(args?.id ?? "");
188
+ const stored = await ctx.storage.table("reports").get(id);
189
+ if (!stored) throw new Error("找不到该报表,请重新拖入文件");
190
+ return stored;
191
+ },
192
+
193
+ async ingest(ctx, args) {
194
+ const fileName = String(args?.fileName ?? "").trim() || "未命名报表";
195
+ const base64 = String(args?.base64 ?? "");
196
+ if (!base64) throw new Error("文件内容为空");
197
+
198
+ const data = new Uint8Array(Buffer.from(base64, "base64"));
199
+ let sheets: SheetData[];
200
+ try {
201
+ sheets = (await parseWorkbook(data)).sheets;
202
+ } catch (cause) {
203
+ throw new Error(
204
+ `无法读取这个 Excel:${cause instanceof Error ? cause.message : String(cause)}(仅支持 .xlsx,旧版 .xls 需要先另存为 .xlsx)`,
205
+ );
206
+ }
207
+ if (!sheets.length) throw new Error("工作簿里没有带数据的表");
208
+
209
+ const id = "r_" + Date.now().toString(36);
210
+ const report = {
211
+ id,
212
+ fileName,
213
+ createdAt: Date.now(),
214
+ sheetCount: sheets.length,
215
+ rowCount: sheets.reduce((n, s) => n + s.rowCount, 0),
216
+ };
217
+
218
+ // ⭐ Big payload → its own table (one file per report); the index stays tiny so
219
+ // `list` is cheap. Same reason the UI gets preview rows, not the whole sheet.
220
+ await ctx.storage.table("reports").set(id, { ...report, sheets });
221
+ const index = [report, ...((await ctx.storage.get("index")) ?? [])].slice(
222
+ 0,
223
+ 30,
224
+ );
225
+ await ctx.storage.set("index", index);
226
+
227
+ return { ...report, sheets };
228
+ },
229
+
230
+ /** ⭐ The host's model, called from a button. No API key in this file, no second SDK. */
231
+ async digest(ctx, args) {
232
+ const id = String(args?.id ?? "");
233
+ const sheets = await loadSheets(ctx, id);
234
+ const text = await ctx.llm(digestPrompt(sheets), {
235
+ schema: {
236
+ type: "object",
237
+ properties: {
238
+ headline: { type: "string" },
239
+ bullets: { type: "array", items: { type: "string" } },
240
+ },
241
+ required: ["headline", "bullets"],
242
+ },
243
+ });
244
+ let digest = { headline: "模型没有返回结论", bullets: [] as string[] };
245
+ try {
246
+ const parsed = JSON.parse(text);
247
+ digest = {
248
+ headline: String(parsed.headline ?? digest.headline),
249
+ bullets: Array.isArray(parsed.bullets)
250
+ ? parsed.bullets.map(String)
251
+ : [],
252
+ };
253
+ } catch {
254
+ digest = { headline: text.slice(0, 120), bullets: [] };
255
+ }
256
+
257
+ const stored = await ctx.storage.table("reports").get(id);
258
+ await ctx.storage.table("reports").set(id, { ...stored, digest });
259
+ const index = ((await ctx.storage.get("index")) ?? []).map((r) =>
260
+ r.id === id ? { ...r, digest } : r,
261
+ );
262
+ await ctx.storage.set("index", index);
263
+ return digest;
264
+ },
265
+
266
+ async remove(ctx, args) {
267
+ const id = String(args?.id ?? "");
268
+ await ctx.storage.table("reports").delete(id);
269
+ await ctx.storage.set(
270
+ "index",
271
+ ((await ctx.storage.get("index")) ?? []).filter((r) => r.id !== id),
272
+ );
273
+ return { ok: true };
274
+ },
275
+ },
276
+ });
@@ -0,0 +1,8 @@
1
+ {
2
+ "id": "com.example.sheets",
3
+ "name": "表格台",
4
+ "description": "文件进,格子上干活,哪里变了",
5
+ "version": "0.1.0",
6
+ "entry": "ui.tsx",
7
+ "acronym": "BG"
8
+ }
@@ -0,0 +1,46 @@
1
+ /* name: 桌面分栏 */
2
+ /* Look-owned palette: walnut desk + amber desk-lamp. The papers are cream in BOTH modes —
3
+ a dark desk with lamp-lit paper is the desk; dark papers would read as mud. All ink is
4
+ dark in both modes for the same reason, so `--foreground` is never painted on the wood. */
5
+ :root[data-mode="light"] {
6
+ --bg: #8a6845;
7
+ --fg: #33260f;
8
+ --surface: #faf5ea;
9
+ --surface-fg: #33260f;
10
+ --border: #6b4f2c;
11
+ --muted: #ebdfc6;
12
+ --muted-fg: #74603f;
13
+ --primary: #a8741c;
14
+ --primary-fg: #fdf6e7;
15
+ --secondary: #efe3c8;
16
+ --secondary-fg: #33260f;
17
+ --accent: #e9d9b4;
18
+ --accent-fg: #33260f;
19
+ --destructive: #a13d2d;
20
+ --destructive-fg: #fff8ee;
21
+ --ring: #c98f2e;
22
+ --input: #c7ab7d;
23
+ --radius: 12px;
24
+ --shadow: rgba(48, 32, 12, 0.42);
25
+ }
26
+ :root[data-mode="dark"] {
27
+ --bg: #2f2311;
28
+ --fg: #2e2113;
29
+ --surface: #f0e6cf;
30
+ --surface-fg: #2e2113;
31
+ --border: #7a5a30;
32
+ --muted: #e2d5b8;
33
+ --muted-fg: #5f4d30;
34
+ --primary: #a8741c;
35
+ --primary-fg: #fdf6e7;
36
+ --secondary: #e6d9b6;
37
+ --secondary-fg: #2e2113;
38
+ --accent: #dfcf9f;
39
+ --accent-fg: #2e2113;
40
+ --destructive: #b04938;
41
+ --destructive-fg: #fff3ec;
42
+ --ring: #d9a643;
43
+ --input: #e2d3ae;
44
+ --radius: 12px;
45
+ --shadow: rgba(8, 5, 1, 0.6);
46
+ }