@notis_ai/cli 0.2.0-beta.19.1 → 0.2.0-beta.196.1

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 (216) hide show
  1. package/README.md +822 -135
  2. package/bin/check-runtime.js +15 -0
  3. package/bin/notis.js +2 -0
  4. package/config/notis_app_boundary_rules.json +50 -0
  5. package/config/notis_app_design_rules.json +135 -0
  6. package/config/portal-route-roots.json +48 -0
  7. package/dist/agent-hooks/notis-agent-hook.mjs +45587 -0
  8. package/dist/base-skills/notis-apps/SKILL.md +93 -0
  9. package/dist/base-skills/notis-apps/references/architecture.md +114 -0
  10. package/dist/base-skills/notis-apps/references/context.md +81 -0
  11. package/dist/base-skills/notis-apps/references/design.md +97 -0
  12. package/dist/base-skills/notis-apps/references/memory.md +58 -0
  13. package/dist/base-skills/notis-apps/references/reading.md +67 -0
  14. package/dist/base-skills/notis-apps/references/release.md +107 -0
  15. package/dist/base-skills/notis-apps/references/sdk.md +116 -0
  16. package/dist/base-skills/notis-apps/references/troubleshooting.md +24 -0
  17. package/dist/base-skills/notis-apps/references/views.md +142 -0
  18. package/dist/base-skills/notis-cli/SKILL.md +154 -0
  19. package/dist/base-skills/notis-cli/references/app-delivery.md +19 -0
  20. package/dist/base-skills/notis-cli/references/intelligence.md +94 -0
  21. package/dist/base-skills/notis-cli/references/native-databases.md +21 -0
  22. package/dist/base-skills/notis-cli/references/tool-examples.md +56 -0
  23. package/dist/base-skills/notis-cli/references/troubleshooting.md +39 -0
  24. package/dist/base-skills/notis-query/SKILL.md +41 -0
  25. package/dist/base-skills/notis-query/references/database-discovery.md +60 -0
  26. package/dist/base-skills/notis-query/references/documents.md +63 -0
  27. package/dist/base-skills/notis-query/references/query.md +76 -0
  28. package/{template/packages/notis-sdk → dist/sdk}/package.json +14 -4
  29. package/dist/sdk/src/agentContext.ts +36 -0
  30. package/dist/sdk/src/bundleModule.ts +79 -0
  31. package/dist/sdk/src/components/Dialog.tsx +46 -0
  32. package/dist/sdk/src/components/DocumentEditor.tsx +106 -0
  33. package/dist/sdk/src/components/DocumentPage.tsx +141 -0
  34. package/dist/sdk/src/components/Markdown.tsx +60 -0
  35. package/dist/sdk/src/components/MarkdownEditor.tsx +121 -0
  36. package/dist/sdk/src/components/MultiSelectActionBar.tsx +285 -0
  37. package/dist/sdk/src/components/MultiSelectCheckbox.tsx +97 -0
  38. package/dist/sdk/src/components/MultiSelectDragOverlay.tsx +39 -0
  39. package/dist/sdk/src/components/NotisCommentBoundary.tsx +172 -0
  40. package/dist/sdk/src/components/NotisSelectionBoundary.tsx +59 -0
  41. package/dist/sdk/src/components/RecordComponents.tsx +33 -0
  42. package/dist/sdk/src/components/RenderChartData.tsx +19 -0
  43. package/dist/sdk/src/components/ShortcutHints.tsx +56 -0
  44. package/dist/sdk/src/components/Skeleton.tsx +24 -0
  45. package/dist/sdk/src/config.ts +239 -0
  46. package/dist/sdk/src/documents.ts +258 -0
  47. package/dist/sdk/src/hooks/useAction.ts +28 -0
  48. package/dist/sdk/src/hooks/useActiveResource.ts +19 -0
  49. package/dist/sdk/src/hooks/useAgentContext.ts +23 -0
  50. package/dist/sdk/src/hooks/useCloudComputer.ts +95 -0
  51. package/dist/sdk/src/hooks/useCloudComputerShell.ts +114 -0
  52. package/dist/sdk/src/hooks/useCollectionInteractions.ts +838 -0
  53. package/dist/sdk/src/hooks/useDatabaseSchema.ts +49 -0
  54. package/dist/sdk/src/hooks/useDatabaseSubscription.ts +76 -0
  55. package/dist/sdk/src/hooks/useDocument.ts +43 -0
  56. package/dist/sdk/src/hooks/useDocuments.ts +84 -0
  57. package/dist/sdk/src/hooks/useHandover.ts +78 -0
  58. package/dist/sdk/src/hooks/useLongPressSelection.ts +79 -0
  59. package/dist/sdk/src/hooks/useMultiSelect.ts +95 -0
  60. package/dist/sdk/src/hooks/useNativeDocumentBody.ts +50 -0
  61. package/dist/sdk/src/hooks/useNativeDocuments.ts +83 -0
  62. package/dist/sdk/src/hooks/useNotis.ts +42 -0
  63. package/dist/sdk/src/hooks/useNotisNavigation.ts +67 -0
  64. package/dist/sdk/src/hooks/useQuery.ts +74 -0
  65. package/dist/sdk/src/hooks/useTool.ts +65 -0
  66. package/dist/sdk/src/hooks/useToolQuery.ts +12 -0
  67. package/dist/sdk/src/hooks/useTopBarSearch.ts +81 -0
  68. package/dist/sdk/src/hooks/useUpsertDocument.ts +95 -0
  69. package/dist/sdk/src/hooks/useViewParams.ts +121 -0
  70. package/dist/sdk/src/hooks/useViewerReads.ts +129 -0
  71. package/dist/sdk/src/index.ts +200 -0
  72. package/dist/sdk/src/interactions/actions.ts +59 -0
  73. package/dist/sdk/src/interactions/shortcuts.tsx +740 -0
  74. package/dist/sdk/src/interactions/visibility.ts +13 -0
  75. package/dist/sdk/src/interactions.ts +45 -0
  76. package/dist/sdk/src/nativeData.ts +39 -0
  77. package/dist/sdk/src/presentation.tsx +82 -0
  78. package/dist/sdk/src/provider.tsx +49 -0
  79. package/dist/sdk/src/queryCache.ts +172 -0
  80. package/dist/sdk/src/queryErrors.ts +51 -0
  81. package/dist/sdk/src/runtime.ts +603 -0
  82. package/dist/sdk/src/space.ts +425 -0
  83. package/dist/sdk/src/styles.css +290 -0
  84. package/dist/sdk/src/tailwind.ts +66 -0
  85. package/dist/sdk/src/vite.ts +83 -0
  86. package/dist/skill-sync/index.js +2143 -0
  87. package/dist/skill-sync/index.js.map +7 -0
  88. package/dist/skill-sync-worker.mjs +3487 -0
  89. package/dist/space-harness/host.js +66 -0
  90. package/dist/view-renderer/dist/host.css +1 -0
  91. package/dist/view-renderer/dist/host.js +1042 -0
  92. package/dist/view-renderer/dist/theme.css +73 -0
  93. package/dist/view-renderer/src/dom.js +180 -0
  94. package/dist/view-renderer/src/errors.js +8 -0
  95. package/dist/view-renderer/src/host.tsx +173 -0
  96. package/dist/view-renderer/src/index.js +4 -0
  97. package/dist/view-renderer/src/pool.js +76 -0
  98. package/dist/view-renderer/src/remote-broker.js +59 -0
  99. package/dist/view-renderer/src/renderer.js +201 -0
  100. package/package.json +25 -8
  101. package/skills/notis-apps/cli.md +406 -0
  102. package/skills/notis-cli/AGENT_INSTRUCTIONS.md +39 -0
  103. package/skills/notis-onboarding/BRIEF.md +133 -0
  104. package/skills/notis-query/cli.md +39 -0
  105. package/src/agent-hook-entry.js +5 -0
  106. package/src/cli.js +294 -25
  107. package/src/command-specs/agents.js +392 -0
  108. package/src/command-specs/apps.js +1476 -203
  109. package/src/command-specs/auth.js +114 -137
  110. package/src/command-specs/diagnostics.js +730 -0
  111. package/src/command-specs/files.js +29 -0
  112. package/src/command-specs/handover.js +374 -0
  113. package/src/command-specs/helpers.js +86 -82
  114. package/src/command-specs/index.js +31 -6
  115. package/src/command-specs/meta.js +150 -18
  116. package/src/command-specs/onboarding.js +290 -0
  117. package/src/command-specs/profile.js +358 -0
  118. package/src/command-specs/skills.js +304 -0
  119. package/src/command-specs/smoke.js +386 -0
  120. package/src/command-specs/spaces.js +572 -0
  121. package/src/command-specs/tools.js +455 -139
  122. package/src/command-specs/views.js +69 -0
  123. package/src/runtime/agent-browser.js +700 -0
  124. package/src/runtime/agent-memory-state.js +126 -0
  125. package/src/runtime/agent-setup.js +383 -0
  126. package/src/runtime/app-boundary-validator.js +407 -0
  127. package/src/runtime/app-changelog.js +79 -0
  128. package/src/runtime/app-data-literals.js +82 -0
  129. package/src/runtime/app-platform.js +2752 -237
  130. package/src/runtime/app-registry-scaffolds.js +367 -0
  131. package/src/runtime/app-test-server.js +293 -0
  132. package/src/runtime/assets/store-screenshot-dark.png +0 -0
  133. package/src/runtime/auth-recovery.js +110 -0
  134. package/src/runtime/base-skills.d.ts +20 -0
  135. package/src/runtime/base-skills.js +167 -0
  136. package/src/runtime/channel.js +133 -0
  137. package/src/runtime/confined-space-build.js +74 -0
  138. package/src/runtime/confined-space-verify.js +49 -0
  139. package/src/runtime/delegated-context.js +68 -0
  140. package/src/runtime/errors.js +1 -0
  141. package/src/runtime/git.js +233 -0
  142. package/src/runtime/login-listener.js +15 -0
  143. package/src/runtime/native-record-files.js +47 -0
  144. package/src/runtime/oauth.js +2622 -0
  145. package/src/runtime/output.js +37 -5
  146. package/src/runtime/ports.js +31 -0
  147. package/src/runtime/profiles.js +906 -55
  148. package/src/runtime/retired-sdk-files.js +20 -0
  149. package/src/runtime/screenshot-framing.js +85 -0
  150. package/src/runtime/skill-sync/cloud-client.ts +121 -0
  151. package/src/runtime/skill-sync/index.ts +905 -0
  152. package/src/runtime/skill-sync/local-scanner.ts +1259 -0
  153. package/src/runtime/skill-sync/native-identity.ts +102 -0
  154. package/src/runtime/skill-sync/native-plan.ts +59 -0
  155. package/src/runtime/skill-sync/symlink-manager.ts +433 -0
  156. package/src/runtime/skill-sync/sync-plan.ts +54 -0
  157. package/src/runtime/skill-sync/types.ts +157 -0
  158. package/src/runtime/skill-sync/write-cloud-skill.ts +50 -0
  159. package/src/runtime/skill-sync-service.js +109 -0
  160. package/src/runtime/source-root.js +32 -0
  161. package/src/runtime/space-collection-scaffold.js +66 -0
  162. package/src/runtime/space-database-structures.js +229 -0
  163. package/src/runtime/space-fixture-broker.js +50 -0
  164. package/src/runtime/space-lock.js +337 -0
  165. package/src/runtime/space-platform.js +105 -0
  166. package/src/runtime/space-source.js +281 -0
  167. package/src/runtime/space-test-server.js +327 -0
  168. package/src/runtime/space-verification.js +89 -0
  169. package/src/runtime/space-verify-browser-worker.js +51 -0
  170. package/src/runtime/space-view-manifest.js +254 -0
  171. package/src/runtime/store-screenshot.js +146 -0
  172. package/src/runtime/sync-skills.d.ts +37 -0
  173. package/src/runtime/sync-skills.js +231 -0
  174. package/src/runtime/telemetry.js +92 -0
  175. package/src/runtime/transport.js +331 -45
  176. package/src/runtime/view-render.js +49 -0
  177. package/src/skill-sync-worker-entry.js +2 -0
  178. package/src/skill-sync-worker.js +50 -0
  179. package/src/space-harness-host.ts +103 -0
  180. package/template/.harness/index.html.tmpl +435 -0
  181. package/template/CHANGELOG.md +5 -0
  182. package/template/app/globals.css +29 -3
  183. package/template/app/layout.tsx +6 -3
  184. package/template/app/page.tsx +49 -42
  185. package/template/components/page-heading.tsx +23 -0
  186. package/template/components/ui/badge.tsx +7 -4
  187. package/template/components/ui/button.tsx +1 -1
  188. package/template/components/ui/card.tsx +24 -11
  189. package/template/components/ui/native-select.tsx +24 -0
  190. package/template/notis.config.ts +24 -6
  191. package/template/package-lock.json +3642 -0
  192. package/template/package.json +19 -16
  193. package/template/postcss.config.mjs +1 -1
  194. package/template/tailwind.config.ts +1 -6
  195. package/template/tsconfig.json +1 -0
  196. package/src/command-specs/db.js +0 -163
  197. package/src/runtime/app-preview-server.js +0 -312
  198. package/template/packages/notis-sdk/src/config.ts +0 -48
  199. package/template/packages/notis-sdk/src/helpers.ts +0 -131
  200. package/template/packages/notis-sdk/src/hooks/useAppState.ts +0 -50
  201. package/template/packages/notis-sdk/src/hooks/useCollectionItem.ts +0 -58
  202. package/template/packages/notis-sdk/src/hooks/useDatabase.ts +0 -87
  203. package/template/packages/notis-sdk/src/hooks/useDocument.ts +0 -61
  204. package/template/packages/notis-sdk/src/hooks/useNotis.ts +0 -31
  205. package/template/packages/notis-sdk/src/hooks/useNotisNavigation.ts +0 -49
  206. package/template/packages/notis-sdk/src/hooks/useTool.ts +0 -49
  207. package/template/packages/notis-sdk/src/hooks/useUpsertDocument.ts +0 -57
  208. package/template/packages/notis-sdk/src/index.ts +0 -47
  209. package/template/packages/notis-sdk/src/provider.tsx +0 -44
  210. package/template/packages/notis-sdk/src/runtime.ts +0 -159
  211. package/template/packages/notis-sdk/src/styles.css +0 -123
  212. package/template/packages/notis-sdk/src/vite.ts +0 -54
  213. package/template/packages/notis-sdk/tsconfig.json +0 -15
  214. /package/{template/packages/notis-sdk → dist/sdk}/src/hooks/useBackend.ts +0 -0
  215. /package/{template/packages/notis-sdk → dist/sdk}/src/hooks/useTools.ts +0 -0
  216. /package/{template/packages/notis-sdk → dist/sdk}/src/ui.ts +0 -0
