@notis_ai/cli 0.2.17 → 0.2.19

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 (395) hide show
  1. package/README.md +542 -146
  2. package/bin/check-runtime.js +15 -0
  3. package/bin/notis.js +2 -0
  4. package/config/notis_app_design_rules.json +320 -0
  5. package/config/portal-route-roots.json +45 -0
  6. package/dist/agent-hooks/notis-agent-hook.mjs +42323 -18258
  7. package/dist/base-skills/notis-cli/.notis-base-skill.json +1 -0
  8. package/dist/base-skills/notis-cli/SKILL.md +51 -280
  9. package/dist/base-skills/notis-cli/references/app-delivery.md +17 -0
  10. package/dist/base-skills/notis-cli/references/intelligence.md +94 -0
  11. package/dist/base-skills/notis-cli/references/native-databases.md +21 -0
  12. package/dist/base-skills/notis-cli/references/tool-examples.md +56 -0
  13. package/dist/base-skills/notis-cli/references/troubleshooting.md +67 -0
  14. package/dist/base-skills/notis-query/.notis-base-skill.json +1 -0
  15. package/dist/base-skills/notis-query/SKILL.md +35 -699
  16. package/dist/base-skills/notis-query/references/database-discovery.md +59 -0
  17. package/dist/base-skills/notis-query/references/documents.md +74 -0
  18. package/dist/base-skills/notis-query/references/query.md +76 -0
  19. package/dist/base-skills/notis-spaces/.notis-base-skill.json +1 -0
  20. package/dist/base-skills/notis-spaces/SKILL.md +218 -0
  21. package/dist/base-skills/notis-spaces/references/architecture.md +116 -0
  22. package/dist/base-skills/notis-spaces/references/context.md +81 -0
  23. package/dist/base-skills/notis-spaces/references/design.md +141 -0
  24. package/dist/base-skills/notis-spaces/references/fixtures.md +29 -0
  25. package/dist/base-skills/notis-spaces/references/memory.md +58 -0
  26. package/dist/base-skills/notis-spaces/references/reading.md +73 -0
  27. package/dist/base-skills/notis-spaces/references/release.md +120 -0
  28. package/dist/base-skills/notis-spaces/references/reports.md +77 -0
  29. package/dist/base-skills/notis-spaces/references/sdk.md +273 -0
  30. package/dist/base-skills/notis-spaces/references/store.md +118 -0
  31. package/dist/base-skills/notis-spaces/references/troubleshooting.md +28 -0
  32. package/dist/base-skills/notis-spaces/references/views.md +229 -0
  33. package/{template/packages → dist}/sdk/package.json +9 -10
  34. package/dist/sdk/src/agentContext.ts +36 -0
  35. package/dist/sdk/src/bundleModule.ts +175 -0
  36. package/dist/sdk/src/components/Dialog.tsx +103 -0
  37. package/dist/sdk/src/components/DocumentEditor.tsx +113 -0
  38. package/dist/sdk/src/components/DocumentPage.tsx +184 -0
  39. package/{template/packages → dist}/sdk/src/components/Markdown.tsx +9 -3
  40. package/{template/packages → dist}/sdk/src/components/MarkdownEditor.tsx +26 -5
  41. package/{template/packages → dist}/sdk/src/components/MultiSelectActionBar.tsx +95 -12
  42. package/{template/packages → dist}/sdk/src/components/MultiSelectCheckbox.tsx +4 -2
  43. package/dist/sdk/src/components/NotisCommentBoundary.tsx +172 -0
  44. package/{template/packages → dist}/sdk/src/components/NotisSelectionBoundary.tsx +9 -5
  45. package/dist/sdk/src/components/RecordComponents.tsx +111 -0
  46. package/dist/sdk/src/components/Skeleton.tsx +38 -0
  47. package/dist/sdk/src/config.ts +31 -0
  48. package/{template/packages → dist}/sdk/src/documents.ts +21 -6
  49. package/dist/sdk/src/hooks/useAction.ts +28 -0
  50. package/dist/sdk/src/hooks/useAgentContext.ts +23 -0
  51. package/{template/packages → dist}/sdk/src/hooks/useBackend.ts +3 -2
  52. package/dist/sdk/src/hooks/useCloudComputer.ts +94 -0
  53. package/dist/sdk/src/hooks/useCloudComputerShell.ts +114 -0
  54. package/{template/packages → dist}/sdk/src/hooks/useCollectionInteractions.ts +157 -147
  55. package/dist/sdk/src/hooks/useDatabaseSchema.ts +50 -0
  56. package/{template/packages → dist}/sdk/src/hooks/useDatabaseSubscription.ts +2 -2
  57. package/dist/sdk/src/hooks/useDocument.ts +51 -0
  58. package/{template/packages → dist}/sdk/src/hooks/useDocuments.ts +25 -59
  59. package/{template/packages → dist}/sdk/src/hooks/useHandover.ts +7 -7
  60. package/dist/sdk/src/hooks/useLongPressSelection.ts +79 -0
  61. package/dist/sdk/src/hooks/useMarqueeSelection.ts +194 -0
  62. package/{template/packages → dist}/sdk/src/hooks/useMultiSelect.ts +2 -8
  63. package/dist/sdk/src/hooks/useNativeDocumentBody.ts +50 -0
  64. package/dist/sdk/src/hooks/useNativeDocuments.ts +143 -0
  65. package/{template/packages → dist}/sdk/src/hooks/useNotis.ts +6 -1
  66. package/dist/sdk/src/hooks/useNotisNavigation.ts +70 -0
  67. package/dist/sdk/src/hooks/useQuery.ts +81 -0
  68. package/dist/sdk/src/hooks/useToolQuery.ts +12 -0
  69. package/dist/sdk/src/hooks/useTopBarSearch.ts +102 -0
  70. package/dist/sdk/src/hooks/useTopBarTitleLeaf.ts +75 -0
  71. package/{template/packages → dist}/sdk/src/hooks/useUpsertDocument.ts +1 -1
  72. package/dist/sdk/src/hooks/useViewParams.ts +195 -0
  73. package/dist/sdk/src/hooks/useViewerReads.ts +129 -0
  74. package/{template/packages → dist}/sdk/src/index.ts +64 -1
  75. package/{template/packages → dist}/sdk/src/interactions/actions.ts +14 -1
  76. package/{template/packages → dist}/sdk/src/interactions/shortcuts.tsx +129 -23
  77. package/dist/sdk/src/interactions/visibility.ts +13 -0
  78. package/{template/packages → dist}/sdk/src/interactions.ts +5 -1
  79. package/dist/sdk/src/nativeData.ts +39 -0
  80. package/{template/packages → dist}/sdk/src/provider.tsx +9 -4
  81. package/dist/sdk/src/queryCache.ts +292 -0
  82. package/dist/sdk/src/queryErrors.ts +51 -0
  83. package/dist/sdk/src/runtime.ts +675 -0
  84. package/dist/sdk/src/runtimeModules.ts +33 -0
  85. package/dist/sdk/src/space.ts +442 -0
  86. package/dist/sdk/src/standardViewParams.ts +36 -0
  87. package/{template/packages → dist}/sdk/src/styles.css +81 -16
  88. package/dist/sdk/src/tailwind.ts +66 -0
  89. package/dist/sdk/src/ui/charts/RenderChartData.tsx +25 -0
  90. package/dist/sdk/src/ui/engine/core.ts +392 -0
  91. package/dist/sdk/src/ui/engine/dom.ts +183 -0
  92. package/dist/sdk/src/ui/engine/hooks.ts +195 -0
  93. package/dist/sdk/src/ui/engine/instance.ts +63 -0
  94. package/dist/sdk/src/ui/engine/keycapContext.ts +2 -0
  95. package/dist/sdk/src/ui/engine/registry.ts +262 -0
  96. package/dist/sdk/src/ui/engine/types.ts +62 -0
  97. package/dist/sdk/src/ui/icons.tsx +91 -0
  98. package/dist/sdk/src/ui/util.ts +83 -0
  99. package/dist/sdk/src/viewPeriod.ts +26 -0
  100. package/dist/sdk/src/vite.ts +92 -0
  101. package/dist/sdk/src/words/actions.ts +295 -0
  102. package/dist/sdk/src/words/clashes.ts +158 -0
  103. package/dist/sdk/src/words/format.ts +136 -0
  104. package/dist/sdk/src/words/index.ts +13 -0
  105. package/dist/sdk/src/words/keymap.ts +72 -0
  106. package/dist/sdk/src/words/keys.ts +297 -0
  107. package/dist/sdk/src/words/shell.ts +46 -0
  108. package/dist/sdk/src/words/types.ts +65 -0
  109. package/dist/skill-sync/index.js +832 -151
  110. package/dist/skill-sync/index.js.map +4 -4
  111. package/dist/skill-sync-worker.mjs +3941 -0
  112. package/dist/space-harness/host.js +1460 -0
  113. package/dist/space-sdk/dist/chunk-ZSN57ATH.js +5 -0
  114. package/dist/space-sdk/dist/index.js +15 -0
  115. package/dist/space-sdk/dist/ui.js +18 -0
  116. package/dist/space-sdk/package.json +33 -0
  117. package/dist/space-sdk/src/agentContext.d.ts +36 -0
  118. package/dist/space-sdk/src/components/Dialog.d.ts +20 -0
  119. package/dist/space-sdk/src/components/DocumentEditor.d.ts +46 -0
  120. package/dist/space-sdk/src/components/DocumentPage.d.ts +53 -0
  121. package/dist/space-sdk/src/components/Markdown.d.ts +18 -0
  122. package/dist/space-sdk/src/components/MarkdownEditor.d.ts +11 -0
  123. package/dist/space-sdk/src/components/MultiSelectActionBar.d.ts +31 -0
  124. package/dist/space-sdk/src/components/MultiSelectCheckbox.d.ts +14 -0
  125. package/dist/space-sdk/src/components/MultiSelectDragOverlay.d.ts +8 -0
  126. package/dist/space-sdk/src/components/NotisCommentBoundary.d.ts +36 -0
  127. package/dist/space-sdk/src/components/NotisSelectionBoundary.d.ts +16 -0
  128. package/dist/space-sdk/src/components/RecordComponents.d.ts +64 -0
  129. package/dist/space-sdk/src/components/ShortcutHints.d.ts +12 -0
  130. package/dist/space-sdk/src/components/Skeleton.d.ts +23 -0
  131. package/dist/space-sdk/src/config.ts +31 -0
  132. package/dist/space-sdk/src/documents.d.ts +59 -0
  133. package/dist/space-sdk/src/hooks/useAction.d.ts +8 -0
  134. package/dist/space-sdk/src/hooks/useActiveResource.d.ts +3 -0
  135. package/dist/space-sdk/src/hooks/useAgentContext.d.ts +7 -0
  136. package/dist/space-sdk/src/hooks/useBackend.d.ts +23 -0
  137. package/dist/space-sdk/src/hooks/useCloudComputer.d.ts +45 -0
  138. package/dist/space-sdk/src/hooks/useCloudComputerShell.d.ts +49 -0
  139. package/dist/space-sdk/src/hooks/useCollectionInteractions.d.ts +118 -0
  140. package/dist/space-sdk/src/hooks/useDatabaseSchema.d.ts +14 -0
  141. package/dist/space-sdk/src/hooks/useDatabaseSubscription.d.ts +26 -0
  142. package/dist/space-sdk/src/hooks/useDocument.d.ts +22 -0
  143. package/dist/space-sdk/src/hooks/useDocuments.d.ts +31 -0
  144. package/dist/space-sdk/src/hooks/useHandover.d.ts +43 -0
  145. package/dist/space-sdk/src/hooks/useLongPressSelection.d.ts +9 -0
  146. package/dist/space-sdk/src/hooks/useMarqueeSelection.d.ts +57 -0
  147. package/dist/space-sdk/src/hooks/useMultiSelect.d.ts +51 -0
  148. package/dist/space-sdk/src/hooks/useNativeDocumentBody.d.ts +24 -0
  149. package/dist/space-sdk/src/hooks/useNativeDocuments.d.ts +55 -0
  150. package/dist/space-sdk/src/hooks/useNotis.d.ts +25 -0
  151. package/dist/space-sdk/src/hooks/useNotisNavigation.d.ts +33 -0
  152. package/dist/space-sdk/src/hooks/useQuery.d.ts +22 -0
  153. package/dist/space-sdk/src/hooks/useTool.d.ts +20 -0
  154. package/dist/space-sdk/src/hooks/useToolQuery.d.ts +3 -0
  155. package/dist/space-sdk/src/hooks/useTools.d.ts +15 -0
  156. package/dist/space-sdk/src/hooks/useTopBarSearch.d.ts +48 -0
  157. package/dist/space-sdk/src/hooks/useTopBarTitleLeaf.d.ts +24 -0
  158. package/dist/space-sdk/src/hooks/useUpsertDocument.d.ts +27 -0
  159. package/dist/space-sdk/src/hooks/useViewParams.d.ts +76 -0
  160. package/dist/space-sdk/src/hooks/useViewerReads.d.ts +38 -0
  161. package/dist/space-sdk/src/index.d.ts +98 -0
  162. package/dist/space-sdk/src/interactions/actions.d.ts +33 -0
  163. package/dist/space-sdk/src/interactions/shortcuts.d.ts +42 -0
  164. package/dist/space-sdk/src/interactions/visibility.d.ts +2 -0
  165. package/dist/space-sdk/src/nativeData.d.ts +66 -0
  166. package/dist/space-sdk/src/provider.d.ts +17 -0
  167. package/dist/space-sdk/src/queryCache.d.ts +45 -0
  168. package/dist/space-sdk/src/queryErrors.ts +51 -0
  169. package/dist/space-sdk/src/runtime.d.ts +615 -0
  170. package/dist/space-sdk/src/runtimeModules.ts +33 -0
  171. package/dist/space-sdk/src/space.ts +442 -0
  172. package/dist/space-sdk/src/standardViewParams.d.ts +15 -0
  173. package/dist/space-sdk/src/tailwind-candidates.d.ts +3418 -0
  174. package/dist/space-sdk/src/tailwind.ts +66 -0
  175. package/dist/space-sdk/src/ui/actions/ActionToast.d.ts +15 -0
  176. package/dist/space-sdk/src/ui/actions/actionWords.d.ts +16 -0
  177. package/dist/space-sdk/src/ui/actions/index.d.ts +7 -0
  178. package/dist/space-sdk/src/ui/actions/useActions.d.ts +69 -0
  179. package/dist/space-sdk/src/ui/actions/useToast.d.ts +41 -0
  180. package/dist/space-sdk/src/ui/blocks/Tabs.d.ts +139 -0
  181. package/dist/space-sdk/src/ui/blocks/blocks.d.ts +217 -0
  182. package/dist/space-sdk/src/ui/blocks/index.d.ts +4 -0
  183. package/dist/space-sdk/src/ui/board/BoardView.d.ts +36 -0
  184. package/dist/space-sdk/src/ui/board/boardModel.d.ts +46 -0
  185. package/dist/space-sdk/src/ui/board/boardWords.d.ts +9 -0
  186. package/dist/space-sdk/src/ui/board/index.d.ts +5 -0
  187. package/dist/space-sdk/src/ui/calendar/CalendarView.d.ts +49 -0
  188. package/dist/space-sdk/src/ui/calendar/DayPicker.d.ts +23 -0
  189. package/dist/space-sdk/src/ui/calendar/calendarMath.d.ts +81 -0
  190. package/dist/space-sdk/src/ui/charts/Chart.d.ts +203 -0
  191. package/dist/space-sdk/src/ui/charts/ChartTable.d.ts +37 -0
  192. package/dist/space-sdk/src/ui/charts/RenderChartData.d.ts +16 -0
  193. package/dist/space-sdk/src/ui/charts/StatRow.d.ts +59 -0
  194. package/dist/space-sdk/src/ui/charts/chartData.d.ts +84 -0
  195. package/dist/space-sdk/src/ui/comments/CommentPane.d.ts +58 -0
  196. package/dist/space-sdk/src/ui/comments/commentModel.d.ts +157 -0
  197. package/dist/space-sdk/src/ui/comments/commentWords.d.ts +60 -0
  198. package/dist/space-sdk/src/ui/comments/index.d.ts +4 -0
  199. package/dist/space-sdk/src/ui/comments/useComments.d.ts +146 -0
  200. package/dist/space-sdk/src/ui/engine/HelpSheet.d.ts +12 -0
  201. package/dist/space-sdk/src/ui/engine/KeyboardEngine.d.ts +27 -0
  202. package/dist/space-sdk/src/ui/engine/core.d.ts +73 -0
  203. package/dist/space-sdk/src/ui/engine/hooks.d.ts +64 -0
  204. package/dist/space-sdk/src/ui/engine/index.d.ts +14 -0
  205. package/dist/space-sdk/src/ui/engine/instance.d.ts +21 -0
  206. package/dist/space-sdk/src/ui/engine/keycapContext.d.ts +2 -0
  207. package/dist/space-sdk/src/ui/engine/registry.d.ts +77 -0
  208. package/dist/space-sdk/src/ui/engine/step.d.ts +11 -0
  209. package/dist/space-sdk/src/ui/engine/types.d.ts +54 -0
  210. package/dist/space-sdk/src/ui/fields/fieldWords.d.ts +56 -0
  211. package/dist/space-sdk/src/ui/fields/fields.d.ts +162 -0
  212. package/dist/space-sdk/src/ui/fields/index.d.ts +5 -0
  213. package/dist/space-sdk/src/ui/fields/useFieldDraft.d.ts +22 -0
  214. package/dist/space-sdk/src/ui/gallery/AttachmentGallery.d.ts +53 -0
  215. package/dist/space-sdk/src/ui/gallery/ImageViewer.d.ts +27 -0
  216. package/dist/space-sdk/src/ui/gallery/galleryWords.d.ts +95 -0
  217. package/dist/space-sdk/src/ui/gallery/index.d.ts +5 -0
  218. package/dist/space-sdk/src/ui/icons.d.ts +13 -0
  219. package/dist/space-sdk/src/ui/index.d.ts +54 -0
  220. package/dist/space-sdk/src/ui/keycap/Keycap.d.ts +22 -0
  221. package/dist/space-sdk/src/ui/keycap/index.d.ts +2 -0
  222. package/dist/space-sdk/src/ui/layout/Panels.d.ts +50 -0
  223. package/dist/space-sdk/src/ui/layout/chatPanelEdge.d.ts +77 -0
  224. package/dist/space-sdk/src/ui/layout/index.d.ts +5 -0
  225. package/dist/space-sdk/src/ui/layout/panelMath.d.ts +91 -0
  226. package/dist/space-sdk/src/ui/list/ListReader.d.ts +380 -0
  227. package/dist/space-sdk/src/ui/list/Row.d.ts +145 -0
  228. package/dist/space-sdk/src/ui/list/SelectionBar.d.ts +65 -0
  229. package/dist/space-sdk/src/ui/list/index.d.ts +14 -0
  230. package/dist/space-sdk/src/ui/list/rowState.d.ts +22 -0
  231. package/dist/space-sdk/src/ui/list/useListKeys.d.ts +89 -0
  232. package/dist/space-sdk/src/ui/list/useReorder.d.ts +86 -0
  233. package/dist/space-sdk/src/ui/list/useSelection.d.ts +90 -0
  234. package/dist/space-sdk/src/ui/open/OpenAsMenu.d.ts +15 -0
  235. package/dist/space-sdk/src/ui/open/index.d.ts +6 -0
  236. package/dist/space-sdk/src/ui/open/openModeStore.d.ts +39 -0
  237. package/dist/space-sdk/src/ui/open/useOpenMode.d.ts +17 -0
  238. package/dist/space-sdk/src/ui/overlay/Menu.d.ts +88 -0
  239. package/dist/space-sdk/src/ui/overlay/Popover.d.ts +28 -0
  240. package/dist/space-sdk/src/ui/overlay/Tooltip.d.ts +19 -0
  241. package/dist/space-sdk/src/ui/overlay/index.d.ts +9 -0
  242. package/dist/space-sdk/src/ui/overlay/layerRoot.d.ts +24 -0
  243. package/dist/space-sdk/src/ui/overlay/position.d.ts +31 -0
  244. package/dist/space-sdk/src/ui/period/PeriodPicker.d.ts +30 -0
  245. package/dist/space-sdk/src/ui/period/dateFormat.d.ts +50 -0
  246. package/dist/space-sdk/src/ui/period/dateWords.d.ts +88 -0
  247. package/dist/space-sdk/src/ui/period/periods.d.ts +70 -0
  248. package/dist/space-sdk/src/ui/period/usePeriod.d.ts +23 -0
  249. package/dist/space-sdk/src/ui/present/index.d.ts +3 -0
  250. package/dist/space-sdk/src/ui/present/presentWords.d.ts +27 -0
  251. package/dist/space-sdk/src/ui/present/screens.d.ts +36 -0
  252. package/dist/space-sdk/src/ui/present/useAudienceScreen.d.ts +38 -0
  253. package/dist/space-sdk/src/ui/styles.d.ts +21 -0
  254. package/dist/space-sdk/src/ui/timeline/TimelineView.d.ts +44 -0
  255. package/dist/space-sdk/src/ui/timeline/timelineMath.d.ts +123 -0
  256. package/dist/space-sdk/src/viewPeriod.d.ts +8 -0
  257. package/dist/space-sdk/src/vite.ts +92 -0
  258. package/dist/space-sdk/src/words/actions.ts +295 -0
  259. package/dist/space-sdk/src/words/clashes.ts +158 -0
  260. package/dist/space-sdk/src/words/format.ts +136 -0
  261. package/dist/space-sdk/src/words/index.ts +13 -0
  262. package/dist/space-sdk/src/words/keymap.ts +72 -0
  263. package/dist/space-sdk/src/words/keys.ts +297 -0
  264. package/dist/space-sdk/src/words/shell.ts +46 -0
  265. package/dist/space-sdk/src/words/types.ts +65 -0
  266. package/dist/view-renderer/dist/host.css +1 -0
  267. package/dist/view-renderer/dist/host.js +2374 -0
  268. package/dist/view-renderer/dist/theme.css +73 -0
  269. package/dist/view-renderer/src/dom.js +212 -0
  270. package/dist/view-renderer/src/errors.js +8 -0
  271. package/dist/view-renderer/src/host.tsx +250 -0
  272. package/dist/view-renderer/src/index.js +4 -0
  273. package/dist/view-renderer/src/png.js +213 -0
  274. package/dist/view-renderer/src/pool.js +110 -0
  275. package/dist/view-renderer/src/remote-broker.js +59 -0
  276. package/dist/view-renderer/src/renderer.js +271 -0
  277. package/package.json +21 -11
  278. package/skills/notis-cli/AGENT_INSTRUCTIONS.md +63 -12
  279. package/skills/notis-onboarding/BRIEF.md +14 -9
  280. package/skills/notis-query/cli.md +1 -1
  281. package/skills/notis-spaces/cli.md +540 -0
  282. package/src/cli.js +8 -8
  283. package/src/command-specs/agents.js +121 -8
  284. package/src/command-specs/auth.js +3 -3
  285. package/src/command-specs/diagnostics.js +97 -20
  286. package/src/command-specs/documents.js +158 -0
  287. package/src/command-specs/files.js +29 -0
  288. package/src/command-specs/handover.js +331 -79
  289. package/src/command-specs/helpers.js +50 -40
  290. package/src/command-specs/index.js +14 -5
  291. package/src/command-specs/meta.js +38 -9
  292. package/src/command-specs/onboarding.js +1 -1
  293. package/src/command-specs/profile.js +42 -1
  294. package/src/command-specs/skills.js +314 -9
  295. package/src/command-specs/smoke.js +16 -4
  296. package/src/command-specs/spaces.js +783 -0
  297. package/src/command-specs/tools.js +118 -21
  298. package/src/command-specs/version-history.js +20 -0
  299. package/src/command-specs/views.js +69 -0
  300. package/src/runtime/agent-browser.js +178 -267
  301. package/src/runtime/agent-setup.js +172 -13
  302. package/src/runtime/app-boundary-validator.js +338 -2
  303. package/src/runtime/app-data-literals.js +82 -0
  304. package/src/runtime/app-platform.js +750 -1568
  305. package/src/runtime/auth-recovery.js +17 -0
  306. package/src/runtime/base-skills.d.ts +11 -0
  307. package/src/runtime/base-skills.js +100 -3
  308. package/src/runtime/computer-identity.d.ts +30 -0
  309. package/src/runtime/computer-identity.js +151 -0
  310. package/src/runtime/config-lock.js +135 -0
  311. package/src/runtime/confined-space-build.js +74 -0
  312. package/src/runtime/confined-space-verify.js +49 -0
  313. package/src/runtime/delegated-context.js +5 -21
  314. package/src/runtime/native-record-files.js +47 -0
  315. package/src/runtime/oauth.js +342 -31
  316. package/src/runtime/profiles.js +19 -112
  317. package/src/runtime/retired-sdk-files.js +24 -0
  318. package/src/runtime/retry.js +150 -0
  319. package/src/runtime/skill-sync/cloud-client.ts +33 -8
  320. package/src/runtime/skill-sync/index.ts +443 -106
  321. package/src/runtime/skill-sync/local-scanner.ts +248 -32
  322. package/src/runtime/skill-sync/native-identity.ts +102 -0
  323. package/src/runtime/skill-sync/native-plan.ts +70 -0
  324. package/src/runtime/skill-sync/symlink-manager.ts +66 -16
  325. package/src/runtime/skill-sync/sync-plan.ts +34 -2
  326. package/src/runtime/skill-sync/types.ts +54 -0
  327. package/src/runtime/skill-sync/write-cloud-skill.ts +4 -4
  328. package/src/runtime/skill-sync-service.js +109 -0
  329. package/src/runtime/source-root.js +32 -0
  330. package/src/runtime/space-collection-scaffold.js +107 -0
  331. package/src/runtime/space-database-structures.js +229 -0
  332. package/src/runtime/space-fixture-broker.js +68 -0
  333. package/src/runtime/space-lock.js +337 -0
  334. package/src/runtime/space-platform.js +133 -0
  335. package/src/runtime/space-source.js +290 -0
  336. package/src/runtime/space-test-server.js +354 -0
  337. package/src/runtime/space-verification.js +94 -0
  338. package/src/runtime/space-verify-browser-worker.js +51 -0
  339. package/src/runtime/space-view-manifest.js +368 -0
  340. package/src/runtime/sync-skills.d.ts +5 -1
  341. package/src/runtime/sync-skills.js +11 -2
  342. package/src/runtime/tool-confirmation.js +138 -0
  343. package/src/runtime/transport.js +118 -24
  344. package/src/runtime/upsell.js +219 -0
  345. package/src/runtime/view-render.js +49 -0
  346. package/src/skill-sync-worker-entry.js +2 -0
  347. package/src/skill-sync-worker.js +114 -0
  348. package/src/space-harness-host.ts +122 -0
  349. package/template/.harness/index.html.tmpl +9 -352
  350. package/template/app/globals.css +29 -3
  351. package/template/app/layout.tsx +2 -6
  352. package/template/components/ui/badge.tsx +7 -4
  353. package/template/components/ui/button.tsx +1 -1
  354. package/template/components/ui/native-select.tsx +24 -0
  355. package/template/notis.config.ts +4 -36
  356. package/template/package-lock.json +1800 -1867
  357. package/template/package.json +16 -14
  358. package/template/postcss.config.mjs +1 -1
  359. package/template/tailwind.config.ts +1 -6
  360. package/template/tsconfig.json +1 -0
  361. package/template/vite.config.ts +2 -2
  362. package/dist/base-skills/notis-apps/SKILL.md +0 -613
  363. package/skills/notis-apps/cli.md +0 -285
  364. package/src/command-specs/apps.js +0 -3000
  365. package/src/runtime/app-changelog.js +0 -79
  366. package/src/runtime/app-dev-consumers.js +0 -154
  367. package/src/runtime/app-dev-host-lock.js +0 -80
  368. package/src/runtime/app-dev-process-identity.js +0 -111
  369. package/src/runtime/app-dev-roots.js +0 -284
  370. package/src/runtime/app-dev-server.js +0 -1140
  371. package/src/runtime/app-dev-sessions.js +0 -185
  372. package/src/runtime/app-registry-scaffolds.js +0 -367
  373. package/src/runtime/assets/store-screenshot-dark.png +0 -0
  374. package/src/runtime/cli-mode.generated.js +0 -5
  375. package/src/runtime/cli-mode.js +0 -34
  376. package/src/runtime/store-screenshot.js +0 -143
  377. package/template/CHANGELOG.md +0 -5
  378. package/template/app/page.tsx +0 -60
  379. package/template/components/ui/card.tsx +0 -56
  380. package/template/packages/sdk/src/components/DocumentEditor.tsx +0 -103
  381. package/template/packages/sdk/src/config.ts +0 -259
  382. package/template/packages/sdk/src/hooks/useCloudComputer.ts +0 -97
  383. package/template/packages/sdk/src/hooks/useDatabaseSchema.ts +0 -85
  384. package/template/packages/sdk/src/hooks/useDocument.ts +0 -78
  385. package/template/packages/sdk/src/hooks/useNotisNavigation.ts +0 -52
  386. package/template/packages/sdk/src/hooks/useTopBarSearch.ts +0 -73
  387. package/template/packages/sdk/src/runtime.ts +0 -439
  388. package/template/packages/sdk/src/vite.ts +0 -56
  389. package/template/packages/sdk/tsconfig.json +0 -15
  390. /package/{template/packages → dist}/sdk/src/components/MultiSelectDragOverlay.tsx +0 -0
  391. /package/{template/packages → dist}/sdk/src/components/ShortcutHints.tsx +0 -0
  392. /package/{template/packages → dist}/sdk/src/hooks/useActiveResource.ts +0 -0
  393. /package/{template/packages → dist}/sdk/src/hooks/useTool.ts +0 -0
  394. /package/{template/packages → dist}/sdk/src/hooks/useTools.ts +0 -0
  395. /package/{template/packages → dist}/sdk/src/ui.ts +0 -0
