@monkey-mini-app/dsh-mini-app 0.1.1 → 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 (312) hide show
  1. package/README.md +29 -27
  2. package/lib/client.js +2024 -783
  3. package/lib/index.d.ts +2 -0
  4. package/lib/index.js +20 -7
  5. package/package.json +10 -9
  6. package/skills/monkey-mini-app/SKILL.md +181 -114
  7. package/skills/monkey-mini-app/references/catalog.md +236 -99
  8. package/skills/monkey-mini-app/references/contracts/accordion.md +30 -0
  9. package/skills/monkey-mini-app/references/contracts/activity-feed.md +12 -2
  10. package/skills/monkey-mini-app/references/contracts/alert-dialog.md +38 -0
  11. package/skills/monkey-mini-app/references/contracts/alert.md +38 -0
  12. package/skills/monkey-mini-app/references/contracts/app-shell.md +2 -2
  13. package/skills/monkey-mini-app/references/contracts/aspect-ratio.md +25 -0
  14. package/skills/monkey-mini-app/references/contracts/attachment-gallery.md +12 -2
  15. package/skills/monkey-mini-app/references/contracts/attachment.md +35 -0
  16. package/skills/monkey-mini-app/references/contracts/autocomplete.md +12 -2
  17. package/skills/monkey-mini-app/references/contracts/avatar.md +24 -0
  18. package/skills/monkey-mini-app/references/contracts/badge.md +26 -0
  19. package/skills/monkey-mini-app/references/contracts/breadcrumb.md +33 -0
  20. package/skills/monkey-mini-app/references/contracts/bubble.md +30 -0
  21. package/skills/monkey-mini-app/references/contracts/button-group.md +36 -0
  22. package/skills/monkey-mini-app/references/contracts/button.md +26 -0
  23. package/skills/monkey-mini-app/references/contracts/calendar.md +20 -0
  24. package/skills/monkey-mini-app/references/contracts/card.md +41 -0
  25. package/skills/monkey-mini-app/references/contracts/cascader.md +12 -2
  26. package/skills/monkey-mini-app/references/contracts/chart.md +32 -0
  27. package/skills/monkey-mini-app/references/contracts/checkbox.md +19 -0
  28. package/skills/monkey-mini-app/references/contracts/code-block.md +20 -2
  29. package/skills/monkey-mini-app/references/contracts/code-editor.md +30 -4
  30. package/skills/monkey-mini-app/references/contracts/collapsible.md +21 -0
  31. package/skills/monkey-mini-app/references/contracts/color-picker.md +12 -2
  32. package/skills/monkey-mini-app/references/contracts/combobox.md +34 -0
  33. package/skills/monkey-mini-app/references/contracts/command.md +41 -0
  34. package/skills/monkey-mini-app/references/contracts/comment-thread.md +12 -2
  35. package/skills/monkey-mini-app/references/contracts/commit-graph.md +50 -0
  36. package/skills/monkey-mini-app/references/contracts/confirm-dialog.md +20 -2
  37. package/skills/monkey-mini-app/references/contracts/context-menu.md +41 -0
  38. package/skills/monkey-mini-app/references/contracts/copyable.md +12 -2
  39. package/skills/monkey-mini-app/references/contracts/currency-input.md +12 -2
  40. package/skills/monkey-mini-app/references/contracts/dashboard-shell.md +41 -0
  41. package/skills/monkey-mini-app/references/contracts/data-grid.md +13 -6
  42. package/skills/monkey-mini-app/references/contracts/date-picker.md +20 -2
  43. package/skills/monkey-mini-app/references/contracts/date-range-picker.md +10 -2
  44. package/skills/monkey-mini-app/references/contracts/date-time-picker.md +20 -2
  45. package/skills/monkey-mini-app/references/contracts/date-time-range-picker.md +20 -2
  46. package/skills/monkey-mini-app/references/contracts/description-list.md +12 -2
  47. package/skills/monkey-mini-app/references/contracts/detail-panel.md +10 -2
  48. package/skills/monkey-mini-app/references/contracts/dialog.md +44 -0
  49. package/skills/monkey-mini-app/references/contracts/diff-viewer.md +21 -2
  50. package/skills/monkey-mini-app/references/contracts/donut-chart.md +12 -2
  51. package/skills/monkey-mini-app/references/contracts/drawer.md +29 -0
  52. package/skills/monkey-mini-app/references/contracts/dropdown-menu.md +49 -0
  53. package/skills/monkey-mini-app/references/contracts/duration-input.md +20 -2
  54. package/skills/monkey-mini-app/references/contracts/empty.md +40 -0
  55. package/skills/monkey-mini-app/references/contracts/env-badge.md +12 -2
  56. package/skills/monkey-mini-app/references/contracts/env-table.md +46 -0
  57. package/skills/monkey-mini-app/references/contracts/event-calendar.md +28 -20
  58. package/skills/monkey-mini-app/references/contracts/field.md +34 -0
  59. package/skills/monkey-mini-app/references/contracts/file-dropzone.md +20 -2
  60. package/skills/monkey-mini-app/references/contracts/file-tree.md +12 -2
  61. package/skills/monkey-mini-app/references/contracts/filter-bar.md +2 -2
  62. package/skills/monkey-mini-app/references/contracts/form-sheet.md +51 -0
  63. package/skills/monkey-mini-app/references/contracts/gantt.md +20 -2
  64. package/skills/monkey-mini-app/references/contracts/gauge.md +12 -2
  65. package/skills/monkey-mini-app/references/contracts/hover-card.md +21 -0
  66. package/skills/monkey-mini-app/references/contracts/input-group.md +24 -0
  67. package/skills/monkey-mini-app/references/contracts/input.md +33 -0
  68. package/skills/monkey-mini-app/references/contracts/item.md +36 -0
  69. package/skills/monkey-mini-app/references/contracts/jira-wiki.md +3 -4
  70. package/skills/monkey-mini-app/references/contracts/jql-input.md +15 -8
  71. package/skills/monkey-mini-app/references/contracts/json-viewer.md +20 -2
  72. package/skills/monkey-mini-app/references/contracts/kanban-issue-panel.md +12 -2
  73. package/skills/monkey-mini-app/references/contracts/kanban.md +10 -2
  74. package/skills/monkey-mini-app/references/contracts/kbd.md +20 -0
  75. package/skills/monkey-mini-app/references/contracts/label.md +33 -0
  76. package/skills/monkey-mini-app/references/contracts/list-detail.md +46 -0
  77. package/skills/monkey-mini-app/references/contracts/log-viewer.md +45 -4
  78. package/skills/monkey-mini-app/references/contracts/markdown-editor.md +20 -2
  79. package/skills/monkey-mini-app/references/contracts/markdown.md +12 -2
  80. package/skills/monkey-mini-app/references/contracts/marker.md +30 -0
  81. package/skills/monkey-mini-app/references/contracts/menubar.md +34 -0
  82. package/skills/monkey-mini-app/references/contracts/message-scroller.md +24 -0
  83. package/skills/monkey-mini-app/references/contracts/message.md +24 -0
  84. package/skills/monkey-mini-app/references/contracts/mini-calendar.md +20 -2
  85. package/skills/monkey-mini-app/references/contracts/native-select.md +21 -0
  86. package/skills/monkey-mini-app/references/contracts/navigation-menu.md +27 -0
  87. package/skills/monkey-mini-app/references/contracts/notification-center.md +12 -2
  88. package/skills/monkey-mini-app/references/contracts/number-field.md +20 -2
  89. package/skills/monkey-mini-app/references/contracts/page-header.md +2 -2
  90. package/skills/monkey-mini-app/references/contracts/pagination.md +33 -0
  91. package/skills/monkey-mini-app/references/contracts/password-field.md +12 -2
  92. package/skills/monkey-mini-app/references/contracts/phone-input.md +12 -2
  93. package/skills/monkey-mini-app/references/contracts/popover.md +32 -0
  94. package/skills/monkey-mini-app/references/contracts/progress-ring.md +12 -2
  95. package/skills/monkey-mini-app/references/contracts/progress.md +39 -0
  96. package/skills/monkey-mini-app/references/contracts/questionnaire.md +33 -0
  97. package/skills/monkey-mini-app/references/contracts/radar-chart.md +12 -2
  98. package/skills/monkey-mini-app/references/contracts/radio-group.md +20 -0
  99. package/skills/monkey-mini-app/references/contracts/rating.md +12 -2
  100. package/skills/monkey-mini-app/references/contracts/relative-date-picker.md +20 -2
  101. package/skills/monkey-mini-app/references/contracts/request-inspector.md +12 -2
  102. package/skills/monkey-mini-app/references/contracts/resizable.md +29 -0
  103. package/skills/monkey-mini-app/references/contracts/reveal.md +31 -0
  104. package/skills/monkey-mini-app/references/contracts/rich-text-editor.md +14 -2
  105. package/skills/monkey-mini-app/references/contracts/run-timeline.md +20 -2
  106. package/skills/monkey-mini-app/references/contracts/scroll-area.md +20 -0
  107. package/skills/monkey-mini-app/references/contracts/scrollspy.md +20 -2
  108. package/skills/monkey-mini-app/references/contracts/search-input.md +12 -2
  109. package/skills/monkey-mini-app/references/contracts/select.md +36 -0
  110. package/skills/monkey-mini-app/references/contracts/separator.md +27 -0
  111. package/skills/monkey-mini-app/references/contracts/settings-split.md +53 -0
  112. package/skills/monkey-mini-app/references/contracts/severity-chip.md +12 -2
  113. package/skills/monkey-mini-app/references/contracts/sheet.md +34 -0
  114. package/skills/monkey-mini-app/references/contracts/sidebar.md +42 -0
  115. package/skills/monkey-mini-app/references/contracts/skeleton.md +33 -0
  116. package/skills/monkey-mini-app/references/contracts/slider-range.md +12 -2
  117. package/skills/monkey-mini-app/references/contracts/slider.md +25 -0
  118. package/skills/monkey-mini-app/references/contracts/sortable-list.md +20 -2
  119. package/skills/monkey-mini-app/references/contracts/sparkline.md +12 -2
  120. package/skills/monkey-mini-app/references/contracts/spinner.md +31 -0
  121. package/skills/monkey-mini-app/references/contracts/stacked-bar-chart.md +16 -2
  122. package/skills/monkey-mini-app/references/contracts/stat-card.md +2 -2
  123. package/skills/monkey-mini-app/references/contracts/status-badge.md +2 -2
  124. package/skills/monkey-mini-app/references/contracts/stepper-item.md +39 -0
  125. package/skills/monkey-mini-app/references/contracts/stepper.md +38 -11
  126. package/skills/monkey-mini-app/references/contracts/switch.md +25 -0
  127. package/skills/monkey-mini-app/references/contracts/table-page.md +41 -0
  128. package/skills/monkey-mini-app/references/contracts/table.md +42 -0
  129. package/skills/monkey-mini-app/references/contracts/tabs.md +31 -0
  130. package/skills/monkey-mini-app/references/contracts/tag-input.md +12 -2
  131. package/skills/monkey-mini-app/references/contracts/terminal.md +13 -2
  132. package/skills/monkey-mini-app/references/contracts/test-step-list.md +12 -2
  133. package/skills/monkey-mini-app/references/contracts/textarea.md +25 -0
  134. package/skills/monkey-mini-app/references/contracts/time-picker.md +18 -2
  135. package/skills/monkey-mini-app/references/contracts/time-range-picker.md +20 -2
  136. package/skills/monkey-mini-app/references/contracts/time-wheel.md +6 -2
  137. package/skills/monkey-mini-app/references/contracts/timeline.md +20 -2
  138. package/skills/monkey-mini-app/references/contracts/timezone-select.md +20 -2
  139. package/skills/monkey-mini-app/references/contracts/toast.md +39 -0
  140. package/skills/monkey-mini-app/references/contracts/toggle-group.md +28 -0
  141. package/skills/monkey-mini-app/references/contracts/toggle.md +26 -0
  142. package/skills/monkey-mini-app/references/contracts/tooltip.md +30 -0
  143. package/skills/monkey-mini-app/references/contracts/transfer.md +12 -2
  144. package/skills/monkey-mini-app/references/contracts/tree-view.md +20 -2
  145. package/skills/monkey-mini-app/references/contracts/trend-card.md +12 -2
  146. package/skills/monkey-mini-app/references/contracts/user-picker.md +12 -2
  147. package/skills/monkey-mini-app/references/contracts/wizard-shell.md +56 -0
  148. package/skills/monkey-mini-app/references/ctx.md +123 -53
  149. package/skills/monkey-mini-app/references/eval.md +115 -0
  150. package/skills/monkey-mini-app/references/examples/alert/alert-01.tsx +17 -0
  151. package/skills/monkey-mini-app/references/examples/aspect-ratio/aspect-ratio-01.tsx +16 -0
  152. package/skills/monkey-mini-app/references/examples/attachment/attachment-01.tsx +19 -0
  153. package/skills/monkey-mini-app/references/examples/breadcrumb/breadcrumb-01.tsx +31 -0
  154. package/skills/monkey-mini-app/references/examples/bubble/bubble-01.tsx +16 -0
  155. package/skills/monkey-mini-app/references/examples/button-group/button-group-01.tsx +23 -0
  156. package/skills/monkey-mini-app/references/examples/card/card-01.tsx +19 -0
  157. package/skills/monkey-mini-app/references/examples/charts-blocks.md +15 -0
  158. package/skills/monkey-mini-app/references/examples/code-block/code-block-01.tsx +14 -0
  159. package/skills/monkey-mini-app/references/examples/code-editor/code-editor-01.tsx +15 -0
  160. package/skills/monkey-mini-app/references/examples/command/command-01.tsx +30 -0
  161. package/skills/monkey-mini-app/references/examples/confirm-dialog/confirm-dialog-01.tsx +33 -0
  162. package/skills/monkey-mini-app/references/examples/context-menu/context-menu-01.tsx +29 -0
  163. package/skills/monkey-mini-app/references/examples/dashboard-shell/dashboard-shell-01.tsx +78 -0
  164. package/skills/monkey-mini-app/references/examples/data-grid/data-grid-01.tsx +34 -0
  165. package/skills/monkey-mini-app/references/examples/data-grid/data-grid-02.tsx +88 -0
  166. package/skills/monkey-mini-app/references/examples/date-picker/date-picker-01.tsx +14 -0
  167. package/skills/monkey-mini-app/references/examples/date-range-picker/date-range-picker-01.tsx +14 -0
  168. package/skills/monkey-mini-app/references/examples/date-time-picker/date-time-picker-01.tsx +16 -0
  169. package/skills/monkey-mini-app/references/examples/date-time-range-picker/date-time-range-picker-01.tsx +15 -0
  170. package/skills/monkey-mini-app/references/examples/detail-panel/detail-panel-01.tsx +21 -0
  171. package/skills/monkey-mini-app/references/examples/dialog/dialog-01.tsx +30 -0
  172. package/skills/monkey-mini-app/references/examples/diff-viewer/diff-viewer-01.tsx +10 -0
  173. package/skills/monkey-mini-app/references/examples/dropdown-menu/dropdown-menu-01.tsx +31 -0
  174. package/skills/monkey-mini-app/references/examples/duration-input/duration-input-01.tsx +20 -0
  175. package/skills/monkey-mini-app/references/examples/editors.md +11 -0
  176. package/skills/monkey-mini-app/references/examples/empty/empty-01.tsx +19 -0
  177. package/skills/monkey-mini-app/references/examples/event-calendar/event-calendar-01.tsx +53 -0
  178. package/skills/monkey-mini-app/references/examples/file-dropzone/file-dropzone-01.tsx +14 -0
  179. package/skills/monkey-mini-app/references/examples/form-sheet/form-sheet-01.tsx +85 -0
  180. package/skills/monkey-mini-app/references/examples/forms.md +16 -0
  181. package/skills/monkey-mini-app/references/examples/gantt/gantt-01.tsx +29 -0
  182. package/skills/monkey-mini-app/references/examples/input/input-01.tsx +10 -0
  183. package/skills/monkey-mini-app/references/examples/item/item-01.tsx +19 -0
  184. package/skills/monkey-mini-app/references/examples/jql-input/jql-input-01.tsx +33 -0
  185. package/skills/monkey-mini-app/references/examples/json-viewer/json-viewer-01.tsx +10 -0
  186. package/skills/monkey-mini-app/references/examples/kanban/kanban-01.tsx +60 -0
  187. package/skills/monkey-mini-app/references/examples/label/label-01.tsx +10 -0
  188. package/skills/monkey-mini-app/references/examples/list-detail/list-detail-01.tsx +117 -0
  189. package/skills/monkey-mini-app/references/examples/log-viewer/log-viewer-01.tsx +20 -0
  190. package/skills/monkey-mini-app/references/examples/markdown-editor/markdown-editor-01.tsx +18 -0
  191. package/skills/monkey-mini-app/references/examples/marker/marker-01.tsx +16 -0
  192. package/skills/monkey-mini-app/references/examples/mini-calendar/mini-calendar-01.tsx +14 -0
  193. package/skills/monkey-mini-app/references/examples/misc-charts-blocks/misc-charts-blocks-01.tsx +20 -0
  194. package/skills/monkey-mini-app/references/examples/misc-charts-blocks/misc-charts-blocks-02.tsx +32 -0
  195. package/skills/monkey-mini-app/references/examples/misc-charts-blocks/misc-charts-blocks-03.tsx +47 -0
  196. package/skills/monkey-mini-app/references/examples/misc-charts-blocks/misc-charts-blocks-04.tsx +20 -0
  197. package/skills/monkey-mini-app/references/examples/misc-charts-blocks/misc-charts-blocks-05.tsx +24 -0
  198. package/skills/monkey-mini-app/references/examples/misc-charts-blocks/misc-charts-blocks-06.tsx +89 -0
  199. package/skills/monkey-mini-app/references/examples/misc-editors/misc-editors-01.tsx +114 -0
  200. package/skills/monkey-mini-app/references/examples/misc-editors/misc-editors-02.tsx +33 -0
  201. package/skills/monkey-mini-app/references/examples/misc-forms/misc-forms-01.tsx +22 -0
  202. package/skills/monkey-mini-app/references/examples/misc-forms/misc-forms-02.tsx +37 -0
  203. package/skills/monkey-mini-app/references/examples/misc-forms/misc-forms-03.tsx +42 -0
  204. package/skills/monkey-mini-app/references/examples/misc-forms/misc-forms-04.tsx +25 -0
  205. package/skills/monkey-mini-app/references/examples/misc-forms/misc-forms-05.tsx +27 -0
  206. package/skills/monkey-mini-app/references/examples/misc-forms/misc-forms-06.tsx +33 -0
  207. package/skills/monkey-mini-app/references/examples/misc-forms/misc-forms-07.tsx +44 -0
  208. package/skills/monkey-mini-app/references/examples/misc-overlays/misc-overlays-01.tsx +43 -0
  209. package/skills/monkey-mini-app/references/examples/misc-overlays/misc-overlays-02.tsx +38 -0
  210. package/skills/monkey-mini-app/references/examples/misc-primitives/misc-primitives-01.tsx +21 -0
  211. package/skills/monkey-mini-app/references/examples/misc-primitives/misc-primitives-02.tsx +52 -0
  212. package/skills/monkey-mini-app/references/examples/misc-primitives/misc-primitives-03.tsx +44 -0
  213. package/skills/monkey-mini-app/references/examples/number-field/number-field-01.tsx +22 -0
  214. package/skills/monkey-mini-app/references/examples/overlays.md +11 -0
  215. package/skills/monkey-mini-app/references/examples/pagination/pagination-01.tsx +51 -0
  216. package/skills/monkey-mini-app/references/examples/primitives.md +12 -0
  217. package/skills/monkey-mini-app/references/examples/progress/progress-01.tsx +10 -0
  218. package/skills/monkey-mini-app/references/examples/relative-date-picker/relative-date-picker-01.tsx +19 -0
  219. package/skills/monkey-mini-app/references/examples/rich-text-editor/rich-text-editor-01.tsx +15 -0
  220. package/skills/monkey-mini-app/references/examples/run-timeline/run-timeline-01.tsx +17 -0
  221. package/skills/monkey-mini-app/references/examples/scrollspy/scrollspy-01.tsx +29 -0
  222. package/skills/monkey-mini-app/references/examples/separator/separator-01.tsx +10 -0
  223. package/skills/monkey-mini-app/references/examples/settings-split/settings-split-01.tsx +84 -0
  224. package/skills/monkey-mini-app/references/examples/shared/jira-wiki-sample.ts +38 -0
  225. package/skills/monkey-mini-app/references/examples/skeleton/skeleton-01.tsx +10 -0
  226. package/skills/monkey-mini-app/references/examples/slider/slider-01.tsx +22 -0
  227. package/skills/monkey-mini-app/references/examples/sortable-list/sortable-list-01.tsx +18 -0
  228. package/skills/monkey-mini-app/references/examples/spinner/spinner-01.tsx +10 -0
  229. package/skills/monkey-mini-app/references/examples/stepper/stepper-01.tsx +41 -0
  230. package/skills/monkey-mini-app/references/examples/table/table-01.tsx +25 -0
  231. package/skills/monkey-mini-app/references/examples/table-page/table-page-01.tsx +103 -0
  232. package/skills/monkey-mini-app/references/examples/time-picker/time-picker-01.tsx +19 -0
  233. package/skills/monkey-mini-app/references/examples/time-range-picker/time-range-picker-01.tsx +14 -0
  234. package/skills/monkey-mini-app/references/examples/timeline/timeline-01.tsx +18 -0
  235. package/skills/monkey-mini-app/references/examples/timezone-select/timezone-select-01.tsx +15 -0
  236. package/skills/monkey-mini-app/references/examples/toggle/toggle-01.tsx +20 -0
  237. package/skills/monkey-mini-app/references/examples/toggle-group/toggle-group-01.tsx +22 -0
  238. package/skills/monkey-mini-app/references/examples/tree-view/tree-view-01.tsx +25 -0
  239. package/skills/monkey-mini-app/references/examples/wizard-shell/wizard-shell-01.tsx +58 -0
  240. package/skills/monkey-mini-app/references/history.md +23 -7
  241. package/skills/monkey-mini-app/references/icons.md +99 -69
  242. package/skills/monkey-mini-app/references/llm-json.md +39 -26
  243. package/skills/monkey-mini-app/references/loader.md +47 -20
  244. package/skills/monkey-mini-app/references/looks/aurora-bento.md +88 -0
  245. package/skills/monkey-mini-app/references/looks/desk-split.md +89 -0
  246. package/skills/monkey-mini-app/references/looks/editorial.md +78 -0
  247. package/skills/monkey-mini-app/references/looks/glass-island.md +90 -0
  248. package/skills/monkey-mini-app/references/looks/index.md +18 -0
  249. package/skills/monkey-mini-app/references/looks/signage.md +74 -0
  250. package/skills/monkey-mini-app/references/looks/tape.md +22 -0
  251. package/skills/monkey-mini-app/references/looks/terminal.md +88 -0
  252. package/skills/monkey-mini-app/references/looks/void.md +22 -0
  253. package/skills/monkey-mini-app/references/styling.md +189 -0
  254. package/skills/monkey-mini-app/references/test.md +12 -12
  255. package/skills/monkey-mini-app/references/theme.md +197 -0
  256. package/skills/monkey-mini-app/references/tools.md +12 -12
  257. package/skills/monkey-mini-app/references/troubleshoot.md +165 -12
  258. package/skills/monkey-mini-app/templates/README.md +33 -21
  259. package/skills/monkey-mini-app/templates/{jira → board}/main.api.ts +11 -11
  260. package/skills/monkey-mini-app/templates/board/manifest.json +8 -0
  261. package/skills/monkey-mini-app/templates/board/theme.css +46 -0
  262. package/skills/monkey-mini-app/templates/board/ui.tsx +546 -0
  263. package/skills/monkey-mini-app/templates/chores/main.api.ts +35 -0
  264. package/skills/monkey-mini-app/templates/chores/manifest.json +8 -0
  265. package/skills/monkey-mini-app/templates/chores/theme.css +46 -0
  266. package/skills/monkey-mini-app/templates/chores/ui.tsx +117 -0
  267. package/skills/monkey-mini-app/templates/minimal/main.api.ts +5 -5
  268. package/skills/monkey-mini-app/templates/minimal/manifest.json +1 -2
  269. package/skills/monkey-mini-app/templates/minimal/ui.tsx +17 -8
  270. package/skills/monkey-mini-app/templates/radar/api/scan.ts +79 -0
  271. package/skills/monkey-mini-app/templates/radar/main.api.ts +29 -0
  272. package/skills/monkey-mini-app/templates/radar/manifest.json +8 -0
  273. package/skills/monkey-mini-app/templates/radar/shared/events.ts +25 -0
  274. package/skills/monkey-mini-app/templates/{insights/lib → radar/shared}/sample.ts +1 -1
  275. package/skills/monkey-mini-app/templates/radar/theme.css +47 -0
  276. package/skills/monkey-mini-app/templates/radar/ui/brief.tsx +31 -0
  277. package/skills/monkey-mini-app/templates/radar/ui.tsx +131 -0
  278. package/skills/monkey-mini-app/templates/runner/main.api.ts +91 -0
  279. package/skills/monkey-mini-app/templates/runner/manifest.json +8 -0
  280. package/skills/monkey-mini-app/templates/runner/shared/events.ts +14 -0
  281. package/skills/monkey-mini-app/templates/runner/theme.css +46 -0
  282. package/skills/monkey-mini-app/templates/runner/ui.tsx +213 -0
  283. package/skills/monkey-mini-app/templates/sheets/main.api.ts +276 -0
  284. package/skills/monkey-mini-app/templates/sheets/manifest.json +8 -0
  285. package/skills/monkey-mini-app/templates/sheets/theme.css +46 -0
  286. package/skills/monkey-mini-app/templates/sheets/ui.tsx +419 -0
  287. package/skills/monkey-mini-app/templates/{todo → today}/main.api.ts +8 -8
  288. package/skills/monkey-mini-app/templates/today/manifest.json +8 -0
  289. package/skills/monkey-mini-app/templates/today/theme.css +45 -0
  290. package/skills/monkey-mini-app/templates/today/ui/item-row.tsx +25 -0
  291. package/skills/monkey-mini-app/templates/today/ui.tsx +406 -0
  292. package/skills/monkey-mini-app/templates/{monitor → watch}/main.api.ts +8 -8
  293. package/skills/monkey-mini-app/templates/watch/manifest.json +8 -0
  294. package/skills/monkey-mini-app/templates/watch/ui.tsx +187 -0
  295. package/skills/monkey-mini-app/tsconfig.json +31 -0
  296. package/skills/monkey-mini-app/types/cdn.d.ts +1 -0
  297. package/tsup.config.ts +1 -0
  298. package/skills/monkey-mini-app/templates/agentrun/main.api.ts +0 -78
  299. package/skills/monkey-mini-app/templates/agentrun/manifest.json +0 -9
  300. package/skills/monkey-mini-app/templates/agentrun/ui.tsx +0 -125
  301. package/skills/monkey-mini-app/templates/insights/main.api.ts +0 -101
  302. package/skills/monkey-mini-app/templates/insights/manifest.json +0 -9
  303. package/skills/monkey-mini-app/templates/insights/ui.tsx +0 -138
  304. package/skills/monkey-mini-app/templates/jira/manifest.json +0 -9
  305. package/skills/monkey-mini-app/templates/jira/ui.tsx +0 -318
  306. package/skills/monkey-mini-app/templates/monitor/manifest.json +0 -9
  307. package/skills/monkey-mini-app/templates/monitor/ui.tsx +0 -176
  308. package/skills/monkey-mini-app/templates/review/main.api.ts +0 -68
  309. package/skills/monkey-mini-app/templates/review/manifest.json +0 -9
  310. package/skills/monkey-mini-app/templates/review/ui.tsx +0 -159
  311. package/skills/monkey-mini-app/templates/todo/manifest.json +0 -8
  312. package/skills/monkey-mini-app/templates/todo/ui.tsx +0 -177