@@ -0,0 +1,290 @@
1
+ /**
2
+ * Notis theme CSS variables.
3
+ *
4
+ * Import this in your app layout:
5
+ *
6
+ * import '@notis/sdk/styles.css';
7
+ *
8
+ * The portal injects the live Notis theme variables at render time.
9
+ */
10
+
11
+ /* Top-layer surfaces must remain distinct from the app's flat content panels. */
12
+ dialog.notis-dialog {
13
+ position: fixed;
14
+ inset: 0;
15
+ margin: auto;
16
+ box-sizing: border-box;
17
+ width: min(28rem, calc(100% - 2rem));
18
+ max-height: calc(100dvh - 2rem);
19
+ overflow: auto;
20
+ padding: 1.25rem;
21
+ border: 1px solid hsl(var(--border));
22
+ border-radius: 0.75rem;
23
+ background: hsl(var(--popover));
24
+ color: hsl(var(--popover-foreground));
25
+ box-shadow: 0 16px 48px rgb(0 0 0 / 0.2);
26
+ }
27
+
28
+ dialog.notis-dialog::backdrop { background: rgb(0 0 0 / 0.45); }
29
+ .notis-dialog-title { margin: 0; font-size: 1rem; font-weight: 600; line-height: 1.5; }
30
+ .notis-dialog-description { margin: 0.5rem 0 0; color: hsl(var(--muted-foreground)); font-size: 0.875rem; line-height: 1.5; }
31
+
32
+ /* Framework-neutral styles: the app owns its Tailwind entry point. This file
33
+ * is also consumed in shadow roots and by apps on older Tailwind versions.
34
+ * The shell rules live in the native sublayer `components.notis-sdk`, so a
35
+ * page's Tailwind utilities (p-4, border-red-500) still win over them.
36
+ * The list-row spacing contract below is the one exception. Never
37
+ * use a bare Tailwind-owned `@layer base` / `@layer components` block: Vite
38
+ * processes this import separately from the app stylesheet, and Tailwind 3
39
+ * rejects those blocks without matching `@tailwind` directives.
40
+ *
41
+ * Tailwind 4: the statement below repeats its full layer order, including the
42
+ * `properties` layer it declares first for its --tw-* fallback reset, so the
43
+ * order holds whichever stylesheet loads first and the shell rules win over
44
+ * preflight and the app's base defaults.
45
+ * Tailwind 3: preflight, components and utilities are unlayered and beat every
46
+ * layered rule, so its preflight (`button` and list resets, `*` border colour)
47
+ * wins over these shell rules; utilities still win too. A Tailwind 3 app that
48
+ * puts a shell class on a `button`, `ul` or `ol` restates the background and
49
+ * padding it needs. */
50
+ @layer properties, theme, base, components, utilities;
51
+
52
+ @layer components.notis-sdk {
53
+ * {
54
+ border-color: hsl(var(--border));
55
+ }
56
+ [data-notis-app-root] {
57
+ color: hsl(var(--foreground));
58
+ display: block;
59
+ min-height: 100%;
60
+ }
61
+
62
+ .notis-app-shell {
63
+ margin-inline: auto;
64
+ width: 100%;
65
+ max-width: var(--portal-page-max-width);
66
+ padding: 1.5rem 1rem;
67
+ }
68
+
69
+ /* Flat panel: no border or shadow around items. */
70
+ .notis-app-surface {
71
+ border-radius: 1rem;
72
+ background-color: hsl(var(--muted));
73
+ color: hsl(var(--card-foreground));
74
+ }
75
+
76
+ .list-row {
77
+ border-radius: 0.75rem;
78
+ background-color: hsl(var(--muted));
79
+ transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
80
+ transition-duration: 150ms;
81
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
82
+ }
83
+
84
+ .list-row-selected {
85
+ background-color: hsl(var(--primary) / 0.06);
86
+ }
87
+
88
+ /* Split pages are full-bleed; only the list pane carries a hairline. */
89
+ .notis-app-split {
90
+ display: flex;
91
+ height: 100%;
92
+ min-height: 0;
93
+ width: 100%;
94
+ max-width: none;
95
+ flex-direction: column;
96
+ }
97
+
98
+ .notis-app-pane-list {
99
+ width: 100%;
100
+ flex-shrink: 0;
101
+ background-color: hsl(var(--muted) / 0.4);
102
+ }
103
+
104
+ .notis-app-pane-detail {
105
+ min-width: 0;
106
+ flex: 1 1 0%;
107
+ background-color: hsl(var(--background));
108
+ }
109
+
110
+ .notis-app-section {
111
+ padding: 1.25rem;
112
+ }
113
+
114
+ @media (min-width: 768px) {
115
+ .notis-app-shell { padding-block: 2rem; }
116
+ .notis-app-section { padding: 1.5rem; }
117
+ }
118
+
119
+ @media (min-width: 1024px) {
120
+ .list-row { background-color: transparent; }
121
+ .list-row:hover { background-color: hsl(var(--muted) / 0.6); }
122
+ .list-row-selected,
123
+ .list-row-selected:hover { background-color: hsl(var(--primary) / 0.06); }
124
+ .notis-app-split { flex-direction: row; }
125
+ .notis-app-pane-list {
126
+ width: 20rem;
127
+ border-right-width: 1px;
128
+ border-right-color: hsl(var(--border));
129
+ }
130
+ }
131
+
132
+ @media (min-width: 1280px) {
133
+ .notis-app-pane-list { width: 24rem; }
134
+ }
135
+ }
136
+
137
+ /* A list row owns its 16px side gutter and 12px vertical rhythm, as in the
138
+ * Portal and pre-Space Apps. Keep only this spacing outside the utility layers:
139
+ * Tailwind 3 utilities are unlayered, so a second class specificity preserves
140
+ * it regardless of stylesheet order. Deliberate inline/important overrides still
141
+ * work. Shell/section/layout utilities and row colours remain overridable above. */
142
+ .list-row.list-row { padding: 0.75rem 1rem; }
143
+
144
+ /*
145
+ * Markdown value-type rendering (see the `Markdown` component). Plain CSS on
146
+ * theme variables so it works inside the portal shadow root and the dev
147
+ * harness without depending on the app's Tailwind content scan.
148
+ */
149
+ .notis-markdown {
150
+ font-size: 14px;
151
+ line-height: 1.65;
152
+ color: hsl(var(--foreground));
153
+ overflow-wrap: break-word;
154
+ }
155
+
156
+ .notis-markdown--sm {
157
+ font-size: 13px;
158
+ line-height: 1.55;
159
+ }
160
+
161
+ .notis-markdown > :first-child {
162
+ margin-top: 0;
163
+ }
164
+
165
+ .notis-markdown > :last-child {
166
+ margin-bottom: 0;
167
+ }
168
+
169
+ .notis-markdown p {
170
+ margin: 0.625em 0;
171
+ }
172
+
173
+ .notis-markdown h1,
174
+ .notis-markdown h2,
175
+ .notis-markdown h3,
176
+ .notis-markdown h4,
177
+ .notis-markdown h5,
178
+ .notis-markdown h6 {
179
+ margin: 1.25em 0 0.5em;
180
+ font-weight: 650;
181
+ letter-spacing: -0.01em;
182
+ line-height: 1.3;
183
+ color: hsl(var(--foreground));
184
+ }
185
+
186
+ .notis-markdown h1 { font-size: 1.5em; }
187
+ .notis-markdown h2 { font-size: 1.25em; }
188
+ .notis-markdown h3 { font-size: 1.1em; }
189
+ .notis-markdown h4,
190
+ .notis-markdown h5,
191
+ .notis-markdown h6 { font-size: 1em; }
192
+
193
+ .notis-markdown ul,
194
+ .notis-markdown ol {
195
+ margin: 0.625em 0;
196
+ padding-left: 1.5em;
197
+ }
198
+
199
+ .notis-markdown ul { list-style-type: disc; }
200
+ .notis-markdown ol { list-style-type: decimal; }
201
+
202
+ .notis-markdown li {
203
+ margin: 0.25em 0;
204
+ }
205
+
206
+ .notis-markdown li > ul,
207
+ .notis-markdown li > ol {
208
+ margin: 0.25em 0;
209
+ }
210
+
211
+ .notis-markdown ul.contains-task-list {
212
+ list-style: none;
213
+ padding-left: 0.375em;
214
+ }
215
+
216
+ .notis-markdown li.task-list-item input[type='checkbox'] {
217
+ margin-right: 0.5em;
218
+ accent-color: hsl(var(--primary));
219
+ }
220
+
221
+ .notis-markdown blockquote {
222
+ margin: 0.75em 0;
223
+ padding: 0.125em 0 0.125em 0.875em;
224
+ border-left: 3px solid hsl(var(--border));
225
+ color: hsl(var(--muted-foreground));
226
+ }
227
+
228
+ .notis-markdown a {
229
+ color: hsl(var(--primary));
230
+ text-decoration: underline;
231
+ text-decoration-color: hsl(var(--primary) / 0.35);
232
+ text-underline-offset: 2px;
233
+ }
234
+
235
+ .notis-markdown a:hover {
236
+ text-decoration-color: hsl(var(--primary));
237
+ }
238
+
239
+ .notis-markdown code {
240
+ font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
241
+ font-size: 0.875em;
242
+ padding: 0.125em 0.375em;
243
+ border-radius: 0.25rem;
244
+ background: hsl(var(--muted));
245
+ color: hsl(var(--foreground));
246
+ }
247
+
248
+ .notis-markdown pre {
249
+ margin: 0.75em 0;
250
+ padding: 0.75em 1em;
251
+ border-radius: 0.5rem;
252
+ background: hsl(var(--muted));
253
+ overflow-x: auto;
254
+ }
255
+
256
+ .notis-markdown pre code {
257
+ padding: 0;
258
+ background: transparent;
259
+ font-size: 0.875em;
260
+ }
261
+
262
+ .notis-markdown hr {
263
+ margin: 1.25em 0;
264
+ border: 0;
265
+ border-top: 1px solid hsl(var(--border));
266
+ }
267
+
268
+ .notis-markdown img {
269
+ max-width: 100%;
270
+ border-radius: 0.5rem;
271
+ }
272
+
273
+ .notis-markdown table {
274
+ margin: 0.75em 0;
275
+ width: 100%;
276
+ border-collapse: collapse;
277
+ font-size: 0.95em;
278
+ }
279
+
280
+ .notis-markdown th,
281
+ .notis-markdown td {
282
+ padding: 0.375em 0.75em;
283
+ border: 1px solid hsl(var(--border));
284
+ text-align: left;
285
+ }
286
+
287
+ .notis-markdown th {
288
+ background: hsl(var(--muted));
289
+ font-weight: 600;
290
+ }
@@ -0,0 +1,66 @@
1
+ /** Build-only SDK content discovery. Author configuration and PostCSS plugins stay intact. */
2
+ import { existsSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs';
3
+ import { tmpdir } from 'node:os';
4
+ import { dirname, join, relative, resolve } from 'node:path';
5
+ import { fileURLToPath } from 'node:url';
6
+
7
+ export function notisTailwindContent() {
8
+ let root = process.cwd();
9
+ let temporary: string | undefined;
10
+ const wrappers = new Map<string, string>();
11
+ const cleanup = () => {
12
+ if (temporary) rmSync(temporary, { recursive: true, force: true });
13
+ temporary = undefined;
14
+ wrappers.clear();
15
+ };
16
+ return {
17
+ name: 'notis-sdk-tailwind-content',
18
+ enforce: 'pre' as const,
19
+ configResolved(config: { root: string }) { root = config.root; },
20
+ transform(source: string, id: string) {
21
+ const stylesheet = id.split('?')[0];
22
+ if (!stylesheet.endsWith('.css')) return null;
23
+ // Tailwind 4 discovers dependency sources through CSS, not config.content.
24
+ // Keep the author's imports, configuration and PostCSS pipeline untouched.
25
+ if (/@import\s+(?:url\(\s*)?(['"])tailwindcss(?:\/[^'"]*)?\1/.test(source)) {
26
+ const sdkSource = dirname(fileURLToPath(import.meta.url));
27
+ const relativeSource = './' + relative(dirname(stylesheet), sdkSource).replaceAll('\\', '/');
28
+ const directive = `@source ${JSON.stringify(relativeSource)};`;
29
+ return source.includes(directive) ? null : { code: `${source}\n${directive}\n`, map: null };
30
+ }
31
+ if (!/@tailwind\s/.test(source)) return null;
32
+ const explicit = source.match(/@config\s+(['"])(.*?)\1\s*;/);
33
+ const config = explicit
34
+ ? resolve(dirname(id.split('?')[0]), explicit[2])
35
+ : ['ts', 'js', 'cjs', 'mjs'].map(ext => join(root, `tailwind.config.${ext}`)).find(existsSync);
36
+ if (!config) return null;
37
+ let wrapper = wrappers.get(config);
38
+ if (!wrapper) {
39
+ temporary ||= mkdtempSync(join(tmpdir(), 'notis-tailwind-'));
40
+ wrapper = join(temporary, `config-${wrappers.size}.ts`);
41
+ const sdkGlob = join(dirname(fileURLToPath(import.meta.url)), '**/*.{ts,tsx}').replaceAll('\\', '/');
42
+ writeFileSync(wrapper, `import config from ${JSON.stringify(config)};
43
+ import { resolve } from 'node:path';
44
+ const content = config.content || [];
45
+ const files = Array.isArray(content) ? content : (content.files || []);
46
+ const base = ${JSON.stringify(root)};
47
+ const relativeBase = ${JSON.stringify(dirname(config))};
48
+ export default { ...config, content: {
49
+ ...(Array.isArray(content) ? {} : content),
50
+ relative: false,
51
+ files: [...files.map(file => typeof file !== 'string' ? file :
52
+ (file.startsWith('!') ? '!' : '') + resolve(content.relative ? relativeBase : base, file.replace(/^!/, ''))),
53
+ ${JSON.stringify(sdkGlob)}],
54
+ } };
55
+ `);
56
+ wrappers.set(config, wrapper);
57
+ }
58
+ const directive = `@config ${JSON.stringify('./' + relative(dirname(id.split('?')[0]), wrapper).replaceAll('\\', '/'))};`;
59
+ // Imports must remain before @config. Vite resolves them before PostCSS.
60
+ const code = explicit ? source.replace(explicit[0], directive) : `${source}\n${directive}\n`;
61
+ return { code, map: null };
62
+ },
63
+ closeBundle: cleanup,
64
+ closeWatcher: cleanup,
65
+ };
66
+ }
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Vite config builder for Notis apps.
3
+ *
4
+ * Usage:
5
+ * ```ts
6
+ * // vite.config.ts
7
+ * import { notisViteConfig } from '@notis/sdk/vite';
8
+ * import appConfig from './notis.config';
9
+ * export default notisViteConfig(appConfig);
10
+ * ```
11
+ *
12
+ * Produces a library-mode ES module bundle with React externalized.
13
+ * Output: .notis/output/bundle/app.js + app.css
14
+ */
15
+
16
+ import * as vite from 'vite';
17
+ import type { NotisAppConfig } from './config';
18
+ import type { SpacesWorkspace } from './space';
19
+ import { notisTailwindContent } from './tailwind';
20
+
21
+ const externalReact = ['react', 'react-dom', 'react-dom/client', 'react/jsx-runtime', 'react/jsx-dev-runtime'];
22
+
23
+ // The oldest browsers that support CSS light-dark() natively. With Vite's
24
+ // default CSS target, Lightning CSS (Vite 8) rewrites light-dark(a, b) into
25
+ // var(--lightningcss-light, a) var(--lightningcss-dark, b), and those
26
+ // variables are only set by a stylesheet color-scheme rule. The Notis host
27
+ // sets color-scheme inline, so the lowered colours resolve to nothing and
28
+ // render transparent. Targeting these versions keeps light-dark() as written.
29
+ export const NOTIS_CSS_TARGET = ['chrome123', 'edge123', 'firefox120', 'safari17.5'];
30
+
31
+ export function notisViteConfig(appConfig: NotisAppConfig | SpacesWorkspace): vite.UserConfig {
32
+ // Vite 8 preserves external require() calls. App bundles run in a browser
33
+ // with an ESM import map, so bundled CommonJS dependencies must import React.
34
+ // Older pulled apps also receive this SDK; their Vite already does this.
35
+ const externalRequirePlugin = 'esmExternalRequirePlugin' in vite
36
+ && typeof vite.esmExternalRequirePlugin === 'function'
37
+ ? vite.esmExternalRequirePlugin({ external: externalReact })
38
+ : null;
39
+ return {
40
+ plugins: [
41
+ notisTailwindContent(),
42
+ ...(externalRequirePlugin ? [externalRequirePlugin] : []),
43
+ // @vitejs/plugin-react is added by the consumer's vite.config.ts
44
+ // or auto-detected. We provide the config shape only.
45
+ ],
46
+ build: {
47
+ lib: {
48
+ entry: '.notis/_entry.tsx',
49
+ formats: ['es'],
50
+ fileName: () => 'app.js',
51
+ },
52
+ // Keep Vite's compatibility alias: SDK refresh also serves historical
53
+ // Vite 5/6/7 apps, which do not understand rolldownOptions.
54
+ rollupOptions: {
55
+ // On Vite 8 the plugin must own externalization as well as conversion:
56
+ // a top-level external match bypasses its require-to-import transform.
57
+ external: externalRequirePlugin ? [] : externalReact,
58
+ output: {
59
+ globals: {
60
+ react: 'window.React',
61
+ 'react-dom': 'window.ReactDOM',
62
+ 'react-dom/client': 'window.ReactDOMClient',
63
+ 'react/jsx-runtime': 'window.React',
64
+ },
65
+ assetFileNames: 'app[extname]',
66
+ inlineDynamicImports: true,
67
+ },
68
+ },
69
+ outDir: '.notis/output/bundle',
70
+ emptyOutDir: true,
71
+ cssCodeSplit: false,
72
+ cssTarget: NOTIS_CSS_TARGET,
73
+ },
74
+ resolve: {
75
+ alias: {
76
+ '@': process.cwd(),
77
+ },
78
+ },
79
+ define: {
80
+ 'process.env.NODE_ENV': JSON.stringify('production'),
81
+ },
82
+ };
83
+ }