@@ -0,0 +1,2 @@
1
+ export { Keycap, KeycapSurface, useKeyLabel } from './Keycap';
2
+ export type { KeycapOn, KeycapProps } from './Keycap';
@@ -0,0 +1,50 @@
1
+ /**
2
+ * `Panels`: a list and the item open from it, side by side while both fit (toolkit spec 2.10).
3
+ *
4
+ * The Manager chat rule, applied inside a Space: when the list minimum plus the reader
5
+ * minimum (320 + 360) no longer fits the Panels container, it shows one pane, the list or
6
+ * the open item, as navigation decides. The open item then slides over the list and comes
7
+ * back with Back (and Esc when `onBack` is given).
8
+ *
9
+ * The switch is a container query on the Panels element (`nui-panels`, 680px for the
10
+ * defaults), not a viewport query and not the host's `data-chat-narrowed` flag: a Space
11
+ * renders in a shadow root, where ancestor attribute variants never reach, and its width is
12
+ * whatever the chat leaves it. JS mirrors the same threshold through a ResizeObserver for
13
+ * `usePanels().mode` (Back, `inert`) and for the drag clamp.
14
+ */
15
+ import { type ReactNode } from 'react';
16
+ export type PanelsMode = 'split' | 'stacked';
17
+ export interface PanelsState {
18
+ /** `split`: list and reader side by side. `stacked`: one pane, the reader over the list. */
19
+ mode: PanelsMode;
20
+ /** The reader width on screen in split mode, inside the container. */
21
+ readerWidth: number;
22
+ /** Choose a reader width (clamped to the container, stored under `storageKey`). */
23
+ setReaderWidth(px: number): void;
24
+ /** A reader is open. */
25
+ readerOpen: boolean;
26
+ /** `mode` is known: the container was measured, or a frame passed without a width (a hidden Space keeps split). */
27
+ settled: boolean;
28
+ }
29
+ export interface PanelsProps {
30
+ list: ReactNode;
31
+ /** The open item; null shows the list alone. */
32
+ reader: ReactNode | null;
33
+ listMin?: number;
34
+ readerMin?: number;
35
+ /** The reader width wanted without a stored choice. Default `readerWantWidth(window)`: 420 under 1280, 480 from 1280. */
36
+ defaultReaderWidth?: number;
37
+ /** A drag handle on the reader's left edge (split mode only). */
38
+ resizable?: boolean;
39
+ /** Keeps the chosen reader width across visits (localStorage `notis:panels:<key>`). */
40
+ storageKey?: string;
41
+ /**
42
+ * Given: in stacked mode Panels shows its own Back bar above the reader and Esc goes back.
43
+ * Leave it out when the reader draws its own Back (read `usePanels().mode`).
44
+ */
45
+ onBack?: () => void;
46
+ className?: string;
47
+ }
48
+ /** The enclosing Panels' state. Outside one: split, no reader, the default width. */
49
+ export declare function usePanels(): PanelsState;
50
+ export declare function Panels({ list, reader, listMin, readerMin, defaultReaderWidth, resizable, storageKey, onBack, className, }: PanelsProps): import("react").JSX.Element;
@@ -0,0 +1,77 @@
1
+ /** The page column (the Manager, a Space, any page) is marked with this attribute. */
2
+ export declare const PAGE_VIEWPORT_ATTRIBUTE = "data-notis-view-viewport";
3
+ export type ChatPanelEdgeMethod = 'drag' | 'keyboard' | 'reset';
4
+ export type ChatPanelEdgeTrigger = 'hover' | 'keyboard';
5
+ export type ChatPanelEdgeOutcome<Page extends string = string> = {
6
+ method: ChatPanelEdgeMethod;
7
+ width: number | null;
8
+ coversPage: boolean;
9
+ page: Page;
10
+ managerPhoneLayout: boolean;
11
+ };
12
+ /** What the edge reports. Structural, so the host's own recorder fits as is. */
13
+ export interface ChatPanelEdgeAnalytics<Page extends string = string> {
14
+ available(page: Page): void;
15
+ resized(outcome: ChatPanelEdgeOutcome<Page>): void;
16
+ pageExtended(trigger: ChatPanelEdgeTrigger, page: Page): void;
17
+ }
18
+ export type ChatPanelEdgeAria = {
19
+ now: number;
20
+ max: number | undefined;
21
+ };
22
+ export interface ChatPanelEdgeAdapters<Page extends string = string> {
23
+ /** The separator element; its parent is the panel. Read lazily: hosts attach refs late. */
24
+ handle(): HTMLElement | null;
25
+ /** The page kind analytics name, read whenever something is reported. */
26
+ page(): Page;
27
+ /** The recorder, read whenever something is reported (a host may swap it). */
28
+ analytics(): ChatPanelEdgeAnalytics<Page>;
29
+ /** The separator's ARIA value changed. */
30
+ onDescribe(aria: ChatPanelEdgeAria): void;
31
+ /**
32
+ * Root custom property where the host publishes its resting sidebar inset (px or rem).
33
+ * Without one the whole window is the resting row.
34
+ */
35
+ sidebarInsetProperty?: string;
36
+ }
37
+ /** The pointer fields the edge reads; a DOM or React pointer event fits. */
38
+ export type EdgePointerEvent = {
39
+ button: number;
40
+ pointerId: number;
41
+ clientX: number;
42
+ currentTarget: EventTarget | null;
43
+ preventDefault(): void;
44
+ };
45
+ /** The key fields the edge reads; a DOM or React keyboard event fits. */
46
+ export type EdgeKeyboardEvent = {
47
+ key: string;
48
+ preventDefault(): void;
49
+ stopPropagation(): void;
50
+ };
51
+ export interface ChatPanelEdge {
52
+ /** Before paint: read the stored width and apply it. */
53
+ mount(): void;
54
+ /** The panel opened or closed. */
55
+ setHidden(hidden: boolean): void;
56
+ /** The desktop layout (the panel beside the page) turned on or off. */
57
+ setDesktop(desktop: boolean): void;
58
+ /** Report the reached denominator: an open desktop panel that shows its edge. */
59
+ reportAvailable(): void;
60
+ /** Track whether the last input was a key press; returns the detach. */
61
+ trackInput(): () => void;
62
+ /** Follow the page viewport (size, sidebar, pointer rest, focus); returns the detach. */
63
+ attach(): () => void;
64
+ pointerDown(event: EdgePointerEvent): void;
65
+ pointerMove(event: EdgePointerEvent): void;
66
+ endDrag(): void;
67
+ keyDown(event: EdgeKeyboardEvent): void;
68
+ doubleClick(): void;
69
+ focus(): void;
70
+ blur(): void;
71
+ }
72
+ /** The page column the panel splits its row with in the host shell. */
73
+ export declare function pageViewport(panel: HTMLElement): HTMLElement | null;
74
+ export declare function createChatPanelEdge<Page extends string = string>(adapters: ChatPanelEdgeAdapters<Page>, initial: {
75
+ hidden: boolean;
76
+ desktop: boolean;
77
+ }): ChatPanelEdge;
@@ -0,0 +1,5 @@
1
+ /** Layout: Panels (list plus open item) and the chat width rule it shares with the Manager. */
2
+ export { Panels, usePanels, type PanelsMode, type PanelsProps, type PanelsState } from './Panels';
3
+ export * as panelMath from './panelMath';
4
+ export * from './panelMath';
5
+ export { PAGE_VIEWPORT_ATTRIBUTE, createChatPanelEdge, pageViewport, type ChatPanelEdge, type ChatPanelEdgeAdapters, type ChatPanelEdgeAnalytics, type ChatPanelEdgeAria, type ChatPanelEdgeMethod, type ChatPanelEdgeOutcome, type ChatPanelEdgeTrigger, type EdgeKeyboardEvent, type EdgePointerEvent, } from './chatPanelEdge';
@@ -0,0 +1,91 @@
1
+ /**
2
+ * The width rule shared by the Manager chat panel and Space `Panels`. Pure: no React, no DOM.
3
+ *
4
+ * Two panes share a row. The side pane (the chat, or a Space's reader) pushes the main pane
5
+ * (the page, or a Space's list) until the main pane reaches its minimum width. Past that the
6
+ * chat slides over the page, as it does on mobile, but stops short of covering it: mobile
7
+ * brings the page back with a swipe, the desktop has no swipe. Resting the pointer on the
8
+ * uncovered strip extends the page back to its minimum width and shrinks the chat, until the
9
+ * pointer returns to the chat. A Space's `Panels` never overlaps: when its two minimums no
10
+ * longer fit, it shows one pane.
11
+ *
12
+ * One chat width serves every page: the protected shell mounts a single panel, so the
13
+ * Manager, Spaces and the floating chat open at the same width. Without a stored preference
14
+ * the chat is 420px at every window width; a Space reader wants 420px under a 1280px window
15
+ * and 480px from 1280px (`readerWantWidth`).
16
+ */
17
+ /** CSS custom property the chat panel reads its width from on lg+. */
18
+ export declare const CHAT_PANEL_WIDTH_PROPERTY = "--notis-chat-panel-width";
19
+ /** CSS custom property for how far the chat panel slides over the page on lg+. */
20
+ export declare const CHAT_PANEL_OVERLAP_PROPERTY = "--notis-chat-panel-overlap";
21
+ export declare const CHAT_PANEL_WIDTH_STORAGE_KEY = "notis:chat-panel-width";
22
+ /** The chat panel width without a stored preference, at every window width (mirrors its `lg:w-[...,420px]` fallback). */
23
+ export declare const CHAT_PANEL_DEFAULT_WIDTH_PX = 420;
24
+ /** The panel sits beside the page, with its edge, from Tailwind's `lg` up. */
25
+ export declare const CHAT_PANEL_DESKTOP_MEDIA_QUERY = "(min-width: 64rem)";
26
+ /**
27
+ * A chosen panel width that leaves the page narrower than this switches the Manager to its
28
+ * phone layout (the `manager-md:`/`manager-lg:` variants in the Portal's globals.css read the
29
+ * flag). Spaces switch on their own container width instead (see `Panels`).
30
+ */
31
+ export declare const MANAGER_PHONE_LAYOUT_BELOW_PX = 576;
32
+ /** Set on the page viewport while the chosen panel width narrows the page. */
33
+ export declare const CHAT_NARROWED_ATTRIBUTE = "data-chat-narrowed";
34
+ /** The phone layout already renders the panel this narrow, so the composer fits it. */
35
+ export declare const CHAT_PANEL_MIN_WIDTH_PX = 360;
36
+ /** The panel never squeezes the page narrower than this; it slides over the page instead. */
37
+ export declare const CHAT_PANEL_MIN_CONTENT_WIDTH_PX = 320;
38
+ /** At its widest the panel still leaves this much of the page visible and clickable. */
39
+ export declare const CHAT_PANEL_PAGE_PEEK_PX = 80;
40
+ export declare const CHAT_PANEL_KEYBOARD_STEP_PX = 24;
41
+ /** How long the pointer rests on the page strip before the page extends; a pass is not a rest. */
42
+ export declare const CHAT_PANEL_PAGE_HOVER_DELAY_MS = 200;
43
+ /** `Panels` defaults: the same two minimums and the same page peek as the chat rule. */
44
+ export declare const PANELS_LIST_MIN_PX = 320;
45
+ export declare const PANELS_READER_MIN_PX = 360;
46
+ export declare const PANELS_READER_PEEK_PX = 80;
47
+ export declare const PANELS_KEYBOARD_STEP_PX = 24;
48
+ export declare const PANELS_HOVER_DELAY_MS = 200;
49
+ /** The reader width a Space wants under a 1280px window. */
50
+ export declare const PANELS_READER_WANT_PX = 420;
51
+ /** The reader width a Space wants from a 1280px window. */
52
+ export declare const PANELS_READER_WANT_WIDE_PX = 480;
53
+ /** The window width from which a Space reader wants `PANELS_READER_WANT_WIDE_PX`. */
54
+ export declare const PANELS_READER_WIDE_FROM_PX = 1280;
55
+ /** The reader width a Space wants in a window `windowWidth` px wide: 420 under 1280, 480 from 1280. */
56
+ export declare function readerWantWidth(windowWidth: number): number;
57
+ /**
58
+ * Widest a side pane may get in a row of `container` px (null when unknown) while `keep` px
59
+ * of the main pane stay visible. A row too narrow for both still gives the side pane its
60
+ * own minimum.
61
+ */
62
+ export declare function readerMaxWidth(container: number | null, keep?: number, readerMin?: number): number;
63
+ /** Widest a side pane gets without covering any of a main pane of minimum `listMin`. */
64
+ export declare function pushLimit(container: number | null, listMin?: number, readerMin?: number): number;
65
+ /** How far a side pane this wide slides over the main pane rather than squeezing it further. */
66
+ export declare function overlap(width: number, container: number | null, listMin?: number): number;
67
+ /** Both panes fit side by side at their minimums; otherwise `Panels` shows one pane. */
68
+ export declare function splitFits(container: number | null, listMin?: number, readerMin?: number): boolean;
69
+ /** The container width at which `Panels` switches between one pane and two. */
70
+ export declare function splitBreakpoint(listMin?: number, readerMin?: number): number;
71
+ /**
72
+ * A `Panels` reader width in a Space `container` px wide (null when unknown):
73
+ * `clamp(min(want, S - listMin), readerMin, S - peek)`. The list keeps its minimum first; a
74
+ * row too narrow for both gives the reader its own minimum, but always leaves the peek.
75
+ */
76
+ export declare function clampReaderWidth(want: number, container: number | null, listMin?: number, readerMin?: number, peek?: number): number;
77
+ /** A stored width is a preference only when it is a positive finite number. */
78
+ export declare function parseStoredWidth(raw: string | null): number | null;
79
+ /**
80
+ * Widest the chat panel may get. `sharedWidth` is the room the panel shares with the page
81
+ * (null when unknown). A row too narrow for both still gives the panel its own minimum.
82
+ */
83
+ export declare function chatPanelMaxWidth(sharedWidth: number | null): number;
84
+ /** Widest the chat panel gets without covering any of the page. */
85
+ export declare function chatPanelPushLimit(sharedWidth: number | null): number;
86
+ export declare function clampChatPanelWidth(width: number, sharedWidth: number | null): number;
87
+ /** The page width a chosen panel width leaves in a row of `sharedWidth`. */
88
+ export declare function chatPanelPageWidth(chosenWidth: number, sharedWidth: number): number;
89
+ /** How far a chat panel this wide slides over the page rather than squeezing it further. */
90
+ export declare function chatPanelOverlap(width: number, sharedWidth: number | null): number;
91
+ export declare function parseStoredChatPanelWidth(raw: string | null): number | null;
@@ -0,0 +1,380 @@
1
+ /**
2
+ * ListReader (toolkit spec 2.3): a list beside a reader, with the Manager's keys, selection, actions and open modes.
3
+ *
4
+ * It composes `useListKeys`, `useSelection`, `useActions`, `useSelectionBar`, `useOpenMode` and `Panels`:
5
+ * - J/K move the cursor (wrapping on a fresh press), Enter or a click opens the item in the current open mode.
6
+ * - X, Shift+J/K, Mod+A, Mod/Shift-click and press and hold select; the selection bar shows the bulk actions.
7
+ * - Esc closes the open item first, then clears the selection.
8
+ * - After an action takes the cursor row off the list, the cursor (and an open item) moves to the next row, else the
9
+ * previous one. An E action (Complete, Archive) whose items stay in the list moves on to the row after them.
10
+ * - Side: the reader sits beside the list (Panels; below the Panels minimum it slides over the list with Back).
11
+ * Center: a dialog over the list (max 880px), J/K still step through items. Full: the reader replaces the list.
12
+ * - The open id lives in the URL (`openParam`, default `open`): the Space URL inside a Space, the page URL (history)
13
+ * on a Notis page, so reload and links restore it. An open id missing from the list shows "Item not found".
14
+ * - `onOpenChange` may keep the open item (unsaved edits): the list then says why in its toast. An open item that
15
+ * leaves the list (a search, a refresh, a delete) stays in the reader while the page keeps it, so a page that
16
+ * deletes the open item drops its unsaved edits first and the list moves on.
17
+ * - Toolbar: one 44px line (a status title, the tabs, "+" and the view menu), then an optional 44px info line. The
18
+ * search lives in the top bar (`search`), and the open item's label joins the top bar title (`crumbLabel`).
19
+ * - Reader bar (48px): close or back, open as, previous, next, the item's label, its actions, More, then Open as full
20
+ * page (center) or a second close (one pane). Actions past the bar's room fold into More.
21
+ * - Sizing: the list fills its parent (height 100%, flex 1); the page gives it a set height.
22
+ * - Reorder (`reorder`, off by default): drag a row, or Alt and an arrow key, to move it one item at a time; the new
23
+ * order shows at once and goes back if `onReorder` rejects (`useReorder`). Off while a local search filters the list
24
+ * or `groupBy` groups it.
25
+ */
26
+ import { type DragEvent as ReactDragEvent, type ReactNode, type Ref } from 'react';
27
+ import { type ActionOption, type ActionRef, type KeySpec, type Words } from '../../words';
28
+ import { type ActionHandlers, type ActionOutcome, type ResolvedAction } from '../actions/useActions';
29
+ import type { ToastOptions } from '../actions/useToast';
30
+ import { type TabRowProps } from '../blocks/Tabs';
31
+ import type { OpenMode } from '../open/openModeStore';
32
+ import { type ListBoard } from '../board/boardModel';
33
+ import { type RowState } from './rowState';
34
+ import { type ReorderChange } from './useReorder';
35
+ /** What the reader slot and the header get besides their item. */
36
+ export interface ReaderCtx<T = unknown> {
37
+ /** Closes the item. Returns false when `onOpenChange` kept it open (the list then says why). */
38
+ close(): boolean;
39
+ /** Opens the next item (wraps from the last to the first when the list wraps). */
40
+ next(): void;
41
+ /** Opens the previous item (wraps from the first to the last when the list wraps). */
42
+ prev(): void;
43
+ hasNext: boolean;
44
+ hasPrev: boolean;
45
+ mode: OpenMode;
46
+ setMode(mode: OpenMode): void;
47
+ /**
48
+ * The section the item was opened at (`apiRef.current.open(id, { section })`), else null. The reader scrolls the
49
+ * element with `data-section="<section>"` into view once it renders.
50
+ */
51
+ section: string | null;
52
+ /** Shows words in the list's toast, the one its actions use (`useToast`). */
53
+ notify(words: Words | string, options?: ToastOptions): void;
54
+ /** The list's actions that apply to the open item, in list order (a toggle pair shows the half that fits it). */
55
+ actions: ResolvedAction<T>[];
56
+ /** Ids of the list's actions running now: a reader bar button for one shows busy. */
57
+ busy: ReadonlySet<string>;
58
+ /**
59
+ * Runs one of the list's actions on the open item, as its key does: busy while it runs, the list's toast after it
60
+ * (Undo and Z when it returned an UndoFn), and an E action moves the reader on to the next item. An action with
61
+ * options and no `option` opens its picker in the reader bar, at the bar button that has focus; the promise
62
+ * then settles with the run of the option chosen, or cancelled when the picker closes. An id the list does not have,
63
+ * or an action that does not apply to the item, settles cancelled.
64
+ */
65
+ run(action: ResolvedAction<T> | string, option?: ActionOption): Promise<ActionOutcome<T>>;
66
+ /**
67
+ * The open item's actions in a More menu, the menu its row has (null when none applies or it is pending). The reader
68
+ * bar already draws it; this places the same menu in the reader body too.
69
+ */
70
+ actionsMenu: ReactNode;
71
+ }
72
+ /** One button of the reader bar (`readerActions`): an icon, and its label and key when `labelled` or keyed. */
73
+ export interface ReaderAction {
74
+ id: string;
75
+ label: Words | string;
76
+ /** An icon name. */
77
+ icon: string;
78
+ /** Its key: shown on the button, and it runs the action while the item is open. */
79
+ key?: KeySpec;
80
+ /** Shows the label beside the icon. Default true when `key` is set; an unlabelled button shows it in a tooltip. */
81
+ labelled?: boolean;
82
+ /** Shows the button disabled: neither a click, its key nor the More menu runs it. Every action is disabled while the open item is pending (`isPending`). */
83
+ disabled?: boolean;
84
+ run(): void | Promise<void>;
85
+ }
86
+ /** The parts of one tile (`renderTile`): a mark, a title and subtitle, a body, then a figure and a trailing node. */
87
+ export interface TileParts {
88
+ /** A 36px mark (logo, monogram) beside the title and subtitle. */
89
+ mark?: ReactNode;
90
+ title: ReactNode;
91
+ subtitle?: ReactNode;
92
+ body?: ReactNode;
93
+ /** A figure at the bottom start (a count, a price). */
94
+ figure?: ReactNode;
95
+ /** At the bottom end (a status, a date, an avatar). */
96
+ trailing?: ReactNode;
97
+ }
98
+ /** One choice of the view menu's Sort or Group part, or one of its `actions`. */
99
+ export interface ViewMenuItem {
100
+ id: string;
101
+ label: Words | string;
102
+ icon?: string;
103
+ checked?: boolean;
104
+ onSelect(): void;
105
+ }
106
+ /** The view menu (`viewMenu`): sort and group choices, a layout switch, view actions and a description, in one "..." button. */
107
+ export interface ViewMenuProps {
108
+ sort?: readonly ViewMenuItem[];
109
+ group?: readonly ViewMenuItem[];
110
+ layout?: {
111
+ value: string;
112
+ options: ReadonlyArray<{
113
+ value: string;
114
+ label: Words | string;
115
+ icon?: string;
116
+ }>;
117
+ onChange(value: string): void;
118
+ };
119
+ /** Commands on the whole view ("Refresh research"), after the choices; `checked` is ignored. */
120
+ actions?: readonly ViewMenuItem[];
121
+ /** A muted line at the end of the menu (what the view shows). */
122
+ description?: Words | string;
123
+ }
124
+ /** The top bar search of a list (`search`). Without `onChange` the list keeps the query and filters with `match`. */
125
+ export interface ListSearchProps<T> {
126
+ placeholder?: Words | string;
127
+ value?: string;
128
+ onChange?(value: string): void;
129
+ onSubmit?(): void | Promise<void>;
130
+ /** Whether an item matches the query (local query only). Default: its title or name holds the query. */
131
+ match?(item: T, query: string): boolean;
132
+ }
133
+ /** Imperative control of a ListReader (`apiRef`). */
134
+ export interface ListReaderApi {
135
+ /**
136
+ * Opens an item, optionally at a section of its reader (see `ReaderCtx.section`). Returns false when it did not
137
+ * open: the item is disabled, or `onOpenChange` kept the open item (the list then says why).
138
+ */
139
+ open(id: string, options?: {
140
+ section?: string;
141
+ }): boolean;
142
+ /** Closes the open item. Returns false when `onOpenChange` kept it open (the list then says why). */
143
+ close(): boolean;
144
+ /** Moves the cursor without opening. */
145
+ focus(id: string): void;
146
+ /** Shows words in the list's toast, the one its actions use (`useToast`). */
147
+ notify(words: Words | string, options?: ToastOptions): void;
148
+ }
149
+ /** What `onOpenChange` returns: false, words or a string keep the open item; anything else lets the change happen. */
150
+ export type OpenChangeVerdict = void | boolean | Words | string;
151
+ /** Why an open change happens: a click, a key or the API (`user`), a move the list makes itself (`auto`: autoOpen, the open item left the list, an E action moved on), or the URL (`url`: load, Back and Forward, a Space link). */
152
+ export type OpenChangeReason = 'user' | 'auto' | 'url';
153
+ /** One group heading of a ListReader (`groupBy`). */
154
+ export interface ListGroup {
155
+ id: string;
156
+ label: Words | string;
157
+ }
158
+ /** The props of `ListReader`. */
159
+ export interface ListReaderProps<T> {
160
+ items: readonly T[];
161
+ /** Default `item.id`. */
162
+ getId?: (item: T) => string;
163
+ /** One row, usually `<Row />`; the list draws the row element and its states around it. */
164
+ row: (item: T, state: RowState) => ReactNode;
165
+ /** The open item. Leave out for a list without a reader (Enter then only calls `onOpen`). */
166
+ reader?: (item: T, ctx: ReaderCtx<T>) => ReactNode;
167
+ /** Standard action ids or custom actions, in order. */
168
+ actions?: readonly ActionRef<T>[];
169
+ /** The Space's runs for the standard ids it lists (a standard id without one is hidden). */
170
+ handlers?: ActionHandlers<T>;
171
+ /** Modes offered, the first is the default. Default side, center and full. */
172
+ openAs?: OpenMode | readonly OpenMode[];
173
+ /** 48px (default) or 40px rows. */
174
+ density?: 'comfortable' | 'compact';
175
+ /**
176
+ * 'table': `row` returns the cells; `columns` gives the header cells. 'board': one column per stage of `board`
177
+ * (BoardView sets it), each drawing its tiles with `renderTile`.
178
+ */
179
+ layout?: 'list' | 'table' | 'tiles' | 'board';
180
+ /** Board layout: the columns, each item's column and how tiles move. Ignored by the other layouts. */
181
+ board?: ListBoard<T>;
182
+ /** Tiles layout: draws each tile from its parts instead of `row`. */
183
+ renderTile?: (item: T) => TileParts;
184
+ /** Tiles layout: 'manager' tiles keep a 152px minimum height. */
185
+ tileVariant?: 'default' | 'manager';
186
+ /** 'two-tone' tints the list beside the reader at all times; 'plain' (default) only while an item is open. */
187
+ look?: 'two-tone' | 'plain';
188
+ /** Header cells of the table layout. */
189
+ columns?: ReactNode;
190
+ /** Consecutive items with the same group id share a heading. */
191
+ groupBy?: (item: T) => ListGroup;
192
+ /** Default true when an action is bulk. */
193
+ selectable?: boolean;
194
+ /**
195
+ * Drag from empty space in the list to select the rows under the rectangle (the Manager's marquee), whenever the
196
+ * list allows multiple selection. Pending and disabled rows are skipped. Default true; false turns it off.
197
+ */
198
+ dragSelect?: boolean;
199
+ /** J on the last row goes to the first. Default true. */
200
+ wrap?: boolean;
201
+ /** Shown when `items` is empty. Default `<EmptyState />`. */
202
+ empty?: ReactNode;
203
+ /** At the toolbar start: what the list shows now (a status, "Inbox"), never the page or view name. */
204
+ title?: {
205
+ text: Words | string;
206
+ count?: number;
207
+ };
208
+ /** Pills in the toolbar line (TabRow); the title leads them unless `tabs.lead` is set. */
209
+ tabs?: Omit<TabRowProps<string>, 'end'>;
210
+ /** Icon buttons at the toolbar end, before "+" (a refresh). Keep them few; the rest go in `actions`. */
211
+ toolbarActions?: ReactNode;
212
+ /** A "+" at the toolbar end, its label in a tooltip; `key` also runs it. */
213
+ create?: {
214
+ label: Words | string;
215
+ onCreate(): void;
216
+ key?: KeySpec;
217
+ };
218
+ /** A "..." at the toolbar end with the view's sort, group and layout choices. */
219
+ viewMenu?: ViewMenuProps;
220
+ /** One 44px line under the toolbar (a sync state, a notice). */
221
+ infoLine?: ReactNode;
222
+ /** The top bar search for this list. Leave out for a list with no search. */
223
+ search?: ListSearchProps<T>;
224
+ /**
225
+ * Below the list, outside its scroll (page numbers, a count): one 48px line, at the end of the row. It belongs to
226
+ * the list: beside an open reader it stays under the list, a reader over the list covers it, and it keeps clear of
227
+ * the floating Notis button. The selection bar and the undo toast sit above it.
228
+ */
229
+ footer?: ReactNode;
230
+ /** The open item's label in the reader bar (an id, "PRO-002"). */
231
+ readerLabel?: (item: T) => ReactNode;
232
+ /**
233
+ * The open item's buttons in the reader bar, before its More menu. `ctx.run` runs one of the list's actions with
234
+ * the list's toast. Buttons past the bar's room (more than three) fold into More.
235
+ */
236
+ readerActions?: (item: T, ctx: ReaderCtx<T>) => readonly ReaderAction[];
237
+ /**
238
+ * The open item's leaf in the top bar title ("Tickets / PRO-002"), in every open mode; null for none. Default the
239
+ * item's `title`, else its `name`, when it is a string.
240
+ */
241
+ crumbLabel?: (item: T) => string | null;
242
+ /**
243
+ * Side mode beside the list: open the first item once the list loads (no history step), and with nothing open
244
+ * show "Pick something from the list to read it." in the reader. Default false.
245
+ */
246
+ autoOpen?: boolean;
247
+ /** The URL param holding the open id. Default 'open'. Declare it in the Space's `params` (type text). */
248
+ openParam?: string;
249
+ /**
250
+ * Outside a Space: keep the open id in the page URL (`?open=`, history push on open and close). Default true.
251
+ * Ignored when `open` is controlled.
252
+ */
253
+ openInUrl?: boolean;
254
+ /** Controlled selection (ids); pair with `onSelectedChange`. */
255
+ selected?: readonly string[];
256
+ onSelectedChange?: (ids: string[]) => void;
257
+ /**
258
+ * After an action ran on the selection: 'clear' (default) empties it and keeps only the items that failed;
259
+ * 'keep' leaves it as it was. A cancelled run never changes it.
260
+ */
261
+ afterAction?: 'clear' | 'keep';
262
+ /**
263
+ * Rows can be dragged (all, or the ones this returns true for). Dragging a selected row carries the whole
264
+ * selection in list order. The drag data holds the ids as JSON under `LIST_DRAG_TYPE` and one per line as text.
265
+ */
266
+ draggable?: boolean | ((item: T) => boolean);
267
+ onDragStart?: (items: T[], event: ReactDragEvent<HTMLElement>) => void;
268
+ /**
269
+ * Rows can be put in a new order (off when left out): drag one, or press Alt and an arrow key (all four in tiles),
270
+ * Alt+Home or Alt+End. One item moves at a time. The new order shows at once; `onReorder` saves it, and when its
271
+ * promise rejects the list goes back to `items` and says it could not save (an `ActionError` reason shows under it).
272
+ * Off while a local search filters the list or `groupBy` groups it. Pending and disabled rows do not move.
273
+ */
274
+ reorder?: ListReorder<T>;
275
+ /** The first page is loading: skeleton rows while `items` is empty, a thin bar above the list otherwise. */
276
+ loading?: boolean;
277
+ /** More items can be loaded: a Load more button at the end, loaded as it scrolls into view and by J on the last row. */
278
+ hasMore?: boolean;
279
+ onLoadMore?: () => void | Promise<void>;
280
+ /** The next page is loading. */
281
+ loadingMore?: boolean;
282
+ /**
283
+ * A change on this item is being saved: it shows busy, cannot be selected, dragged or acted on (it still opens).
284
+ * A run may mark its own items pending: they leave the selection while it lasts, and once it ends `afterAction`
285
+ * applies to the selection the run started on (the failed items come back even before the marks clear).
286
+ */
287
+ isPending?: (item: T) => boolean;
288
+ /** This item cannot be opened, selected, dragged or acted on. */
289
+ isDisabled?: (item: T) => boolean;
290
+ /** Group headings fold their rows away. Default false. */
291
+ collapsible?: boolean;
292
+ /** Controlled folded group ids; pair with `onCollapsedChange`. */
293
+ collapsed?: readonly string[];
294
+ onCollapsedChange?: (ids: string[]) => void;
295
+ /** A muted count after each group heading. Default true. */
296
+ groupCounts?: boolean;
297
+ /** Imperative control: open an item (at a section), close, move the cursor, show a toast. */
298
+ apiRef?: Ref<ListReaderApi>;
299
+ /**
300
+ * Called with the item the reader shows, null when it closes: after a click, a key or the API, and when the URL
301
+ * opens one (on load, Back and Forward, a Space link). Without a reader, Enter and a click call it with the item.
302
+ */
303
+ onOpen?: (item: T | null) => void;
304
+ /**
305
+ * The page an item opens, for the desktop's right-click Open in new tab, Open in browser and Copy link. Default: the
306
+ * current URL with the open param set, when the open id lives in the URL. Return null for an item with no page.
307
+ */
308
+ itemHref?: (item: T) => string | null | undefined;
309
+ /** Controlled open id; pair with `onOpenChange`. */
310
+ open?: string | null;
311
+ /**
312
+ * Called with the id about to open (null to close): a click, a key, the API, Back and Forward, a Space link.
313
+ * Return false to keep the current item open, for example while its reader has unsaved edits: the list, the
314
+ * cursor and the URL stay as they are and the list's toast says "Save or cancel your changes first.". Return words
315
+ * or a string to say something else. `reason` says why the change happens; a move the list makes on its own
316
+ * (`auto`) is kept without a toast.
317
+ */
318
+ onOpenChange?: (id: string | null, reason: OpenChangeReason) => OpenChangeVerdict;
319
+ /** Shortcut owner of this list. Default a child of the Space's owner, one per list. */
320
+ scope?: string;
321
+ /** The list's id inside the Space: keys the open mode and the reader width. Default 'list'. */
322
+ listId?: string;
323
+ /** Accessible name of the list. */
324
+ label?: Words | string;
325
+ className?: string;
326
+ }
327
+ /** How a ListReader's rows are put in a new order (see `reorder`). */
328
+ export interface ListReorder<T> {
329
+ /** Save the move: the item, its index before and after, and every id in the new order. */
330
+ onReorder: (change: ReorderChange<T>) => void | Promise<unknown>;
331
+ /** Only these items move (all by default). */
332
+ canReorder?: (item: T) => boolean;
333
+ }
334
+ /** Every word ListReader shows, in English and French. */
335
+ export declare const LIST_READER_WORDS: Readonly<{
336
+ list: Words;
337
+ open: Words;
338
+ openFull: Words;
339
+ viewOptions: Words;
340
+ sort: Words;
341
+ group: Words;
342
+ layout: Words;
343
+ pickOne: Words;
344
+ pickKeys: Words;
345
+ rowActions: Words;
346
+ loadMore: Words;
347
+ loading: Words;
348
+ expandGroup: Words;
349
+ collapseGroup: Words;
350
+ keptOpen: Words;
351
+ notMoved: Words;
352
+ notFound: Words;
353
+ notFoundBody: Words;
354
+ }>;
355
+ /** The drag data type of list rows: a JSON array of ids. */
356
+ export declare const LIST_DRAG_TYPE = "application/x-notis-items";
357
+ /**
358
+ * An item's menu order (deck menu rank): the first E action, then the status actions, the others in list order,
359
+ * and the danger ones last.
360
+ */
361
+ export declare function rankActions<A extends {
362
+ id: string;
363
+ key?: KeySpec;
364
+ tone?: string;
365
+ }>(actions: readonly A[]): A[];
366
+ /** The id that takes `gone`'s place: the next one still in `now`, else the previous one. */
367
+ export declare function successorOf(previous: readonly string[], now: readonly string[], gone: string): string | null;
368
+ /** A list beside a reader, with the Manager's keys, selection, actions and open modes (see the file header). */
369
+ export interface ListSkeletonProps {
370
+ /** Draw a group head first, for a list that groups its rows. */
371
+ grouped?: boolean;
372
+ rows?: number;
373
+ }
374
+ /**
375
+ * The list while its first page loads, drawn like the rows it stands for: a group head when the list
376
+ * groups, then a lead mark and a title over a meta line. Pages use it for their own route fallbacks so
377
+ * the page does not shift when the real list arrives.
378
+ */
379
+ export declare function ListSkeleton({ grouped, rows }: ListSkeletonProps): import("react").JSX.Element;
380
+ export declare function ListReader<T>(props: ListReaderProps<T>): import("react").JSX.Element;