@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,58 @@
1
+ /**
2
+ * The comment pane and its pieces, rendered from a `useComments` controller:
3
+ *
4
+ * - `CommentPane`: the side panel (filters, Copy changes, the new comment box, the thread cards, the delete
5
+ * confirmation and the toast).
6
+ * - `CommentPins`: the numbered pins and zones on the anchor element. Put it inside the element the comments sit on (a
7
+ * slide, a section) and give that element `position: relative`. With `controller.commenting` on it covers the element:
8
+ * a click drops a pin, a press and drag marks a zone (when the table has zone columns). The pane's "Comment on this
9
+ * item" starts a comment on the whole anchor, with no pin.
10
+ * - `CommentThreadCard`, `NewCommentBox` and `CommentAvatar` for Spaces that lay the pane out themselves.
11
+ *
12
+ * Keyboard: Enter sends a reply or a new comment and Shift+Enter adds a line; Escape in an empty new comment drops it
13
+ * (with text, the first Escape leaves the field); Escape leaves Add comment mode; a thread card selects with Enter.
14
+ */
15
+ import React from 'react';
16
+ import { type CommentThread } from './commentModel';
17
+ import type { CommentController } from './useComments';
18
+ export interface CommentAvatarProps {
19
+ author: string;
20
+ /** The person using the Space: their avatar is filled, everyone else's is quiet. */
21
+ me?: string;
22
+ className?: string;
23
+ }
24
+ /** The author's initial. Decorative: the author's name is always written next to it. */
25
+ export declare function CommentAvatar({ author, me, className }: CommentAvatarProps): React.JSX.Element;
26
+ export interface CommentThreadCardProps {
27
+ controller: CommentController;
28
+ thread: CommentThread;
29
+ /** Name the anchor in the card's meta line (when the pane lists every anchor). */
30
+ showAnchor?: boolean;
31
+ }
32
+ export declare function CommentThreadCard({ controller, thread, showAnchor }: CommentThreadCardProps): React.JSX.Element;
33
+ export interface NewCommentBoxProps {
34
+ controller: CommentController;
35
+ }
36
+ /** The box for the comment `controller.draftPin` started. Takes focus when it opens. */
37
+ export declare function NewCommentBox({ controller }: NewCommentBoxProps): React.JSX.Element | null;
38
+ export interface CommentPinsProps {
39
+ controller: CommentController;
40
+ /** The anchor the pins sit on. Default: `controller.anchorKey`. */
41
+ anchorKey?: string | null;
42
+ /** A pin was pressed. Default: `controller.selectThread`. */
43
+ onOpen?(thread: CommentThread): void;
44
+ }
45
+ /**
46
+ * Numbered pins at each thread's x and y on the anchor element, the zones threads mark, and the pin or zone of the
47
+ * comment being written. In Add comment mode it also covers the element to take the click or drag that places one.
48
+ */
49
+ export declare function CommentPins({ controller, anchorKey, onOpen }: CommentPinsProps): React.JSX.Element;
50
+ export interface CommentPaneProps {
51
+ controller: CommentController;
52
+ /** The heading. Default "Comments". */
53
+ title?: string;
54
+ /** Hide Copy changes (a pane read by people only). Default shown. */
55
+ showCopy?: boolean;
56
+ className?: string;
57
+ }
58
+ export declare function CommentPane({ controller, title, showCopy, className }: CommentPaneProps): React.JSX.Element;
@@ -0,0 +1,157 @@
1
+ /**
2
+ * Comment threads on a Space database (pure; no React). The table shape is the Notis Slides Comments table:
3
+ *
4
+ * | Column | Type | Meaning |
5
+ * | ----------- | -------------------- | --------------------------------------------------------------------- |
6
+ * | Body | title | The comment text. |
7
+ * | Deck | relation | The scope the comment belongs to (a deck, a page, a review). |
8
+ * | Slide | relation | The anchor record it is on (a slide, a section). Empty: on the scope. |
9
+ * | Thread | text | Empty on a thread's first comment; the root's record key on a reply. |
10
+ * | Author | select | Who wrote it (Flo, Claude, Notis, or any name). |
11
+ * | X, Y | number | The pin, 0 to 1 across and down the anchor. Empty: on the whole anchor. |
12
+ * | W, H | number | A zone from the pin, 0 to 1 of the anchor's width and height. Empty: a point. |
13
+ * | Status | select | Open, Resolved or Deleted (a delete keeps the row for the digest). |
14
+ * | Needs | select | none, check, choice or input: what the author asks of the reader. |
15
+ * | Options | text | The choices of a choice ask, separated by `|`. |
16
+ * | Answer | text | The reader's answer to the ask. |
17
+ * | Answered at | date | When the answer was given. |
18
+ * | Change | select | The last change made here: created, replied, answered, resolved, reopened, deleted. |
19
+ * | Changed at | date | When that change was made; the digest lists changes after the checkpoint. |
20
+ * | Example | checkbox | A sample comment shown with an Example badge. |
21
+ *
22
+ * Every column name can be renamed with `CommentColumns`; the defaults are the Slides names, so a Space that copies
23
+ * the Slides table needs no mapping and no migration. Zones are opt-in: a table that adds W and H number columns
24
+ * passes `{ w: 'W', h: 'H' }`. Without them (`w` and `h` null, the default) a drag on the anchor places a pin where it
25
+ * started, and nothing writes a column the table does not have.
26
+ */
27
+ export type CommentRow = Record<string, unknown>;
28
+ export type CommentNeeds = 'none' | 'check' | 'choice' | 'input';
29
+ export type CommentStatus = 'Open' | 'Resolved' | 'Deleted';
30
+ export type CommentChange = 'created' | 'replied' | 'answered' | 'resolved' | 'reopened' | 'deleted';
31
+ /** Column names of the Comments table. `scope` or `anchor` set to null: the table has no such column. */
32
+ export interface CommentColumns {
33
+ body: string;
34
+ scope: string | null;
35
+ anchor: string | null;
36
+ thread: string;
37
+ author: string;
38
+ x: string;
39
+ y: string;
40
+ /** The zone's width and height. Null: the table has no zone columns, and comments are points only. */
41
+ w: string | null;
42
+ h: string | null;
43
+ status: string;
44
+ needs: string;
45
+ options: string;
46
+ answer: string;
47
+ answeredAt: string;
48
+ change: string;
49
+ changedAt: string;
50
+ example: string;
51
+ }
52
+ export declare const COMMENT_COLUMNS: Readonly<CommentColumns>;
53
+ export declare function commentColumns(columns?: Partial<CommentColumns>): CommentColumns;
54
+ export interface CommentRecord {
55
+ id: string;
56
+ recordKey: string;
57
+ revision: number;
58
+ body: string;
59
+ scopeIds: string[];
60
+ anchorIds: string[];
61
+ thread: string;
62
+ author: string;
63
+ x: number | null;
64
+ y: number | null;
65
+ w: number | null;
66
+ h: number | null;
67
+ status: CommentStatus;
68
+ needs: CommentNeeds;
69
+ options: string[];
70
+ answer: string;
71
+ answeredAt: string | null;
72
+ change: CommentChange | null;
73
+ changedAt: string | null;
74
+ example: boolean;
75
+ createdAt: string | null;
76
+ }
77
+ /** The record a thread sits on (a slide, a section). `order` numbers it in the digest and the card meta. */
78
+ export interface CommentAnchor {
79
+ id: string;
80
+ recordKey: string;
81
+ order: number;
82
+ title: string;
83
+ }
84
+ /** The record the comments belong to (a deck, a page). `checkpoint` is the last time changes were copied. */
85
+ export interface CommentScope {
86
+ id: string;
87
+ recordKey: string;
88
+ name: string;
89
+ checkpoint: string | null;
90
+ }
91
+ export interface CommentThread {
92
+ root: CommentRecord;
93
+ replies: CommentRecord[];
94
+ anchor: CommentAnchor | undefined;
95
+ }
96
+ /** One Comments row as a comment. An author outside `authors` (when given) reads as `fallbackAuthor`. */
97
+ export declare function readCommentRow(row: CommentRow, options?: {
98
+ columns?: Partial<CommentColumns>;
99
+ authors?: readonly string[];
100
+ fallbackAuthor?: string;
101
+ }): CommentRecord;
102
+ /** The rows of a list answer (`{ rows }`), skipping anything that is not an object. */
103
+ export declare function commentRowsOf(value: unknown): CommentRow[];
104
+ /** Time in ms; a date without an offset is read as UTC so ordering stays stable. */
105
+ export declare function commentTimeOf(value: string | null | undefined): number;
106
+ /** True when the comment belongs to `scope` (by id or record key). No scope: every comment belongs. */
107
+ export declare function inCommentScope(comment: CommentRecord, scope: Pick<CommentScope, 'id' | 'recordKey'> | null | undefined): boolean;
108
+ export declare function commentAnchorOf(comment: CommentRecord, anchors: readonly CommentAnchor[]): CommentAnchor | undefined;
109
+ /** Threads in anchor order, then by creation; deleted replies are left out. Deleted roots stay (filter them to hide). */
110
+ export declare function commentThreads(comments: readonly CommentRecord[], anchors: readonly CommentAnchor[]): CommentThread[];
111
+ /** Changes after the checkpoint: `me`'s comments and replies, and every answer or status change. */
112
+ export declare function commentChangesSince(comments: readonly CommentRecord[], checkpoint: string | null | undefined, me?: string): CommentRecord[];
113
+ export interface CommentDigestOptions {
114
+ /** First line, before the scope name. Default "Slide comments". */
115
+ heading?: string;
116
+ /** What the scope is called ("Deck"): the fallback name and "Deck record". */
117
+ scopeNoun?: string;
118
+ /** What an anchor is called ("Slide"): "Slide 3" and "Unknown slide". */
119
+ anchorNoun?: string;
120
+ /** The table agents insert replies into. Default "Comments". */
121
+ table?: string;
122
+ /** The reader whose answers and status changes the digest reports. Default "Flo". */
123
+ me?: string;
124
+ columns?: Partial<CommentColumns>;
125
+ }
126
+ /** True when the comment marks a zone (a pin with a width and a height), not a point. */
127
+ export declare function isCommentZone(comment: Pick<CommentRecord, 'x' | 'y' | 'w' | 'h'> | null | undefined): boolean;
128
+ /**
129
+ * The compact digest pasted into an agent's chat: every change since the scope's checkpoint, with where it is, what
130
+ * changed and the thread state. Always English: it is read by agents, not shown to people.
131
+ */
132
+ export declare function commentDigest(input: {
133
+ scope: CommentScope | null;
134
+ comments: readonly CommentRecord[];
135
+ anchors: readonly CommentAnchor[];
136
+ changes: readonly CommentRecord[];
137
+ nowIso: string;
138
+ }, options?: CommentDigestOptions): string;
139
+ /** Local fields shown until the server row reaches `revision` (null while the write is in flight). */
140
+ export interface CommentPatch {
141
+ fields: Partial<CommentRecord>;
142
+ revision: number | null;
143
+ }
144
+ export declare function applyCommentPatches(comments: readonly CommentRecord[], patches: Readonly<Record<string, CommentPatch>>): CommentRecord[];
145
+ /** The two answers of a check ask, stored in English and shown in the reader's language. */
146
+ export declare const COMMENT_CHECK_ANSWERS: readonly ['Looks good', 'Undo'];
147
+ /** Text files an input ask accepts as an attachment. */
148
+ export declare const COMMENT_TEXT_FILE: RegExp;
149
+ /** An answer to an input ask is kept to 500 characters. */
150
+ export declare function clipCommentAnswer(body: string): string;
151
+ export declare function newCommentId(): string;
152
+ /** "2 min ago", "il y a 3 h": short relative time in the reader's language. */
153
+ export declare function commentRelativeTime(iso: string | null, locale: string, now: number): string;
154
+ /** Clipboard API first; the selection copy runs inside `host` (the Space's own element), never on the page body. */
155
+ export declare function writeCommentClipboard(text: string, host: HTMLElement | null): Promise<boolean>;
156
+ /** Bring an element into view inside its nearest scrolling box only; the page around the Space never moves. */
157
+ export declare function scrollCommentIntoView(element: HTMLElement): void;
@@ -0,0 +1,60 @@
1
+ /**
2
+ * The words of the comment pane, in English and French. `{n}` is an anchor number or a count, `{who}` an author and
3
+ * `{answer}` an answer. A Space names its own anchors (a slide, a section) by passing `words` to `useComments`.
4
+ */
5
+ import { type Words } from '../../words';
6
+ export declare const COMMENT_WORDS: Readonly<{
7
+ comments: Words;
8
+ thisAnchor: Words;
9
+ all: Words;
10
+ open: Words;
11
+ resolved: Words;
12
+ resolvedFilter: Words;
13
+ status: Words;
14
+ scope: Words;
15
+ copy: Words;
16
+ copiedOne: Words;
17
+ copiedMany: Words;
18
+ copyFailed: Words;
19
+ anchorLabel: Words;
20
+ reply: Words;
21
+ replyToReopen: Words;
22
+ newComment: Words;
23
+ newCommentOn: Words;
24
+ newCommentWhole: Words;
25
+ commentOnAnchor: Words;
26
+ pinHint: Words;
27
+ zoneHint: Words;
28
+ commentPlaceholder: Words;
29
+ send: Words;
30
+ cancel: Words;
31
+ resolve: Words;
32
+ reopen: Words;
33
+ delete: Words;
34
+ deleteTitle: Words;
35
+ deleteBody: Words;
36
+ needs: Words;
37
+ needCheck: Words;
38
+ needChoice: Words;
39
+ needInput: Words;
40
+ looksGood: Words;
41
+ undo: Words;
42
+ attach: Words;
43
+ paste: Words;
44
+ sent: Words;
45
+ example: Words;
46
+ emptyAnchor: Words;
47
+ emptyAll: Words;
48
+ emptyResolved: Words;
49
+ saveError: Words;
50
+ textOnly: Words;
51
+ newActivity: Words;
52
+ pin: Words;
53
+ zone: Words;
54
+ }>;
55
+ export type CommentWordKey = keyof typeof COMMENT_WORDS;
56
+ export type CommentWords = Readonly<Record<CommentWordKey, Words>>;
57
+ /** The pane's words with a Space's own wording on top (for example "This slide" for `thisAnchor`). */
58
+ export declare function commentWords(overrides?: Partial<Record<CommentWordKey, Words>>): CommentWords;
59
+ /** "Copied 3 changes". */
60
+ export declare function commentCopiedWords(words: CommentWords, n: number): Words;
@@ -0,0 +1,4 @@
1
+ export * from './commentModel';
2
+ export * from './commentWords';
3
+ export * from './useComments';
4
+ export * from './CommentPane';
@@ -0,0 +1,146 @@
1
+ /**
2
+ * The comment controller: reads a Comments database through the view's declared list, follows its live feed, writes
3
+ * through the normal native mutations and keeps every change on screen at once (optimistic patches and drafts) until
4
+ * the server rows carry it. `CommentPane`, `CommentPins` and `CommentThreadCard` render from it.
5
+ */
6
+ import { type MouseEvent as ReactMouseEvent, type PointerEvent as ReactPointerEvent } from 'react';
7
+ import { type Locale, type Words } from '../../words';
8
+ import { type ToastController } from '../actions/useToast';
9
+ import { type CommentAnchor, type CommentColumns, type CommentDigestOptions, type CommentRecord, type CommentScope, type CommentThread } from './commentModel';
10
+ import { type CommentWordKey, type CommentWords } from './commentWords';
11
+ /** Which threads the pane lists: the current anchor's, or every thread in the scope. */
12
+ export type CommentAnchorFilter = 'anchor' | 'all';
13
+ /** Open threads, or resolved ones. */
14
+ export type CommentStatusFilter = 'open' | 'resolved';
15
+ /**
16
+ * A new comment being written: on an anchor, with a pin (x and y, 0 to 1), a zone (w and h too, 0 to 1 of the
17
+ * anchor's size) or neither (on the whole anchor).
18
+ */
19
+ export interface CommentDraftPin {
20
+ anchorKey: string | null;
21
+ x: number | null;
22
+ y: number | null;
23
+ w: number | null;
24
+ h: number | null;
25
+ }
26
+ /** The zone being dragged on an anchor, 0 to 1 of its size. */
27
+ export interface CommentDragZone {
28
+ anchorKey: string | null;
29
+ x: number;
30
+ y: number;
31
+ w: number;
32
+ h: number;
33
+ }
34
+ /** Pointer handlers for the element the anchor is drawn in: a click drops a pin, a drag marks a zone. */
35
+ export interface CommentZoneHandlers {
36
+ onPointerDown(event: ReactPointerEvent<HTMLElement>): void;
37
+ onPointerMove(event: ReactPointerEvent<HTMLElement>): void;
38
+ onPointerUp(event: ReactPointerEvent<HTMLElement>): void;
39
+ onPointerCancel(event: ReactPointerEvent<HTMLElement>): void;
40
+ }
41
+ export interface CommentActions {
42
+ /** Adds a reply. A reply reopens a resolved thread and answers an open input ask. True once saved. */
43
+ reply(thread: CommentThread, body: string): Promise<boolean>;
44
+ /** Answers a check or choice ask. */
45
+ answer(root: CommentRecord, answer: string): void;
46
+ setStatus(root: CommentRecord, status: 'Open' | 'Resolved'): void;
47
+ /** Opens the delete confirmation for the thread. */
48
+ askDelete(root: CommentRecord): void;
49
+ notify(words: Words | string): void;
50
+ }
51
+ export interface UseCommentsOptions {
52
+ /** The list the view declares in `shows` for the Comments database. Default 'comments'. */
53
+ list?: string;
54
+ /** The database alias the list reads and writes (insert and update actions). Default 'comments'. */
55
+ database?: string;
56
+ /** The record the comments belong to. Null: every comment is shown and none is written with a scope. */
57
+ scope?: CommentScope | null;
58
+ /** The records threads sit on, in order. Empty: comments are not anchored. */
59
+ anchors?: readonly CommentAnchor[];
60
+ /** The anchor on screen (its record key): the pane's "this item" filter and where pins are placed. */
61
+ anchorKey?: string | null;
62
+ /** The person using the Space; their comments count as changes and never as new activity. Default 'Flo'. */
63
+ me?: string;
64
+ /** Authors the Author select knows; anyone else reads as `fallbackAuthor`. Default: any name. */
65
+ authors?: readonly string[];
66
+ fallbackAuthor?: string;
67
+ columns?: Partial<CommentColumns>;
68
+ /** Wording of the digest Copy changes puts on the clipboard. */
69
+ digest?: CommentDigestOptions;
70
+ /** Saves the checkpoint after a copy (for example the scope's "Last turn at"). A throw rolls the checkpoint back. */
71
+ onCheckpoint?(at: string): Promise<void>;
72
+ /** The Space's own wording on top of the defaults. */
73
+ words?: Partial<Record<CommentWordKey, Words>>;
74
+ pageSize?: number;
75
+ /** Follow the database's live feed where the host has one. Default true. */
76
+ live?: boolean;
77
+ /** Called when a thread is picked (a pin, a card): the Space can move to its anchor and open its panel. */
78
+ onSelectThread?(thread: CommentThread): void;
79
+ }
80
+ export interface CommentController {
81
+ comments: CommentRecord[];
82
+ /** Threads in the scope, deleted ones left out, in anchor order. */
83
+ threads: CommentThread[];
84
+ /** The threads the pane lists for the current filters. */
85
+ visibleThreads: CommentThread[];
86
+ /** Changes since the checkpoint: what Copy changes puts on the clipboard. */
87
+ changes: CommentRecord[];
88
+ checkpoint: string | null;
89
+ isNew(comment: CommentRecord): boolean;
90
+ threadsOn(anchorKey: string | null | undefined): CommentThread[];
91
+ /** The thread's pin number on its anchor (1-based), 0 when it is not there. */
92
+ numberOf(thread: CommentThread): number;
93
+ scope: CommentScope | null;
94
+ anchors: readonly CommentAnchor[];
95
+ anchorKey: string | null;
96
+ anchor: CommentAnchor | undefined;
97
+ filter: CommentAnchorFilter;
98
+ setFilter(filter: CommentAnchorFilter): void;
99
+ statusFilter: CommentStatusFilter;
100
+ setStatusFilter(filter: CommentStatusFilter): void;
101
+ threadKey: string | null;
102
+ setThreadKey(key: string | null): void;
103
+ selectThread(thread: CommentThread): void;
104
+ actions: CommentActions;
105
+ /** Add comment mode: the next click on the anchor drops a pin. Escape leaves it. */
106
+ commenting: boolean;
107
+ setCommenting(on: boolean): void;
108
+ toggleCommenting(): void;
109
+ draftPin: CommentDraftPin | null;
110
+ /**
111
+ * Starts a new comment on `anchorKey` at x, y (0 to 1), on a zone when w and h are given too, or on the whole
112
+ * anchor when x and y are null.
113
+ */
114
+ placePin(anchorKey: string | null, x: number | null, y: number | null, w?: number | null, h?: number | null): void;
115
+ /** In Add comment mode, drops a pin where the anchor element was clicked. True when a pin was placed. */
116
+ placePinFromEvent(event: ReactMouseEvent<HTMLElement>, anchorKey: string | null): boolean;
117
+ /** True when the table has zone columns: a drag in Add comment mode marks a zone instead of dropping a pin. */
118
+ zones: boolean;
119
+ /** The zone being dragged, while the button is held. */
120
+ dragZone: CommentDragZone | null;
121
+ /** In Add comment mode: a click on the element drops a pin, a press and drag marks a zone. */
122
+ zoneHandlers(anchorKey: string | null): CommentZoneHandlers;
123
+ cancelPin(): void;
124
+ /** Saves the new comment. True once saved. */
125
+ sendNew(body: string): Promise<boolean>;
126
+ deleting: CommentRecord | null;
127
+ cancelDelete(): void;
128
+ confirmDelete(): Promise<void>;
129
+ /** Copies the digest and records the checkpoint. `host` is the Space's own element, for the selection fallback. */
130
+ copyChanges(host: HTMLElement | null): Promise<boolean>;
131
+ copying: boolean;
132
+ /** Record keys with a write in flight. */
133
+ busy: ReadonlySet<string>;
134
+ now: number;
135
+ toaster: ToastController;
136
+ words: CommentWords;
137
+ /** A word in the reader's language, with `{n}`-style values filled. */
138
+ say(key: CommentWordKey, vars?: Readonly<Record<string, string | number>>): string;
139
+ locale: Locale;
140
+ me: string;
141
+ loading: boolean;
142
+ hasData: boolean;
143
+ error: Error | null;
144
+ refetch(): Promise<unknown>;
145
+ }
146
+ export declare function useComments(options?: UseCommentsOptions): CommentController;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * The one translated `?` sheet (toolkit spec 2.1), built from the live registry: only shortcuts that answer here
3
+ * and now are listed, "This Space" first, then "Notis". Rendered once by the host.
4
+ */
5
+ export interface HelpSheetProps {
6
+ /**
7
+ * Where the sheet mounts. Default: the pinned overlay layer root (LayerRootProvider), else the top-level
8
+ * container of the page the engine listens on. The sheet is rendered once by the host, never by a Space.
9
+ */
10
+ container?: Element | DocumentFragment | null;
11
+ }
12
+ export declare function HelpSheet({ container }: HelpSheetProps): import("react").ReactPortal | null;
@@ -0,0 +1,27 @@
1
+ import { type ReactNode } from 'react';
2
+ import type { Locale, Platform } from '../../words';
3
+ import type { KeyboardEngineCore } from './core';
4
+ import { type ShortcutScopeOptions } from './hooks';
5
+ import type { EngineHost } from './types';
6
+ export interface KeyboardEngineProps {
7
+ host: EngineHost;
8
+ locale: Locale;
9
+ platform?: Platform;
10
+ /** Clashes throw (dev, design check). Default: true unless NODE_ENV is 'production'. */
11
+ strict?: boolean;
12
+ /** Production clash log (telemetry). */
13
+ onClash?: (message: string) => void;
14
+ /** An own core (tests). Default: the page's shared core. */
15
+ engine?: KeyboardEngineCore;
16
+ /** The document to listen on. Default: the global document. */
17
+ document?: Document;
18
+ children?: ReactNode;
19
+ }
20
+ /** The one keyboard listener of a page, at the Portal root (or the preview root). */
21
+ export declare function KeyboardEngine(props: KeyboardEngineProps): import("react").JSX.Element;
22
+ export interface ShortcutScopeProps extends ShortcutScopeOptions {
23
+ owner: string;
24
+ children?: ReactNode;
25
+ }
26
+ /** Owner of every shortcut below it: a Space, or a retained view that goes silent while hidden. */
27
+ export declare function ShortcutScope({ owner, available, kind, children }: ShortcutScopeProps): import("react").JSX.Element;
@@ -0,0 +1,73 @@
1
+ /**
2
+ * The one keyboard listener (toolkit spec 2.1). Document capture phase; React handlers no longer own keys.
3
+ * No React here: the React pieces (`KeyboardEngine`, hooks) drive one shared core.
4
+ */
5
+ import { type Locale, type Platform } from '../../words';
6
+ import { ShortcutRegistry } from './registry';
7
+ import type { EngineSettings, ShortcutDef } from './types';
8
+ /** Escape chain order, highest first: menus and dialogs, help sheet, selection clear, detail panel, route back. */
9
+ export declare const ESCAPE_PRIORITY: Readonly<{
10
+ route: 0;
11
+ detail: 100;
12
+ selection: 200;
13
+ help: 300;
14
+ overlay: 400;
15
+ }>;
16
+ export declare const SEQUENCE_TIMEOUT_MS = 1500;
17
+ export declare function detectPlatform(): Platform;
18
+ export declare function detectLocale(): Locale;
19
+ export declare class KeyboardEngineCore {
20
+ readonly registry: ShortcutRegistry;
21
+ settings: EngineSettings;
22
+ /** Mounted `<KeyboardEngine>` count. With none, settings hooks fall back to the document (lang). */
23
+ mounted: number;
24
+ /** Clock, replaceable in tests. */
25
+ now: () => number;
26
+ private layers;
27
+ private blockers;
28
+ private seq;
29
+ private held;
30
+ private pending;
31
+ private attached;
32
+ private helpOpen;
33
+ private helpUnregister;
34
+ private forcedRepeat;
35
+ constructor(settings?: Partial<EngineSettings>);
36
+ /** Updates settings. Returns true when one changed; listeners hear it unless `silent` (during a React render). */
37
+ configure(settings: Partial<EngineSettings>, options?: {
38
+ silent?: boolean;
39
+ }): boolean;
40
+ subscribe(listener: () => void): () => void;
41
+ getVersion(): number;
42
+ /** Starts listening on a document. Ref counted; the last detach removes the listeners. */
43
+ attach(doc: Document): () => void;
44
+ isAttached(doc: Document): boolean;
45
+ /** The first document the engine listens on (the host page), or null before KeyboardEngine mounts. */
46
+ attachedDocument(): Document | null;
47
+ private resetHeld;
48
+ register(def: ShortcutDef, owner?: string): (() => void) | null;
49
+ defineOwner: ShortcutRegistry['defineOwner'];
50
+ setOwnerAvailable(id: string, available: boolean): void;
51
+ isOwnerAvailable(id: string): boolean;
52
+ addEscapeLayer(id: string, onEscape: (event?: KeyboardEvent) => boolean, priority?: number): () => void;
53
+ addEscapeBlocker(priority?: number, isActive?: () => boolean): () => void;
54
+ escapeLayerIds(): string[];
55
+ private sortedLayers;
56
+ /**
57
+ * Runs the chain. True when a layer handled it. Called without an event by a Close button that means "Escape";
58
+ * from a key press each layer gets the keydown.
59
+ */
60
+ runEscapeChain(event?: KeyboardEvent): boolean;
61
+ isHelpOpen(): boolean;
62
+ openHelp(): void;
63
+ closeHelp(): void;
64
+ toggleHelp(): void;
65
+ private ensureHelpShortcut;
66
+ /** True for a key repeat, including a press of a key that is still held (some hosts drop `event.repeat`). */
67
+ isRepeat(event: KeyboardEvent): boolean;
68
+ handleKeyUp(event: KeyboardEvent): void;
69
+ handleKeyDown(event: KeyboardEvent): void;
70
+ private run;
71
+ /** True when Escape is fully handled here (nothing else should see it as a shortcut). */
72
+ private handleEscape;
73
+ }
@@ -0,0 +1,64 @@
1
+ /**
2
+ * React hooks of the keyboard engine (toolkit spec 2.1). Every hook works without a mounted `<KeyboardEngine>`
3
+ * (unit tests, a bare preview): registrations land in the shared core, which listens only once an engine mounts or
4
+ * `core.attach(document)` is called, and settings fall back to the document language and the browser platform.
5
+ */
6
+ import { type Locale, type Platform } from '../../words';
7
+ import { type KeyboardEngineCore } from './core';
8
+ import type { EngineSettings, OwnerKind, ScopeHandle, ShortcutDef } from './types';
9
+ /** The engine core in effect here: an injected one, else the shared one. */
10
+ export declare function useEngineCore(): KeyboardEngineCore;
11
+ /** The owner shortcuts register under: the nearest `<ShortcutScope>`, else 'notis'. */
12
+ export declare function useShortcutOwner(): string;
13
+ /** Toolkit language. Without a mounted engine: the document's `lang` ('fr...' gives 'fr', else 'en'). */
14
+ export declare function useToolkitLocale(): Locale;
15
+ /** 'mac' or 'other'. Without a mounted engine: detected from the browser. */
16
+ export declare function useToolkitPlatform(): Platform;
17
+ /** Host, locale, platform and strict mode. */
18
+ export declare function useToolkitSettings(): Readonly<EngineSettings>;
19
+ /**
20
+ * Registers one shortcut while mounted. Re-registers only when its id, keys, scope, owner, words or flags change
21
+ * (or `deps` change); `run` and `when` are read live.
22
+ */
23
+ export declare function useShortcut(def: ShortcutDef, deps?: readonly unknown[]): void;
24
+ /** Registers several shortcuts while mounted (same rules as `useShortcut`). */
25
+ export declare function useShortcuts(defs: readonly ShortcutDef[], deps?: readonly unknown[]): void;
26
+ export interface ShortcutScopeOptions {
27
+ /** False for a hidden retained view or a Space in the background: all its shortcuts go silent. */
28
+ available: boolean;
29
+ /** 'space' (default under the root) for Space code, 'host' for Notis pages. Inherited from the parent owner. */
30
+ kind?: OwnerKind;
31
+ }
32
+ /**
33
+ * Declares a Space or a retained view as an owner, nested under the current owner. Its shortcuts are those
34
+ * registered under a `<ShortcutScope owner>` with the same id (or with `def.owner`).
35
+ */
36
+ export declare function useShortcutScope(owner: string, options: ShortcutScopeOptions): ScopeHandle;
37
+ export interface EscapeLayerOptions {
38
+ /** Chain position (ESCAPE_PRIORITY). Default overlay. */
39
+ priority?: number;
40
+ /** False keeps the hook mounted without a layer. Default true. */
41
+ enabled?: boolean;
42
+ }
43
+ /**
44
+ * Adds a step to the Escape chain while mounted. `onEscape` returns true when it handled the key (the chain
45
+ * stops), false to let the next step run. Higher priority runs first; the latest wins within a priority. It gets the
46
+ * keydown when a key press runs the chain (none from `runEscapeChain()` without an event).
47
+ */
48
+ export declare function useEscapeLayer(id: string, onEscape: (event?: KeyboardEvent) => boolean, options?: EscapeLayerOptions): void;
49
+ /**
50
+ * Stops the Escape chain below `priority` while `active` (the composer holds text). Default priority sits between
51
+ * the detail panel and selection clear, so Escape still clears a selection but never leaves the page.
52
+ */
53
+ export declare function useEscapeBlocker(active: boolean, options?: {
54
+ priority?: number;
55
+ }): void;
56
+ export interface HelpSheetControls {
57
+ open(): void;
58
+ close(): void;
59
+ toggle(): void;
60
+ isOpen: boolean;
61
+ }
62
+ export declare function useHelpSheet(): HelpSheetControls;
63
+ /** Re-renders on every registry change (the help sheet, dev overlays). */
64
+ export declare function useRegistryVersion(): number;
@@ -0,0 +1,14 @@
1
+ export { ESCAPE_PRIORITY, SEQUENCE_TIMEOUT_MS, KeyboardEngineCore, detectLocale, detectPlatform } from './core';
2
+ export { NotisKeyClash, ROOT_OWNER, ShortcutRegistry } from './registry';
3
+ export type { DefineOwnerOptions, RegisteredShortcut, RegistryOptions } from './registry';
4
+ export { getSharedInstance } from './instance';
5
+ export type { SharedInstance } from './instance';
6
+ export { useEngineCore, useEscapeBlocker, useEscapeLayer, useHelpSheet, useRegistryVersion, useShortcut, useShortcutOwner, useShortcutScope, useShortcuts, useToolkitLocale, useToolkitPlatform, useToolkitSettings, } from './hooks';
7
+ export type { EscapeLayerOptions, HelpSheetControls, ShortcutScopeOptions } from './hooks';
8
+ export { KeyboardEngine, ShortcutScope } from './KeyboardEngine';
9
+ export type { KeyboardEngineProps, ShortcutScopeProps } from './KeyboardEngine';
10
+ export { HelpSheet } from './HelpSheet';
11
+ export type { HelpSheetProps } from './HelpSheet';
12
+ export { stepCursor } from './step';
13
+ export type { StepOptions } from './step';
14
+ export type { EngineHost, EngineSettings, HelpEntry, OwnerKind, ScopeHandle, ShortcutDef, ShortcutGroup, } from './types';
@@ -0,0 +1,21 @@
1
+ /**
2
+ * One engine per page, even when two copies of the toolkit load (a Space bundle that inlined `@notis/sdk/ui` by
3
+ * mistake). The first copy stores its core and React contexts on `globalThis` under a registered symbol; a second
4
+ * copy logs once and reuses them, so its shortcuts land in the same registry and its hooks read the same contexts.
5
+ */
6
+ import { type Context } from 'react';
7
+ import { KeyboardEngineCore } from './core';
8
+ import type { KeycapOn } from './keycapContext';
9
+ export interface SharedInstance {
10
+ readonly version: 1;
11
+ readonly core: KeyboardEngineCore;
12
+ /** An injected core (tests, preview) overrides the shared one below it. */
13
+ readonly EngineContext: Context<KeyboardEngineCore | null>;
14
+ /** The nearest `<ShortcutScope>` owner. */
15
+ readonly OwnerContext: Context<string>;
16
+ /** Keycap `on` default for a subtree (SelectionBar: pill, Menu and HelpSheet: discreet). */
17
+ readonly KeycapContext: Context<KeycapOn | null>;
18
+ }
19
+ export declare function getSharedInstance(): SharedInstance;
20
+ /** Tests only: forget this module's cached instance (the global slot stays). */
21
+ export declare function __resetSharedInstanceForTests(): void;
@@ -0,0 +1,2 @@
1
+ /** Keycap surfaces (toolkit spec 2.2). */
2
+ export type KeycapOn = 'surface' | 'chrome' | 'pill' | 'discreet' | 'tooltip';