@@ -0,0 +1,117 @@
1
+ import { useEffect, useState } from "react";
2
+
3
+ import { Badge, Button, Icon, Terminal, useApp } from "@monkey-mini-app/ui";
4
+
5
+ type Job = { id: string; title: string };
6
+ type Run = {
7
+ id: string;
8
+ title: string;
9
+ command: string;
10
+ stdout: string;
11
+ stderr: string;
12
+ exitCode: number;
13
+ at: number;
14
+ };
15
+
16
+ export default function Ui() {
17
+ const { call } = useApp();
18
+ const [jobs, setJobs] = useState<Job[]>([]);
19
+ const [run, setRun] = useState<Run | null>(null);
20
+ const [busy, setBusy] = useState<string | null>(null);
21
+ const [error, setError] = useState<string | null>(null);
22
+
23
+ useEffect(() => {
24
+ void call("jobs", {}).then((d) =>
25
+ setJobs((d as { jobs: Job[] }).jobs ?? []),
26
+ );
27
+ }, [call]);
28
+
29
+ async function runJob(id: string) {
30
+ setBusy(id);
31
+ setError(null);
32
+ try {
33
+ setRun((await call("run", { id })) as Run);
34
+ } catch (e) {
35
+ setError(String((e as Error)?.message || e));
36
+ } finally {
37
+ setBusy(null);
38
+ }
39
+ }
40
+
41
+ const lines = run
42
+ ? [
43
+ `$ ${run.command}`,
44
+ run.stdout.trim() || "(no stdout)",
45
+ run.stderr.trim() ? `stderr:\n${run.stderr.trim()}` : "",
46
+ `exit ${run.exitCode}`,
47
+ ].filter(Boolean)
48
+ : ["点一个按钮。没有对话框,没有模型。"];
49
+
50
+ return (
51
+ // ⭐ Look: terminal — buttons on top, kit Terminal well below. Never a prompt box.
52
+ <div className="flex h-full min-h-0 flex-col bg-background">
53
+ <div className="flex items-center gap-2 border-b px-4 py-3">
54
+ {/* one state lamp, not three decorative traffic lights: colour = state, and a literal
55
+ `fill-emerald-400` would fight this look's phosphor ground. */}
56
+ <span
57
+ className={`size-2 rounded-full ${busy ? "bg-primary/50" : run ? (run.exitCode === 0 ? "bg-primary" : "bg-destructive") : "bg-muted-foreground/40"}`}
58
+ />
59
+ <span className="font-mono text-xs">chores</span>
60
+ {run ? (
61
+ <Badge
62
+ variant={run.exitCode === 0 ? "default" : "destructive"}
63
+ className="ml-auto"
64
+ >
65
+ {run.exitCode === 0 ? "ok" : "fail"}
66
+ </Badge>
67
+ ) : null}
68
+ </div>
69
+ <div className="flex flex-wrap gap-2 px-4 py-3">
70
+ {jobs.map((j) => (
71
+ <Button
72
+ key={j.id}
73
+ size="sm"
74
+ variant="outline"
75
+ disabled={busy !== null}
76
+ onClick={() => void runJob(j.id)}
77
+ >
78
+ {busy === j.id ? (
79
+ <Icon.Loader2 className="animate-spin" size={14} />
80
+ ) : (
81
+ <Icon.Play size={14} />
82
+ )}
83
+ {j.title}
84
+ </Button>
85
+ ))}
86
+ </div>
87
+ {error ? <p className="text-destructive px-4 text-sm">{error}</p> : null}
88
+ <div className="min-h-0 flex-1 p-3">
89
+ {/* ⭐ Same phosphor well as `runner`: token surfaces instead of the kit's hard zinc,
90
+ green glow, scanlines + vignette on a click-through overlay. */}
91
+ <div
92
+ className="border-border relative h-full min-h-0 overflow-hidden rounded-lg border"
93
+ style={{
94
+ textShadow:
95
+ "0 0 6px color-mix(in oklch, var(--primary) 65%, transparent)",
96
+ }}
97
+ >
98
+ <Terminal
99
+ className="bg-card text-card-foreground h-full rounded-lg"
100
+ lines={
101
+ lines.length ? lines : ["$ 挑一个上面的按钮,本机跑一条", "$ █"]
102
+ }
103
+ />
104
+ <div
105
+ aria-hidden
106
+ className="pointer-events-none absolute inset-0"
107
+ style={{
108
+ backgroundImage:
109
+ "repeating-linear-gradient(0deg, color-mix(in oklch, var(--foreground) 7%, transparent) 0 1px, transparent 1px 3px)," +
110
+ "radial-gradient(120% 90% at 50% 40%, transparent 62%, var(--shadow))",
111
+ }}
112
+ />
113
+ </div>
114
+ </div>
115
+ </div>
116
+ );
117
+ }
@@ -1,14 +1,14 @@
1
- import { defineDashboard } from "@monkeyagent/dashboard";
1
+ import { defineApp } from "@monkey-mini-app/api";
2
2
 
