@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,546 @@
1
+ import { useCallback, useEffect, useMemo, useState } from "react";
2
+
3
+ import {
4
+ AppShell,
5
+ Badge,
6
+ Button,
7
+ Card,
8
+ CardContent,
9
+ cn,
10
+ type ColumnDef,
11
+ DataGrid,
12
+ Dialog,
13
+ DialogContent,
14
+ DialogDescription,
15
+ DialogFooter,
16
+ DialogHeader,
17
+ DialogTitle,
18
+ FilterBar,
19
+ Icon,
20
+ Input,
21
+ Kanban,
22
+ type KanbanCard,
23
+ NativeSelect,
24
+ PageHeader,
25
+ Select,
26
+ SelectContent,
27
+ SelectItem,
28
+ SelectTrigger,
29
+ SelectValue,
30
+ Sheet,
31
+ SheetContent,
32
+ SheetDescription,
33
+ SheetHeader,
34
+ SheetTitle,
35
+ Textarea,
36
+ useApp,
37
+ } from "@monkey-mini-app/ui";
38
+
39
+ type Issue = {
40
+ key: string;
41
+ type: "Story" | "Task" | "Bug" | "Epic";
42
+ summary: string;
43
+ status: "To Do" | "In Progress" | "Done" | "Blocked";
44
+ priority: "P0" | "P1" | "P2" | "P3";
45
+ assignee: string;
46
+ reporter: string;
47
+ points: number;
48
+ comments: { author: string; text: string; at: number }[];
49
+ createdAt: number;
50
+ updatedAt: number;
51
+ };
52
+
53
+ const STATUSES: Issue["status"][] = ["To Do", "In Progress", "Done", "Blocked"];
54
+ const ASSIGNEES = ["陈", "李", "王"];
55
+ const STATUS_TONE: Record<Issue["status"], string> = {
56
+ "To Do": "default",
57
+ "In Progress": "secondary",
58
+ Done: "secondary",
59
+ Blocked: "destructive",
60
+ };
61
+ // Literal Tailwind classes — never a composed name (`bg-${x}-500` compiles to nothing),
62
+ // and never a hex/oklch literal here: these have to survive a palette + dark-mode switch.
63
+ const STATUS_DOT: Record<Issue["status"], string> = {
64
+ "To Do": "bg-muted-foreground/40",
65
+ "In Progress": "bg-primary/60",
66
+ Done: "bg-primary",
67
+ Blocked: "bg-destructive",
68
+ };
69
+
70
+ // One literal string per status: the tile wash is the same token family as the dot.
71
+ const STATUS_TILE: Record<Issue["status"], string> = {
72
+ "To Do": "bg-card",
73
+ "In Progress": "bg-primary/10",
74
+ Done: "bg-card",
75
+ Blocked: "bg-destructive/10",
76
+ };
77
+
78
+ // ⭐ The aurora: three hue pools mixed out of the palette's own primary — toward the ink for
79
+ // depth, toward destructive for the warm drift. A flat `bg-muted` ground is why a bento
80
+ // grid reads as "admin dashboard" instead of this look. No colour literals.
81
+ const AURORA =
82
+ "radial-gradient(42% 40% at 10% 2%, color-mix(in oklch, var(--primary) 92%, transparent), transparent 58%)," +
83
+ "radial-gradient(38% 44% at 90% 10%, color-mix(in oklch, var(--primary) 62%, var(--foreground)), transparent 60%)," +
84
+ "radial-gradient(52% 46% at 42% 104%, color-mix(in oklch, var(--primary) 58%, var(--destructive)), transparent 62%)";
85
+
86
+ // Tiles are OPAQUE and raised — glass is glass-island's job. Two shadows: contact + lift.
87
+ const RAISED = {
88
+ boxShadow:
89
+ "0 1px 2px color-mix(in oklch, var(--foreground) 14%, transparent)," +
90
+ "0 14px 30px -14px var(--shadow)",
91
+ } as const;
92
+
93
+ export default function Ui() {
94
+ const { call } = useApp();
95
+ const [issues, setIssues] = useState<Issue[]>([]);
96
+ const [view, setView] = useState<"kanban" | "table">("kanban");
97
+ const [sel, setSel] = useState<Issue | null>(null);
98
+ const [assignee, setAssignee] = useState("all");
99
+ const [statusFilter, setStatusFilter] = useState<"all" | Issue["status"]>(
100
+ "all",
101
+ );
102
+ const [summary, setSummary] = useState<{
103
+ byStatus: Record<string, number>;
104
+ total: number;
105
+ } | null>(null);
106
+ const [wlOpen, setWlOpen] = useState(false);
107
+ const [wlNote, setWlNote] = useState("");
108
+ const [wlMinutes, setWlMinutes] = useState(30);
109
+ const [comment, setComment] = useState("");
110
+ const [error, setError] = useState<string | null>(null);
111
+ // ⭐ key: theme switching — stored in ctx.storage (restored after refresh), applied live on document.documentElement
112
+ const load = useCallback(async () => {
113
+ try {
114
+ const data = (await call("list", {})) as { issues: Issue[] };
115
+ const s = (await call("summary", {})) as {
116
+ byStatus: Record<string, number>;
117
+ total: number;
118
+ };
119
+ let list = data.issues || [];
120
+ if (assignee !== "all")
121
+ list = list.filter((i) => i.assignee === assignee);
122
+ setIssues(list);
123
+ setSummary(s);
124
+ } catch (e) {
125
+ setError(String((e as Error)?.message || e));
126
+ }
127
+ }, [call, assignee]);
128
+
129
+ useEffect(() => {
130
+ void load();
131
+ }, [load]);
132
+
133
+ // optimistic update + persist (the backend update already saved)
134
+ async function patch(key: string, p: Partial<Issue>) {
135
+ setSel((prev) => (prev?.key === key ? { ...prev, ...p } : prev));
136
+ await call("update", { key, patch: p });
137
+ void load();
138
+ }
139
+
140
+ // ⭐ key: Kanban drag → onCardsChange yields the new cards, mapped back into patches by status
141
+ const onKanban = (cards: KanbanCard[]) => {
142
+ for (const c of cards) {
143
+ const cur = issues.find((i) => i.key === c.key);
144
+ if (cur && cur.status !== c.columnId)
145
+ void patch(c.key!, { status: c.columnId as Issue["status"] });
146
+ }
147
+ };
148
+
149
+ // ⭐ key: a bento tile is a destination — the status tiles filter the board, they are not decoration.
150
+ const shown =
151
+ statusFilter === "all"
152
+ ? issues
153
+ : issues.filter((i) => i.status === statusFilter);
154
+
155
+ const kanbanColumns = STATUSES.map((status) => ({
156
+ id: status,
157
+ title: status,
158
+ limit: undefined as number | undefined,
159
+ }));
160
+ const kanbanCards: KanbanCard[] = shown.map((i) => ({
161
+ id: i.key,
162
+ key: i.key,
163
+ title: i.summary,
164
+ columnId: i.status,
165
+ type: i.type,
166
+ status: i.status,
167
+ assignee: i.assignee,
168
+ tags: [i.priority],
169
+ updated: new Date(i.updatedAt).toLocaleDateString("zh-CN"),
170
+ }));
171
+
172
+ const columns: ColumnDef<Issue>[] = [
173
+ { accessorKey: "key", header: "键", meta: { sort: true, search: "text" } },
174
+ {
175
+ accessorKey: "type",
176
+ header: "类型",
177
+ meta: { sort: true, search: "select" },
178
+ },
179
+ {
180
+ accessorKey: "summary",
181
+ header: "摘要",
182
+ meta: { sort: true, search: "text" },
183
+ },
184
+ {
185
+ accessorKey: "assignee",
186
+ header: "负责人",
187
+ meta: { sort: true, search: "text" },
188
+ },
189
+ {
190
+ accessorKey: "status",
191
+ header: "状态",
192
+ meta: { sort: true, search: "select" },
193
+ cell: ({ getValue }) => <StatusBadgeMini status={String(getValue())} />,
194
+ },
195
+ {
196
+ accessorKey: "priority",
197
+ header: "优先级",
198
+ meta: { sort: true, search: "select" },
199
+ },
200
+ ];
201
+
202
+ async function openWorklog() {
203
+ if (!sel) return;
204
+ setWlOpen(true);
205
+ setWlNote("生成中…");
206
+ try {
207
+ const d = (await call("worklogDraft", { key: sel.key })) as {
208
+ note: string;
209
+ };
210
+ setWlNote(d.note);
211
+ } catch (e) {
212
+ setWlNote(
213
+ "(AI 生成失败,手动填写)" + String((e as Error)?.message || e),
214
+ );
215
+ }
216
+ }
217
+ async function saveWorklog() {
218
+ if (!sel) return;
219
+ await call("logWork", { key: sel.key, note: wlNote, minutes: wlMinutes });
220
+ setWlOpen(false);
221
+ void load();
222
+ }
223
+ async function addComment() {
224
+ if (!sel || !comment.trim()) return;
225
+ await call("comment", { key: sel.key, text: comment });
226
+ setComment("");
227
+ void load();
228
+ setSel((prev) => (prev ? { ...prev } : prev));
229
+ }
230
+
231
+ const byStatus = summary?.byStatus ?? {};
232
+
233
+ return (
234
+ <AppShell
235
+ header={
236
+ <PageHeader
237
+ title="阶段看板"
238
+ description={`${summary?.total ?? 0} 个 Issue`}
239
+ actions={
240
+ <>
241
+ <Button
242
+ size="sm"
243
+ variant="outline"
244
+ onClick={() => {
245
+ setSel(issues[0] ?? null);
246
+ setView("kanban");
247
+ }}
248
+ >
249
+ <Icon.Sparkles size={16} strokeWidth={2} /> AI 记工时
250
+ </Button>
251
+ </>
252
+ }
253
+ />
254
+ }
255
+ >
256
+ <div className="flex h-full min-h-0 flex-col gap-3">
257
+ {/* `fixed` so the field runs behind the shell header too, not just the main band. */}
258
+ <div
259
+ aria-hidden
260
+ className="pointer-events-none fixed inset-0 -z-10"
261
+ style={{ backgroundImage: AURORA }}
262
+ />
263
+ {/* ⭐ Look: aurora-bento — a tessellation that fills the band, and every tile is a
264
+ destination (filter / switch view), not a stat readout sitting there. Tiles are
265
+ opaque + raised; glass belongs to glass-island. See references/looks/aurora-bento.md. */}
266
+ {/* spans written out, no `sm:` — the panel width is user-dragged, so a breakpoint
267
+ there is a lie (same lesson as `today`). Capped + gapped: an edge-to-edge tile
268
+ wall hides the aurora, and the aurora is the look. */}
269
+ <div className="mx-auto grid w-full max-w-5xl grid-cols-6 gap-2.5">
270
+ <button
271
+ type="button"
272
+ onClick={() => setStatusFilter("all")}
273
+ style={RAISED}
274
+ className={cn(
275
+ "bg-foreground text-background col-span-2 row-span-2 rounded-2xl p-4 text-left",
276
+ statusFilter === "all" &&
277
+ "ring-2 ring-ring ring-offset-2 ring-offset-muted",
278
+ )}
279
+ >
280
+ <p className="text-xs opacity-70">阶段看板</p>
281
+ <p className="mt-2 text-2xl font-medium tabular-nums">
282
+ {summary?.total ?? 0}
283
+ </p>
284
+ <p className="mt-1 text-xs opacity-70">全部事项 · 点回总览</p>
285
+ </button>
286
+ {STATUSES.map((s) => (
287
+ <button
288
+ key={s}
289
+ type="button"
290
+ onClick={() => setStatusFilter(statusFilter === s ? "all" : s)}
291
+ style={RAISED}
292
+ className={cn(
293
+ "bg-card col-span-2 rounded-2xl p-3 text-left",
294
+ statusFilter === s && STATUS_TILE[s],
295
+ )}
296
+ >
297
+ <span className="flex items-center gap-1.5">
298
+ <span className={cn("size-2 rounded-full", STATUS_DOT[s])} />
299
+ <span className="text-muted-foreground text-xs">{s}</span>
300
+ </span>
301
+ <b className="mt-1 block text-lg tabular-nums">
302
+ {byStatus[s] ?? 0}
303
+ </b>
304
+ </button>
305
+ ))}
306
+ <button
307
+ type="button"
308
+ onClick={() => setView(view === "kanban" ? "table" : "kanban")}
309
+ style={RAISED}
310
+ className="bg-card col-span-6 flex items-center justify-between rounded-2xl p-3 text-left text-sm"
311
+ >
312
+ <span className="flex items-center gap-2">
313
+ {view === "kanban" ? (
314
+ <Icon.LayoutGrid size={14} strokeWidth={2} />
315
+ ) : (
316
+ <Icon.Table size={14} strokeWidth={2} />
317
+ )}
318
+ 当前:{view === "kanban" ? "看板" : "表格"}
319
+ </span>
320
+ <span className="text-muted-foreground text-xs">点这里切换</span>
321
+ </button>
322
+ </div>
323
+
324
+ <FilterBar>
325
+ {/* the view switch moved into its bento tile — one destination, one control */}
326
+ <NativeSelect
327
+ value={assignee}
328
+ onChange={(e) => setAssignee(e.target.value)}
329
+ >
330
+ {["all", ...ASSIGNEES].map((a) => (
331
+ <option key={a} value={a}>
332
+ {a === "all" ? "全部负责人" : a}
333
+ </option>
334
+ ))}
335
+ </NativeSelect>
336
+ {error && (
337
+ <span className="text-sm" style={{ color: "var(--destructive)" }}>
338
+ {error}
339
+ </span>
340
+ )}
341
+ </FilterBar>
342
+
343
+ <Card className="min-h-0 flex-1 overflow-y-auto">
344
+ <CardContent>
345
+ {view === "kanban" ? (
346
+ <div className="flex gap-3 overflow-x-auto pb-2">
347
+ <Kanban
348
+ columns={kanbanColumns}
349
+ cards={kanbanCards}
350
+ onCardsChange={onKanban}
351
+ onCardClick={(c) =>
352
+ setSel(issues.find((i) => i.key === c.key) ?? null)
353
+ }
354
+ />
355
+ </div>
356
+ ) : (
357
+ <DataGrid
358
+ columns={columns}
359
+ data={shown}
360
+ pageSize={10}
361
+ onRowClick={(issue) => setSel(issue)}
362
+ />
363
+ )}
364
+ </CardContent>
365
+ </Card>
366
+ </div>
367
+
368
+ {/* detail editing Sheet */}
369
+ <Sheet
370
+ open={Boolean(sel)}
371
+ onOpenChange={(o) => {
372
+ if (!o) setSel(null);
373
+ }}
374
+ >
375
+ <SheetContent className="sm:max-w-lg">
376
+ {sel && (
377
+ <>
378
+ <SheetHeader>
379
+ <SheetTitle className="font-mono flex items-center gap-2">
380
+ {sel.key} <StatusBadgeMini status={sel.status} />
381
+ </SheetTitle>
382
+ <SheetDescription>{sel.summary}</SheetDescription>
383
+ </SheetHeader>
384
+ <div className="flex flex-col gap-4 px-4 pb-4">
385
+ <div className="grid grid-cols-2 gap-2">
386
+ <Field label="状态">
387
+ <MapSelect
388
+ value={sel.status}
389
+ onChange={(v) => void patch(sel.key, { status: v })}
390
+ options={STATUSES.map((s) => ({ v: s, label: s }))}
391
+ />
392
+ </Field>
393
+ <Field label="负责人">
394
+ <MapSelect
395
+ value={sel.assignee}
396
+ onChange={(v) => void patch(sel.key, { assignee: v })}
397
+ options={ASSIGNEES.map((a) => ({ v: a, label: a }))}
398
+ />
399
+ </Field>
400
+ <Field label="优先级">
401
+ <MapSelect
402
+ value={sel.priority}
403
+ onChange={(v) => void patch(sel.key, { priority: v })}
404
+ options={(["P0", "P1", "P2", "P3"] as const).map((p) => ({
405
+ v: p,
406
+ label: p,
407
+ }))}
408
+ />
409
+ </Field>
410
+ <Field label="工时点">
411
+ <MapSelect
412
+ value={String(sel.points) as "1" | "2" | "3" | "5" | "8"}
413
+ onChange={(v) =>
414
+ void patch(sel.key, { points: Number(v) })
415
+ }
416
+ options={["1", "2", "3", "5", "8"].map((p) => ({
417
+ v: p as "1" | "2" | "3" | "5" | "8",
418
+ label: p,
419
+ }))}
420
+ />
421
+ </Field>
422
+ </div>
423
+
424
+ <div className="flex flex-col gap-2">
425
+ <div className="text-xs text-muted-foreground">
426
+ 评论 · {sel.comments.length}
427
+ </div>
428
+ <div className="flex flex-col gap-2">
429
+ {sel.comments.map((c, i) => (
430
+ <div
431
+ key={i}
432
+ className="rounded-lg border bg-muted/30 px-3 py-2 text-sm"
433
+ >
434
+ <div className="flex items-center justify-between">
435
+ <span className="font-medium">{c.author}</span>
436
+ <span className="text-[11px] text-muted-foreground">
437
+ {new Date(c.at).toLocaleString("zh-CN")}
438
+ </span>
439
+ </div>
440
+ <div className="mt-0.5">{c.text}</div>
441
+ </div>
442
+ ))}
443
+ </div>
444
+ <div className="flex gap-2">
445
+ <Textarea
446
+ className="flex-1"
447
+ value={comment}
448
+ placeholder="写评论"
449
+ onChange={(e) => setComment(e.target.value)}
450
+ />
451
+ <Button onClick={() => void addComment()}>发送</Button>
452
+ </div>
453
+ <Button variant="outline" onClick={() => void openWorklog()}>
454
+ <Icon.Sparkles size={16} strokeWidth={2} /> AI 记工时
455
+ </Button>
456
+ </div>
457
+ </div>
458
+ </>
459
+ )}
460
+ </SheetContent>
461
+ </Sheet>
462
+
463
+ {/* AI worklog confirmation Dialog */}
464
+ <Dialog open={wlOpen} onOpenChange={setWlOpen}>
465
+ <DialogContent className="sm:max-w-md">
466
+ <DialogHeader>
467
+ <DialogTitle>记工时</DialogTitle>
468
+ <DialogDescription>
469
+ {sel?.key} · {sel?.summary}
470
+ </DialogDescription>
471
+ </DialogHeader>
472
+ <Textarea
473
+ value={wlNote}
474
+ onChange={(e) => setWlNote(e.target.value)}
475
+ rows={4}
476
+ />
477
+ <div className="flex items-center gap-2">
478
+ <span className="text-sm text-muted-foreground">工时</span>
479
+ <Input
480
+ value={wlMinutes}
481
+ onChange={(e) => setWlMinutes(Number(e.target.value))}
482
+ type="number"
483
+ className="w-24"
484
+ />{" "}
485
+ <span className="text-sm">分钟</span>
486
+ </div>
487
+ <DialogFooter>
488
+ <Button variant="outline" onClick={() => setWlOpen(false)}>
489
+ 取消
490
+ </Button>
491
+ <Button onClick={() => void saveWorklog()}>确认记录</Button>
492
+ </DialogFooter>
493
+ </DialogContent>
494
+ </Dialog>
495
+ </AppShell>
496
+ );
497
+ }
498
+
499
+ function Field({
500
+ label,
501
+ children,
502
+ }: {
503
+ label: string;
504
+ children: React.ReactNode;
505
+ }) {
506
+ return (
507
+ <div className="flex flex-col gap-1">
508
+ <span className="text-xs text-muted-foreground">{label}</span>
509
+ {children}
510
+ </div>
511
+ );
512
+ }
513
+ // ⭐ key: the ui Select is a Base-UI composition (Trigger/Value/Content/Item) — don't treat it as a native <select>
514
+ function MapSelect<T extends string>({
515
+ value,
516
+ onChange,
517
+ options,
518
+ }: {
519
+ value: T;
520
+ onChange: (v: T) => void;
521
+ options: { v: T; label: string }[];
522
+ }) {
523
+ return (
524
+ <Select value={value} onValueChange={(v) => onChange(v as T)}>
525
+ <SelectTrigger className="w-full">
526
+ <SelectValue />
527
+ </SelectTrigger>
528
+ <SelectContent>
529
+ {options.map((o) => (
530
+ <SelectItem key={o.v} value={o.v}>
531
+ {o.label}
532
+ </SelectItem>
533
+ ))}
534
+ </SelectContent>
535
+ </Select>
536
+ );
537
+ }
538
+ function StatusBadgeMini({ status }: { status: string }) {
539
+ return (
540
+ <Badge
541
+ variant={(STATUS_TONE as Record<string, never>)[status] ?? "default"}
542
+ >
543
+ {status}
544
+ </Badge>
545
+ );
546
+ }
@@ -0,0 +1,35 @@
1
+ import { defineApp } from "@monkey-mini-app/api";
2
+
3
+ type Job = { id: string; title: string; command: string };
4
+
5
+ // ⭐ key: chores are named buttons with a known command — not a prompt for ctx.agent.
6
+ const JOBS: Job[] = [
7
+ { id: "disk", title: "磁盘用量", command: "df -k / | tail -1" },
8
+ { id: "top", title: "最耗 CPU", command: "ps -axo pid,pcpu,pmem,comm -r | head -n 6" },
9
+ { id: "who", title: "这台机器", command: "uname -a" },
10
+ ];
11
+
12
+ export default defineApp({
13
+ name: "一键杂事",
14
+ description: "三个按钮,在这台机器上跑已知脚本,结果回到 app",
15
+ api: {
16
+ async jobs() {
17
+ return { jobs: JOBS.map(({ id, title }) => ({ id, title })) };
18
+ },
19
+ async run(ctx, args?: { id?: string }) {
20
+ const job = JOBS.find((j) => j.id === args?.id);
21
+ if (!job) throw new Error("没有这个按钮");
22
+ // ⭐ key: ctx.bash is the point — stdout/stderr/exitCode come back into the UI, not a terminal window.
23
+ const result = await ctx.bash(job.command);
24
+ return {
25
+ id: job.id,
26
+ title: job.title,
27
+ command: job.command,
28
+ stdout: String(result.stdout ?? ""),
29
+ stderr: String(result.stderr ?? ""),
30
+ exitCode: result.exitCode,
31
+ at: Date.now(),
32
+ };
33
+ },
34
+ },
35
+ });
@@ -0,0 +1,8 @@
1
+ {
2
+ "id": "com.example.chores",
3
+ "name": "一键杂事",
4
+ "description": "已知脚本、一个按钮、这台机器、看输出。没有模型。",
5
+ "version": "0.1.0",
6
+ "entry": "ui.tsx",
7
+ "acronym": "ZS"
8
+ }
@@ -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
+ }