3
- export default defineDashboard({
3
+ export default defineApp({
4
4
  name: "骨架示例",
5
5
  description: "最小可运行:一次 call 往返 + 读 Host 配置",
6
6
  api: {
7
- // ⭐ 关键:每个方法都拿到同一个 ctx —— appId / appDir / storage / config / log / 能力(这页不用)
7
+ // ⭐ key: every method receives the same ctx appId / appDir / storage / config / log / capabilities (unused on this page)
8
8
  async ping(ctx) {
9
9
  return {
10
- appId: ctx.appId, // 当前小程序 reverse-DNS id
11
- theme: ctx.config?.theme ?? "light", // 跟随 Host 设置(设置页 / 顶栏可改)
10
+ appId: ctx.appId, // reverse-DNS id of the current mini-app
11
+ theme: ctx.config?.theme ?? "light", // follows the Host theme (changeable in Settings / top bar)
12
12
  now: Date.now(),
13
13
  };
14
14
  },
@@ -3,6 +3,5 @@
3
3
  "name": "骨架示例",
4
4
  "description": "最小可运行结构:一次 call 往返 + 读 Host 配置",
5
5
  "version": "0.1.0",
6
- "entry": "ui.tsx",
7
- "theme": { "followsHost": true }
6
+ "entry": "ui.tsx"
8
7
  }
@@ -1,20 +1,29 @@
1
1
  import { useEffect, useState } from "react";
2
2
 
3
- import { AppShell, Badge, Card, CardContent, CardHeader, CardTitle, Icon, PageHeader } from "@monkey-mini-app/ui";
4
- import { useDashboardApi } from "@monkeyagent/host";
3
+ import {
4
+ AppShell,
5
+ Badge,
6
+ Card,
7
+ CardContent,
8
+ CardHeader,
9
+ CardTitle,
10
+ Icon,
11
+ PageHeader,
12
+ useApp,
13
+ } from "@monkey-mini-app/ui";
5
14
 
6
15
  type Ping = { appId: string; theme: string; now: number };
7
16
 
8
17
  export default function Ui() {
9
- // ⭐ 关键:访问后端**只有**一个入口 —— useDashboardApi().call(method, args)
10
- // method 必须是 defineDashboard({ api }) 的键;UI 永不 import main.api.ts
11
- const { call } = useDashboardApi();
18
+ // ⭐ key: the backend is reachable through **one** entry only — useApp().call(method, args)
19
+ // method must be a key of defineApp({ api }); the UI never imports main.api.ts.
20
+ const { call } = useApp();
12
21
  const [data, setData] = useState<Ping | null>(null);
13
22
  const [loading, setLoading] = useState(true);
14
23
  const [error, setError] = useState<string | null>(null);
15
24
 
16
25
  useEffect(() => {
17
- // ⭐ 关键:组件卸载后别 setState(长/慢任务与取消配套见 insights / agentrun)
26
+ // ⭐ key: don't setState after the component unmounts (long/slow tasks with cancellation: see radar / runner)
18
27
  let alive = true;
19
28
  (async () => {
20
29
  try {
@@ -35,8 +44,8 @@ export default function Ui() {
35
44
  const label = error ? "出错" : loading ? "连接中" : "正常";
36
45
 
37
46
  return (
38
- // ⭐ 关键:页面用 AppShell 包一层(可选 sidebar/header),页头用 PageHeader
39
- // 这里是「骨架基线」;别的模板会在 main 里放列表/看板/图表。
47
+ // ⭐ key: wrap the page in AppShell (optional sidebar/header), use PageHeader for the page header.
48
+ // This is the "skeleton baseline"; other templates put lists/kanban/charts inside main.
40
49
  <AppShell header={<PageHeader title="骨架示例" description="最小可运行结构" />}>
41
50
  <div className="max-w-xl">
42
51
  <Card>
@@ -0,0 +1,79 @@
1
+ import { EV, type Payload, type Progress } from "../shared/events";
2
+ import { SAMPLE_ITEMS } from "../shared/sample";
3
+
4
+ const DIGEST_SCHEMA = {
5
+ type: "object",
6
+ properties: {
7
+ headline: { type: "string" },
8
+ bullets: { type: "array", items: { type: "string" } },
9
+ },
10
+ required: ["headline", "bullets"],
11
+ };
12
+
13
+ function parseDigest(raw: string): { headline: string; bullets: string[] } {
14
+ let value: { headline?: unknown; bullets?: unknown };
15
+ try {
16
+ value = JSON.parse(raw);
17
+ } catch {
18
+ throw new Error("模型没有返回 JSON:" + String(raw).slice(0, 180));
19
+ }
20
+ const headline = String(value?.headline ?? "").trim();
21
+ const bullets = Array.isArray(value.bullets)
22
+ ? value.bullets.map((b) => String(b).trim()).filter(Boolean).slice(0, 3)
23
+ : [];
24
+ if (!headline || bullets.length !== 3) throw new Error("摘要格式不对");
25
+ return { headline, bullets };
26
+ }
27
+
28
+ function sleep(ms: number, signal?: AbortSignal) {
29
+ return new Promise<void>((resolve) => {
30
+ if (signal?.aborted) return resolve();
31
+ const t = setTimeout(resolve, ms);
32
+ signal?.addEventListener(
33
+ "abort",
34
+ () => {
35
+ clearTimeout(t);
36
+ resolve();
37
+ },
38
+ { once: true },
39
+ );
40
+ });
41
+ }
42
+
43
+ // ⭐ key: long job lives in api/ (backend only). UI must not import this file.
44
+ export async function runRefresh(ctx): Promise<Payload> {
45
+ const items = SAMPLE_ITEMS.slice(0, 8);
46
+ const report = async (partial: Partial<Progress>) => {
47
+ const next: Progress = { running: true, step: "refresh", done: 0, total: 3, ...partial };
48
+ await ctx.storage.set("progress", next);
49
+ ctx.push(EV.progress, next);
50
+ };
51
+ try {
52
+ await report({ step: "fetch·sample 8/8", done: 1 });
53
+ if (ctx.signal?.aborted) throw new Error("cancelled");
54
+ await sleep(300, ctx.signal);
55
+
56
+ await report({ step: "summarize#1/1", done: 2 });
57
+ const raw = await ctx.llm(
58
+ "根据这些标题写一条中文 headline,以及恰好 3 条中文 bullets。不要前言:\n" +
59
+ items.map((i) => "- " + i.title).join("\n"),
60
+ { schema: DIGEST_SCHEMA },
61
+ );
62
+ if (ctx.signal?.aborted) throw new Error("cancelled");
63
+ const digest = parseDigest(raw);
64
+
65
+ const payload: Payload = { items, digest, at: Date.now() };
66
+ await ctx.storage.set("latest", payload);
67
+ const done: Progress = { running: false, step: "done", done: 3, total: 3 };
68
+ await ctx.storage.set("progress", done);
69
+ ctx.push(EV.progress, done);
70
+ ctx.push(EV.latest, payload);
71
+ return payload;
72
+ } catch (cause) {
73
+ const message = cause instanceof Error ? cause.message : String(cause);
74
+ const failed: Progress = { running: false, step: "failed", done: 0, total: 3, error: message };
75
+ await ctx.storage.set("progress", failed);
76
+ ctx.push(EV.progress, failed);
77
+ throw new Error("摘要失败:" + message);
78
+ }
79
+ }
@@ -0,0 +1,29 @@
1
+ import { defineApp } from "@monkey-mini-app/api";
2
+
3
+ import { runRefresh } from "./api/scan";
4
+ import { type Payload, type Progress } from "./shared/events";
5
+ import { SAMPLE_ITEMS } from "./shared/sample";
6
+
7
+ export default defineApp({
8
+ name: "信息雷达",
9
+ description: "拉源、做简报、长任务可取消",
10
+ api: {
11
+ async latest(ctx): Promise<Payload> {
12
+ return (await ctx.storage.get("latest")) || { items: SAMPLE_ITEMS, digest: null, at: 0 };
13
+ },
14
+
15
+ // fire-and-forget: returns immediately; api/scan.ts pushes progress over SSE
16
+ async scan(ctx) {
17
+ void runRefresh(ctx);
18
+ return { ok: true };
19
+ },
20
+
21
+ async scanStatus(ctx): Promise<Progress> {
22
+ return (await ctx.storage.get("progress")) || { running: false, step: "idle", done: 0, total: 3 };
23
+ },
24
+
25
+ async refresh(ctx) {
26
+ return runRefresh(ctx);
27
+ },
28
+ },
29
+ });
@@ -0,0 +1,8 @@
1
+ {
2
+ "id": "com.example.radar",
3
+ "name": "信息雷达",
4
+ "description": "拉源、做简报、长任务可取消",
5
+ "version": "0.1.0",
6
+ "entry": "ui.tsx",
7
+ "acronym": "LD"
8
+ }
@@ -0,0 +1,25 @@
1
+ // ⭐ key: names AND payloads live here so ui.tsx and api/ cannot drift.
2
+ // Pure isomorphic: no React, no ctx, no DOM, no Node.
3
+ export const EV = {
4
+ progress: "progress",
5
+ latest: "latest",
6
+ } as const;
7
+
8
+ export type Events = {
9
+ progress: {
10
+ running: boolean;
11
+ step: string;
12
+ done: number;
13
+ total: number;
14
+ error?: string;
15
+ };
16
+ latest: {
17
+ items: { title: string; link?: string }[];
18
+ digest: { headline: string; bullets: string[] } | null;
19
+ at: number;
20
+ };
21
+ };
22
+
23
+ export type EventName = keyof Events;
24
+ export type Progress = Events["progress"];
25
+ export type Payload = Events["latest"];
@@ -1,6 +1,6 @@
1
1
  export type FeedItem = { title: string; link?: string };
2
2
 
3
- // 内置样例源:默认不走网络,保证离线也能跑起来(教"采样走通全链路"
3
+ // Built-in sample feed: no network by default so it runs offline (teaches "prove the full pipeline with a sample")
4
4
  export const SAMPLE_ITEMS: FeedItem[] = [
5
5
  { title: "TypeScript 5.7 发布:更快的类型检查与更好的模块解析", link: "https://example.com/ts57" },
6
6
  { title: "Vite 6 默认启用 Rolldown 路线图", link: "https://example.com/vite6" },
@@ -0,0 +1,47 @@
1
+ /* name: 编辑排版 */
2
+ /* Look-owned palette: paper and ink are the identity — under the default kit palette the
3
+ page is just text and reads as "unfinished". Light is newsprint with vermilion (E1),
4
+ dark is cool night-reading stock with ultramarine (E2). Radius is small: this look is
5
+ rules and type, not cards. */
6
+ :root[data-mode="light"] {
7
+ --bg: #f6f2e9;
8
+ --fg: #1c1a16;
9
+ --surface: #fffdf7;
10
+ --surface-fg: #1c1a16;
11
+ --border: #e0d9c9;
12
+ --muted: #ece5d6;
13
+ --muted-fg: #6d675c;
14
+ --primary: #c0402a;
15
+ --primary-fg: #fff8f5;
16
+ --secondary: #efe8da;
17
+ --secondary-fg: #1c1a16;
18
+ --accent: #f1e9d9;
19
+ --accent-fg: #1c1a16;
20
+ --destructive: #8f2d22;
21
+ --destructive-fg: #fff4f1;
22
+ --ring: #c0402a;
23
+ --input: #d9d2c2;
24
+ --radius: 6px;
25
+ --shadow: rgba(60, 50, 30, 0.18);
26
+ }
27
+ :root[data-mode="dark"] {
28
+ --bg: #14161a;
29
+ --fg: #e8eaee;
30
+ --surface: #191c22;
31
+ --surface-fg: #e8eaee;
32
+ --border: #262a31;
33
+ --muted: #1d2128;
34
+ --muted-fg: #9aa0aa;
35
+ --primary: #7f95f5;
36
+ --primary-fg: #0f1216;
37
+ --secondary: #1d2128;
38
+ --secondary-fg: #e8eaee;
39
+ --accent: #1a2030;
40
+ --accent-fg: #e8eaee;
41
+ --destructive: #ff6b63;
42
+ --destructive-fg: #14060a;
43
+ --ring: #7f95f5;
44
+ --input: #2a2d31;
45
+ --radius: 6px;
46
+ --shadow: rgba(0, 0, 0, 0.5);
47
+ }
@@ -0,0 +1,31 @@
1
+ import type { Payload } from "../shared/events";
2
+
3
+ /**
4
+ * UI-only. The brief is an article, not a card: kicker → serif display → numbered bullets,
5
+ * limited measure. That is the whole `editorial` grammar (references/looks/editorial.md).
6
+ */
7
+ export function Brief({ data, stale }: { data: Payload | null; stale: boolean }) {
8
+ const digest = data?.digest;
9
+ return (
10
+ <article className="max-w-2xl">
11
+ <p className="text-muted-foreground text-xs tracking-[0.2em] uppercase">
12
+ 本期简报 {data?.at ? `· ${new Date(data.at).toLocaleDateString("zh-CN")}` : ""}
13
+ </p>
14
+ <h2 className="mt-3 font-serif text-3xl leading-snug font-bold tracking-tight">
15
+ {digest ? digest.headline : stale ? "还没有简报,点右上角整理一次" : "正在整理…"}
16
+ </h2>
17
+ {digest?.bullets?.length ? (
18
+ <ol className="text-muted-foreground mt-6 flex list-none flex-col gap-4 p-0">
19
+ {digest.bullets.map((b, i) => (
20
+ <li key={i} className="flex gap-4 text-sm leading-relaxed">
21
+ <span className="text-primary font-mono text-xs tabular-nums">
22
+ {String(i + 1).padStart(2, "0")}
23
+ </span>
24
+ <span className="text-foreground">{b}</span>
25
+ </li>
26
+ ))}
27
+ </ol>
28
+ ) : null}
29
+ </article>
30
+ );
31
+ }
@@ -0,0 +1,131 @@
1
+ import { useEffect, useState } from "react";
2
+
3
+ import {
4
+ AppShell,
5
+ Button,
6
+ DetailPanel,
7
+ Icon,
8
+ PageHeader,
9
+ Progress,
10
+ Separator,
11
+ useApp,
12
+ } from "@monkey-mini-app/ui";
13
+
14
+ import { EV, type Payload, type Progress as ScanProgress } from "./shared/events";
15
+ import { Brief } from "./ui/brief";
16
+
17
+ type Item = Payload["items"][number];
18
+
19
+ export default function Ui() {
20
+ const { call, on } = useApp();
21
+ const [data, setData] = useState<Payload | null>(null);
22
+ const [progress, setProgress] = useState<ScanProgress | null>(null);
23
+ const [selected, setSelected] = useState<Item | null>(null);
24
+ const [error, setError] = useState<string | null>(null);
25
+
26
+ const load = async () => setData((await call("latest", {})) as Payload);
27
+
28
+ // ⭐ key: on(EV.progress) / ctx.push(EV.progress) — the name exists only in shared/events.ts.
29
+ useEffect(() => {
30
+ const offProgress = on(EV.progress, (d) => {
31
+ const p = d as ScanProgress;
32
+ setProgress(p);
33
+ if (!p.running && !p.error) void load();
34
+ if (p.error) setError(p.error);
35
+ });
36
+ const offLatest = on(EV.latest, (d) => setData(d as Payload));
37
+ return () => {
38
+ offProgress();
39
+ offLatest();
40
+ };
41
+ }, [on]);
42
+
43
+ async function run() {
44
+ setError(null);
45
+ try {
46
+ await call("scan", {}); // fire-and-forget start, returns immediately
47
+ } catch (e) {
48
+ setError(String((e as Error)?.message || e));
49
+ }
50
+ }
51
+
52
+ useEffect(() => {
53
+ void load();
54
+ }, [call]);
55
+
56
+ const items = data?.items ?? [];
57
+ const running = Boolean(progress?.running);
58
+ const pct = progress && progress.total ? Math.round((progress.done / progress.total) * 100) : 0;
59
+
60
+ return (
61
+ <AppShell
62
+ header={
63
+ <PageHeader
64
+ title="信息雷达"
65
+ description="公开头条 · 模型整理成三条要点"
66
+ actions={
67
+ <Button disabled={running} onClick={() => void run()}>
68
+ <Icon.Sparkles size={16} strokeWidth={2} /> 整理
69
+ </Button>
70
+ }
71
+ />
72
+ }
73
+ >
74
+ {/* ⭐ Look: editorial — one prose column, hairline rules, a numbered index. No card soup. */}
75
+ <div className="mx-auto flex h-full min-h-0 w-full max-w-3xl flex-col gap-6 overflow-y-auto px-2 py-2">
76
+ {running ? (
77
+ <div className="flex items-center gap-3">
78
+ <Progress value={pct} className="h-1 flex-1" />
79
+ <span className="text-muted-foreground font-mono text-xs">{progress?.step}</span>
80
+ </div>
81
+ ) : null}
82
+ {error ? <p className="text-destructive text-sm">{error}</p> : null}
83
+
84
+ <Brief data={data} stale={!running} />
85
+
86
+ <Separator />
87
+
88
+ <section>
89
+ <p className="text-muted-foreground mb-2 text-xs tracking-[0.2em] uppercase">
90
+ 来源索引 · {items.length}
91
+ </p>
92
+ <ul className="list-none p-0">
93
+ {items.map((it, i) => (
94
+ <li key={it.title + i} className="border-border border-b last:border-b-0">
95
+ <button
96
+ type="button"
97
+ onClick={() => setSelected(it)}
98
+ className="hover:bg-muted/50 flex w-full items-baseline gap-4 px-2 py-3 text-left"
99
+ >
100
+ <span className="text-muted-foreground font-mono text-xs tabular-nums">
101
+ {String(i + 1).padStart(2, "0")}
102
+ </span>
103
+ <span className="min-w-0 flex-1 truncate text-sm">{it.title}</span>
104
+ <Icon.ArrowUpRight size={14} strokeWidth={2} className="text-muted-foreground shrink-0" />
105
+ </button>
106
+ </li>
107
+ ))}
108
+ </ul>
109
+ </section>
110
+ </div>
111
+
112
+ {/* reading a source is still a sheet — the look governs the page, not every overlay */}
113
+ <DetailPanel
114
+ open={Boolean(selected)}
115
+ onOpenChange={(o) => {
116
+ if (!o) setSelected(null);
117
+ }}
118
+ title={selected?.title ?? ""}
119
+ >
120
+ <div className="flex flex-col gap-3">
121
+ <p className="text-sm">{selected?.title}</p>
122
+ {selected?.link ? (
123
+ <a href={selected.link} target="_blank" rel="noreferrer" className="text-primary text-xs hover:underline">
124
+ 阅读原文
125
+ </a>
126
+ ) : null}
127
+ </div>
128
+ </DetailPanel>
129
+ </AppShell>
130
+ );
131
+ }
@@ -0,0 +1,91 @@
1
+ import { defineApp } from "@monkey-mini-app/api";
2
+
3
+ import { EV, type Run, type Step } from "./shared/events";
4
+
5
+ // ⭐ key: ctx.agent is the entry point for "have the model do one multi-step job"; it returns the final string.
6
+ // Progress reaches the UI over `ctx.push(...)` (SSE) — no polling. `streamTo` mirrors the agent's own
7
+ // events onto one channel; lifecycle changes are pushed explicitly.
8
+ // The run is ALSO persisted, so reopening the app shows the last run instead of a blank screen.
9
+ // Cancellation: a module-level AbortController (the app module loads once, so a var can hold it).
10
+
11
+ const EMPTY: Run = { goal: "", status: "idle", steps: [], result: "", startedAt: 0 };
12
+
13
+ let currentAbort: AbortController | null = null;
14
+
15
+ async function load(ctx: { storage: { get(k: string): Promise<unknown> } }): Promise<Run> {
16
+ return ((await ctx.storage.get("run")) as Run) || EMPTY;
17
+ }
18
+
19
+ /** Persist + stream one change. Storage is the snapshot, `push` is the live feed. */
20
+ async function save(ctx, run: Run, patch?: Partial<Run>) {
21
+ const next: Run = { ...run, ...(patch || {}) };
22
+ await ctx.storage.set("run", next);
23
+ ctx.push(EV.run, next);
24
+ return next;
25
+ }
26
+
27
+ export default defineApp({
28
+ name: "执行器",
29
+ description: "模型自己走多步,UI 就是这条 run,可取消",
30
+ api: {
31
+ /** Snapshot for first paint: fetch once on mount, then live-update from events. */
32
+ async runStatus(ctx) {
33
+ return load(ctx);
34
+ },
35
+
36
+ // start returns immediately; the agent runs in the background and pushes as it goes
37
+ async start(ctx, args?: { goal?: string }) {
38
+ const goal = String(args?.goal ?? "").trim();
39
+ if (!goal) throw new Error("请输入目标");
40
+ currentAbort?.abort();
41
+ const ac = new AbortController();
42
+ currentAbort = ac;
43
+
44
+ let run = await save(ctx, { ...EMPTY, goal, startedAt: Date.now() }, { status: "running" });
45
+
46
+ void ctx
47
+ .agent(goal, {
48
+ signal: ac.signal,
49
+ maxIterations: 12,
50
+ // ⭐ streamTo uses the same name the UI subscribes to (EV.agent)
51
+ streamTo: EV.agent,
52
+ onEvent: async (ev) => {
53
+ // onEvent still runs — use it to keep the durable snapshot, not to feed the UI
54
+ if (ev.type !== "tool" && ev.type !== "turn" && ev.type !== "done" && ev.type !== "error") {
55
+ return;
56
+ }
57
+ const step: Step =
58
+ ev.type === "tool"
59
+ ? { phase: "tool", name: ev.name, at: Date.now() }
60
+ : ev.type === "turn"
61
+ ? { phase: "turn", turn: ev.turn, at: Date.now() }
62
+ : ev.type === "done"
63
+ ? { phase: "done", at: Date.now() }
64
+ : { phase: "error", text: ev.message, at: Date.now() };
65
+ run = { ...run, steps: [...run.steps, step] };
66
+ await ctx.storage.set("run", run);
67
+ },
68
+ })
69
+ .then(async (text) => {
70
+ const cur = await load(ctx);
71
+ await save(ctx, cur, { status: "done", result: text.slice(-4000) });
72
+ if (currentAbort === ac) currentAbort = null;
73
+ })
74
+ .catch(async (cause) => {
75
+ const msg = String((cause as Error)?.message || cause);
76
+ const cur = await load(ctx);
77
+ await save(ctx, cur, { status: "error", result: msg });
78
+ if (currentAbort === ac) currentAbort = null;
79
+ });
80
+
81
+ return { ok: true, started: true };
82
+ },
83
+
84
+ async cancel(ctx) {
85
+ currentAbort?.abort();
86
+ currentAbort = null;
87
+ await save(ctx, await load(ctx), { status: "cancelled" });
88
+ return { ok: true };
89
+ },
90
+ },
91
+ });
@@ -0,0 +1,8 @@
1
+ {
2
+ "id": "com.example.runner",
3
+ "name": "执行器",
4
+ "description": "模型自己走多步,UI 就是这条 run,可取消",
5
+ "version": "0.1.0",
6
+ "entry": "ui.tsx",
7
+ "acronym": "ZX"
8
+ }
@@ -0,0 +1,14 @@
1
+ export type Step = { phase: string; name?: string; turn?: number; text?: string; at: number };
2
+ export type Run = { goal: string; status: string; steps: Step[]; result: string; startedAt: number };
3
+
4
+ export const EV = {
5
+ run: "run",
6
+ agent: "agent",
7
+ } as const;
8
+
9
+ export type Events = {
10
+ run: Run;
11
+ agent: unknown;
12
+ };
13
+
14
+ export type EventName = keyof Events;