spine-framework 0.1.0

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 (385) hide show
  1. package/.framework/README.md +129 -0
  2. package/.framework/cli/bin.cjs +14 -0
  3. package/.framework/cli/commands/agents.ts +153 -0
  4. package/.framework/cli/commands/auth.ts +94 -0
  5. package/.framework/cli/commands/create-app.ts +185 -0
  6. package/.framework/cli/commands/dev.ts +295 -0
  7. package/.framework/cli/commands/doctor.ts +442 -0
  8. package/.framework/cli/commands/generate.ts +332 -0
  9. package/.framework/cli/commands/init.ts +272 -0
  10. package/.framework/cli/commands/install-app.ts +391 -0
  11. package/.framework/cli/commands/items.ts +253 -0
  12. package/.framework/cli/commands/migrations.ts +141 -0
  13. package/.framework/cli/commands/pipelines.ts +166 -0
  14. package/.framework/cli/commands/status.ts +197 -0
  15. package/.framework/cli/commands/system.ts +184 -0
  16. package/.framework/cli/commands/test.ts +227 -0
  17. package/.framework/cli/commands/uninstall-app.ts +166 -0
  18. package/.framework/cli/context.ts +268 -0
  19. package/.framework/cli/env-loader.ts +36 -0
  20. package/.framework/cli/index.ts +106 -0
  21. package/.framework/cli/welcome.cjs +45 -0
  22. package/.framework/docs/API.md +384 -0
  23. package/.framework/docs/STABILITY.md +52 -0
  24. package/.framework/docs/admin-routes.md +76 -0
  25. package/.framework/docs/api-docs-progress.md +38 -0
  26. package/.framework/docs/api-governance.md +146 -0
  27. package/.framework/docs/api-testing-results.md +212 -0
  28. package/.framework/docs/apis/admin-configs.md +567 -0
  29. package/.framework/docs/apis/admin-data.md +272 -0
  30. package/.framework/docs/apis/index.md +231 -0
  31. package/.framework/docs/apis/internal.md +295 -0
  32. package/.framework/docs/apis/runtime.md +537 -0
  33. package/.framework/docs/assembly-launch-guide.md +138 -0
  34. package/.framework/docs/audit-results.md +590 -0
  35. package/.framework/docs/authorization-model.md +170 -0
  36. package/.framework/docs/db-api-inventory.md +95 -0
  37. package/.framework/docs/examples/custom-app/README.md +77 -0
  38. package/.framework/docs/examples/custom-function/README.md +27 -0
  39. package/.framework/docs/examples/custom-function/handler.ts +48 -0
  40. package/.framework/docs/examples/custom-webhook/README.md +68 -0
  41. package/.framework/docs/gap-remediation-backlog.md +103 -0
  42. package/.framework/docs/guides/cli-guide.md +224 -0
  43. package/.framework/docs/guides/getting-started.md +103 -0
  44. package/.framework/docs/guides/import-guide.md +193 -0
  45. package/.framework/docs/guides/testing-guide.md +229 -0
  46. package/.framework/docs/permission-examples.md +326 -0
  47. package/.framework/docs/ui-adoption-verification.md +111 -0
  48. package/.framework/docs/ui-api-coverage.md +84 -0
  49. package/.framework/docs/v2-compatibility-audit.md +228 -0
  50. package/.framework/functions/.gitkeep +1 -0
  51. package/.framework/functions/_shared/agent-runner.ts +1097 -0
  52. package/.framework/functions/_shared/app-manifest.ts +184 -0
  53. package/.framework/functions/_shared/audit.ts +150 -0
  54. package/.framework/functions/_shared/db.ts +174 -0
  55. package/.framework/functions/_shared/index.ts +382 -0
  56. package/.framework/functions/_shared/middleware.ts +490 -0
  57. package/.framework/functions/_shared/permissions.ts +1325 -0
  58. package/.framework/functions/_shared/pipeline-runner.ts +731 -0
  59. package/.framework/functions/_shared/principal.ts +760 -0
  60. package/.framework/functions/_shared/schema-utils.ts +967 -0
  61. package/.framework/functions/_shared/testing.ts +258 -0
  62. package/.framework/functions/_shared/trigger-engine.ts +425 -0
  63. package/.framework/functions/_shared/webhook-registration.ts +168 -0
  64. package/.framework/functions/_shared/webhook-registry.ts +129 -0
  65. package/.framework/functions/account-nodes.ts +111 -0
  66. package/.framework/functions/admin-data.ts +606 -0
  67. package/.framework/functions/ai-agents.ts +323 -0
  68. package/.framework/functions/api-keys.ts +376 -0
  69. package/.framework/functions/apps.ts +483 -0
  70. package/.framework/functions/auth.ts +196 -0
  71. package/.framework/functions/debug-auth.ts +107 -0
  72. package/.framework/functions/embeddings.ts +556 -0
  73. package/.framework/functions/integration-routes.ts +523 -0
  74. package/.framework/functions/integrations.ts +319 -0
  75. package/.framework/functions/item-progress.ts +272 -0
  76. package/.framework/functions/logs.ts +438 -0
  77. package/.framework/functions/observability.ts +275 -0
  78. package/.framework/functions/pipeline-executions.ts +494 -0
  79. package/.framework/functions/pipelines.ts +485 -0
  80. package/.framework/functions/prompt-configs.ts +339 -0
  81. package/.framework/functions/roles.ts +387 -0
  82. package/.framework/functions/system-cron.ts +742 -0
  83. package/.framework/functions/system.ts +323 -0
  84. package/.framework/functions/tests.ts +119 -0
  85. package/.framework/functions/timers.ts +357 -0
  86. package/.framework/functions/triggers.ts +563 -0
  87. package/.framework/functions/types.ts +604 -0
  88. package/.framework/migrations/000_foundation.sql +1256 -0
  89. package/.framework/migrations/001_seed.sql +92 -0
  90. package/.framework/migrations/002_seed_constraints.sql +13 -0
  91. package/.framework/migrations/003_auth_user_trigger.sql +59 -0
  92. package/.framework/src/App.tsx +126 -0
  93. package/.framework/src/apps/admin/index.tsx +173 -0
  94. package/.framework/src/components/AppWrapper.tsx +56 -0
  95. package/.framework/src/components/CustomAppLoader.tsx +116 -0
  96. package/.framework/src/components/admin/AdminListPage.tsx +151 -0
  97. package/.framework/src/components/admin/AdminSidebar.tsx +166 -0
  98. package/.framework/src/components/admin/AdminStatsCard.tsx +62 -0
  99. package/.framework/src/components/admin/SortableTableHeader.tsx +42 -0
  100. package/.framework/src/components/app-shell/GenericAppShell.tsx +181 -0
  101. package/.framework/src/components/app-shell/GenericDetailPage.tsx +200 -0
  102. package/.framework/src/components/app-shell/GenericListPage.tsx +116 -0
  103. package/.framework/src/components/app-sidebar.tsx +228 -0
  104. package/.framework/src/components/auth/ProtectedRoute.tsx +88 -0
  105. package/.framework/src/components/layout/AppShell.tsx +91 -0
  106. package/.framework/src/components/layout/Header.tsx +88 -0
  107. package/.framework/src/components/layout/Layout.tsx +95 -0
  108. package/.framework/src/components/layout/Sidebar.tsx +329 -0
  109. package/.framework/src/components/runtime/DataDetailHeader.tsx +77 -0
  110. package/.framework/src/components/runtime/DataDetailPage.tsx +171 -0
  111. package/.framework/src/components/runtime/DataFilters.tsx +91 -0
  112. package/.framework/src/components/runtime/DataHeader.tsx +68 -0
  113. package/.framework/src/components/runtime/DataListPage.tsx +124 -0
  114. package/.framework/src/components/runtime/DataStats.tsx +70 -0
  115. package/.framework/src/components/runtime/DataTable.tsx +174 -0
  116. package/.framework/src/components/runtime/SchemaDetailForm.tsx +134 -0
  117. package/.framework/src/components/runtime/index.ts +18 -0
  118. package/.framework/src/components/search-form.tsx +29 -0
  119. package/.framework/src/components/shared/AgentView.tsx +213 -0
  120. package/.framework/src/components/shared/FieldRenderer.tsx +478 -0
  121. package/.framework/src/components/shared/SchemaFields.tsx +226 -0
  122. package/.framework/src/components/ui/DataTable.tsx +343 -0
  123. package/.framework/src/components/ui/Form.tsx +281 -0
  124. package/.framework/src/components/ui/ItemCard.tsx +296 -0
  125. package/.framework/src/components/ui/ItemListView.tsx +308 -0
  126. package/.framework/src/components/ui/LoadingSpinner.tsx +52 -0
  127. package/.framework/src/components/ui/Modal.tsx +61 -0
  128. package/.framework/src/components/ui/RichTextEditor.tsx +210 -0
  129. package/.framework/src/components/ui/accordion.tsx +82 -0
  130. package/.framework/src/components/ui/alert-dialog.tsx +197 -0
  131. package/.framework/src/components/ui/alert.tsx +76 -0
  132. package/.framework/src/components/ui/aspect-ratio.tsx +11 -0
  133. package/.framework/src/components/ui/avatar.tsx +110 -0
  134. package/.framework/src/components/ui/badge.tsx +49 -0
  135. package/.framework/src/components/ui/breadcrumb.tsx +122 -0
  136. package/.framework/src/components/ui/button-group.tsx +83 -0
  137. package/.framework/src/components/ui/button.tsx +65 -0
  138. package/.framework/src/components/ui/calendar.tsx +222 -0
  139. package/.framework/src/components/ui/card.tsx +100 -0
  140. package/.framework/src/components/ui/carousel.tsx +240 -0
  141. package/.framework/src/components/ui/chart.tsx +373 -0
  142. package/.framework/src/components/ui/checkbox.tsx +31 -0
  143. package/.framework/src/components/ui/collapsible.tsx +33 -0
  144. package/.framework/src/components/ui/combobox.tsx +299 -0
  145. package/.framework/src/components/ui/command.tsx +193 -0
  146. package/.framework/src/components/ui/context-menu.tsx +261 -0
  147. package/.framework/src/components/ui/dialog.tsx +165 -0
  148. package/.framework/src/components/ui/direction.tsx +22 -0
  149. package/.framework/src/components/ui/drawer.tsx +132 -0
  150. package/.framework/src/components/ui/dropdown-menu.tsx +269 -0
  151. package/.framework/src/components/ui/empty.tsx +104 -0
  152. package/.framework/src/components/ui/field.tsx +238 -0
  153. package/.framework/src/components/ui/hover-card.tsx +42 -0
  154. package/.framework/src/components/ui/input-group.tsx +153 -0
  155. package/.framework/src/components/ui/input-otp.tsx +87 -0
  156. package/.framework/src/components/ui/input.tsx +19 -0
  157. package/.framework/src/components/ui/item.tsx +196 -0
  158. package/.framework/src/components/ui/kbd.tsx +26 -0
  159. package/.framework/src/components/ui/label.tsx +22 -0
  160. package/.framework/src/components/ui/menubar.tsx +277 -0
  161. package/.framework/src/components/ui/native-select.tsx +61 -0
  162. package/.framework/src/components/ui/navigation-menu.tsx +164 -0
  163. package/.framework/src/components/ui/pagination.tsx +129 -0
  164. package/.framework/src/components/ui/popover.tsx +87 -0
  165. package/.framework/src/components/ui/progress.tsx +31 -0
  166. package/.framework/src/components/ui/radio-group.tsx +42 -0
  167. package/.framework/src/components/ui/resizable.tsx +50 -0
  168. package/.framework/src/components/ui/scroll-area.tsx +53 -0
  169. package/.framework/src/components/ui/select.tsx +195 -0
  170. package/.framework/src/components/ui/separator.tsx +26 -0
  171. package/.framework/src/components/ui/sheet.tsx +145 -0
  172. package/.framework/src/components/ui/sidebar.tsx +706 -0
  173. package/.framework/src/components/ui/skeleton.tsx +13 -0
  174. package/.framework/src/components/ui/slider.tsx +59 -0
  175. package/.framework/src/components/ui/sonner.tsx +47 -0
  176. package/.framework/src/components/ui/spinner.tsx +10 -0
  177. package/.framework/src/components/ui/switch.tsx +33 -0
  178. package/.framework/src/components/ui/table-primitives.tsx +141 -0
  179. package/.framework/src/components/ui/table.tsx +114 -0
  180. package/.framework/src/components/ui/tabs.tsx +90 -0
  181. package/.framework/src/components/ui/textarea.tsx +18 -0
  182. package/.framework/src/components/ui/toggle-group.tsx +89 -0
  183. package/.framework/src/components/ui/toggle.tsx +45 -0
  184. package/.framework/src/components/ui/tooltip.tsx +57 -0
  185. package/.framework/src/contexts/AppContext.tsx +133 -0
  186. package/.framework/src/contexts/AuthContext.tsx +371 -0
  187. package/.framework/src/hooks/use-mobile.ts +19 -0
  188. package/.framework/src/hooks/useApi.ts +526 -0
  189. package/.framework/src/hooks/useApps.ts +114 -0
  190. package/.framework/src/hooks/useEntityList.ts +190 -0
  191. package/.framework/src/hooks/useEntityRecord.ts +308 -0
  192. package/.framework/src/hooks/useForm.ts +307 -0
  193. package/.framework/src/hooks/useListSchema.ts +264 -0
  194. package/.framework/src/hooks/useSchemaRecord.ts +223 -0
  195. package/.framework/src/index.css +128 -0
  196. package/.framework/src/lib/api.ts +156 -0
  197. package/.framework/src/lib/supabase.ts +94 -0
  198. package/.framework/src/lib/utils.ts +317 -0
  199. package/.framework/src/main.tsx +27 -0
  200. package/.framework/src/pages/DashboardPage.tsx +181 -0
  201. package/.framework/src/pages/NotFoundPage.tsx +39 -0
  202. package/.framework/src/pages/admin/AIAgentDetailPage.tsx +161 -0
  203. package/.framework/src/pages/admin/AIAgentsPage.tsx +318 -0
  204. package/.framework/src/pages/admin/APIKeyDetailPage.tsx +199 -0
  205. package/.framework/src/pages/admin/APIKeysPage.tsx +303 -0
  206. package/.framework/src/pages/admin/AlertsConfigPage.tsx +523 -0
  207. package/.framework/src/pages/admin/AppDetailPage.tsx +493 -0
  208. package/.framework/src/pages/admin/AppsPage.tsx +355 -0
  209. package/.framework/src/pages/admin/DesignedPage.tsx +491 -0
  210. package/.framework/src/pages/admin/EmbeddingDetailPage.tsx +534 -0
  211. package/.framework/src/pages/admin/EmbeddingsPage.tsx +424 -0
  212. package/.framework/src/pages/admin/ExtendedShadcnTestPage.tsx +176 -0
  213. package/.framework/src/pages/admin/IncrementalShadcnTestPage.tsx +109 -0
  214. package/.framework/src/pages/admin/IntegratedDashboard.tsx +402 -0
  215. package/.framework/src/pages/admin/IntegrationDetailPage.tsx +187 -0
  216. package/.framework/src/pages/admin/IntegrationsPage.tsx +301 -0
  217. package/.framework/src/pages/admin/LogsPage.tsx +283 -0
  218. package/.framework/src/pages/admin/MinimalShadcnTestPage.tsx +85 -0
  219. package/.framework/src/pages/admin/ObservabilityDashboard.tsx +470 -0
  220. package/.framework/src/pages/admin/PipelineDetailPage.tsx +183 -0
  221. package/.framework/src/pages/admin/PipelineExecutionsPage.tsx +279 -0
  222. package/.framework/src/pages/admin/PipelinesPage.tsx +390 -0
  223. package/.framework/src/pages/admin/PromptConfigDetailPage.tsx +299 -0
  224. package/.framework/src/pages/admin/PromptConfigsPage.tsx +292 -0
  225. package/.framework/src/pages/admin/ProperlyDesignedPage.tsx +434 -0
  226. package/.framework/src/pages/admin/RoleDetailPage.tsx +273 -0
  227. package/.framework/src/pages/admin/RolesPage.tsx +292 -0
  228. package/.framework/src/pages/admin/SelectTestPage.tsx +61 -0
  229. package/.framework/src/pages/admin/ShadcnTestPage.tsx +588 -0
  230. package/.framework/src/pages/admin/SimpleDashboard.tsx +387 -0
  231. package/.framework/src/pages/admin/TestRunDetailPage.tsx +172 -0
  232. package/.framework/src/pages/admin/TestingDashboard.tsx +257 -0
  233. package/.framework/src/pages/admin/TimerDetailPage.tsx +151 -0
  234. package/.framework/src/pages/admin/TimersPage.tsx +376 -0
  235. package/.framework/src/pages/admin/TriggerDetailPage.tsx +149 -0
  236. package/.framework/src/pages/admin/TriggersPage.tsx +381 -0
  237. package/.framework/src/pages/admin/TypeDetailPage.tsx +694 -0
  238. package/.framework/src/pages/admin/TypesPage.tsx +295 -0
  239. package/.framework/src/pages/auth/LoginPage.tsx +188 -0
  240. package/.framework/src/pages/auth/RegisterPage.tsx +163 -0
  241. package/.framework/src/pages/spine-framework/APIPage.tsx +17 -0
  242. package/.framework/src/pages/spine-framework/CLIPage.tsx +25 -0
  243. package/.framework/src/types/auth.ts +125 -0
  244. package/.framework/src/types/types.ts +407 -0
  245. package/STRUCTURE.md +150 -0
  246. package/config/components.json +25 -0
  247. package/config/deno.lock +108 -0
  248. package/config/package-lock.json +17183 -0
  249. package/config/postcss.config.cjs +10 -0
  250. package/config/tailwind.config.cjs +78 -0
  251. package/config/tsconfig.build.json +32 -0
  252. package/config/tsconfig.cli.json +18 -0
  253. package/config/tsconfig.json +41 -0
  254. package/config/tsconfig.node.json +17 -0
  255. package/config/tsconfig.node.tsbuildinfo +1 -0
  256. package/config/tsconfig.tsbuildinfo +1 -0
  257. package/config/typedoc.json +16 -0
  258. package/config/vite.config.d.ts +2 -0
  259. package/config/vite.config.ts +72 -0
  260. package/dist/cli/commands/agents.d.ts +39 -0
  261. package/dist/cli/commands/agents.d.ts.map +1 -0
  262. package/dist/cli/commands/auth.d.ts +36 -0
  263. package/dist/cli/commands/auth.d.ts.map +1 -0
  264. package/dist/cli/commands/create-app.d.ts +23 -0
  265. package/dist/cli/commands/create-app.d.ts.map +1 -0
  266. package/dist/cli/commands/dev.d.ts +39 -0
  267. package/dist/cli/commands/dev.d.ts.map +1 -0
  268. package/dist/cli/commands/doctor.d.ts +42 -0
  269. package/dist/cli/commands/doctor.d.ts.map +1 -0
  270. package/dist/cli/commands/generate.d.ts +36 -0
  271. package/dist/cli/commands/generate.d.ts.map +1 -0
  272. package/dist/cli/commands/init.d.ts +30 -0
  273. package/dist/cli/commands/init.d.ts.map +1 -0
  274. package/dist/cli/commands/install-app.d.ts +30 -0
  275. package/dist/cli/commands/install-app.d.ts.map +1 -0
  276. package/dist/cli/commands/items.d.ts +45 -0
  277. package/dist/cli/commands/items.d.ts.map +1 -0
  278. package/dist/cli/commands/migrations.d.ts +41 -0
  279. package/dist/cli/commands/migrations.d.ts.map +1 -0
  280. package/dist/cli/commands/pipelines.d.ts +40 -0
  281. package/dist/cli/commands/pipelines.d.ts.map +1 -0
  282. package/dist/cli/commands/status.d.ts +23 -0
  283. package/dist/cli/commands/status.d.ts.map +1 -0
  284. package/dist/cli/commands/system.d.ts +29 -0
  285. package/dist/cli/commands/system.d.ts.map +1 -0
  286. package/dist/cli/commands/test.d.ts +46 -0
  287. package/dist/cli/commands/test.d.ts.map +1 -0
  288. package/dist/cli/commands/uninstall-app.d.ts +23 -0
  289. package/dist/cli/commands/uninstall-app.d.ts.map +1 -0
  290. package/dist/cli/context.d.ts +88 -0
  291. package/dist/cli/context.d.ts.map +1 -0
  292. package/dist/cli/env-loader.d.ts +14 -0
  293. package/dist/cli/env-loader.d.ts.map +1 -0
  294. package/dist/cli/index.d.ts +41 -0
  295. package/dist/cli/index.d.ts.map +1 -0
  296. package/dist/functions/_shared/agent-runner.d.ts +156 -0
  297. package/dist/functions/_shared/agent-runner.d.ts.map +1 -0
  298. package/dist/functions/_shared/app-manifest.d.ts +68 -0
  299. package/dist/functions/_shared/app-manifest.d.ts.map +1 -0
  300. package/dist/functions/_shared/audit.d.ts +91 -0
  301. package/dist/functions/_shared/audit.d.ts.map +1 -0
  302. package/dist/functions/_shared/db.d.ts +125 -0
  303. package/dist/functions/_shared/db.d.ts.map +1 -0
  304. package/dist/functions/_shared/index.d.ts +298 -0
  305. package/dist/functions/_shared/index.d.ts.map +1 -0
  306. package/dist/functions/_shared/middleware.d.ts +315 -0
  307. package/dist/functions/_shared/middleware.d.ts.map +1 -0
  308. package/dist/functions/_shared/permissions.d.ts +626 -0
  309. package/dist/functions/_shared/permissions.d.ts.map +1 -0
  310. package/dist/functions/_shared/pipeline-runner.d.ts +124 -0
  311. package/dist/functions/_shared/pipeline-runner.d.ts.map +1 -0
  312. package/dist/functions/_shared/principal.d.ts +284 -0
  313. package/dist/functions/_shared/principal.d.ts.map +1 -0
  314. package/dist/functions/_shared/schema-utils.d.ts +181 -0
  315. package/dist/functions/_shared/schema-utils.d.ts.map +1 -0
  316. package/dist/functions/_shared/testing.d.ts +172 -0
  317. package/dist/functions/_shared/testing.d.ts.map +1 -0
  318. package/dist/functions/_shared/trigger-engine.d.ts +140 -0
  319. package/dist/functions/_shared/trigger-engine.d.ts.map +1 -0
  320. package/dist/functions/_shared/webhook-registration.d.ts +81 -0
  321. package/dist/functions/_shared/webhook-registration.d.ts.map +1 -0
  322. package/dist/functions/_shared/webhook-registry.d.ts +57 -0
  323. package/dist/functions/_shared/webhook-registry.d.ts.map +1 -0
  324. package/dist/functions/account-nodes.d.ts +48 -0
  325. package/dist/functions/account-nodes.d.ts.map +1 -0
  326. package/dist/functions/admin-data.d.ts +178 -0
  327. package/dist/functions/admin-data.d.ts.map +1 -0
  328. package/dist/functions/ai-agents.d.ts +125 -0
  329. package/dist/functions/ai-agents.d.ts.map +1 -0
  330. package/dist/functions/api-keys.d.ts +140 -0
  331. package/dist/functions/api-keys.d.ts.map +1 -0
  332. package/dist/functions/apps.d.ts +163 -0
  333. package/dist/functions/apps.d.ts.map +1 -0
  334. package/dist/functions/auth.d.ts +74 -0
  335. package/dist/functions/auth.d.ts.map +1 -0
  336. package/dist/functions/debug-auth.d.ts +33 -0
  337. package/dist/functions/debug-auth.d.ts.map +1 -0
  338. package/dist/functions/embeddings.d.ts +205 -0
  339. package/dist/functions/embeddings.d.ts.map +1 -0
  340. package/dist/functions/integration-routes.d.ts +45 -0
  341. package/dist/functions/integration-routes.d.ts.map +1 -0
  342. package/dist/functions/integrations.d.ts +124 -0
  343. package/dist/functions/integrations.d.ts.map +1 -0
  344. package/dist/functions/item-progress.d.ts +41 -0
  345. package/dist/functions/item-progress.d.ts.map +1 -0
  346. package/dist/functions/logs.d.ts +162 -0
  347. package/dist/functions/logs.d.ts.map +1 -0
  348. package/dist/functions/observability.d.ts +123 -0
  349. package/dist/functions/observability.d.ts.map +1 -0
  350. package/dist/functions/pipeline-executions.d.ts +190 -0
  351. package/dist/functions/pipeline-executions.d.ts.map +1 -0
  352. package/dist/functions/pipelines.d.ts +171 -0
  353. package/dist/functions/pipelines.d.ts.map +1 -0
  354. package/dist/functions/prompt-configs.d.ts +125 -0
  355. package/dist/functions/prompt-configs.d.ts.map +1 -0
  356. package/dist/functions/roles.d.ts +118 -0
  357. package/dist/functions/roles.d.ts.map +1 -0
  358. package/dist/functions/system-cron.d.ts +65 -0
  359. package/dist/functions/system-cron.d.ts.map +1 -0
  360. package/dist/functions/system.d.ts +29 -0
  361. package/dist/functions/system.d.ts.map +1 -0
  362. package/dist/functions/tests.d.ts +28 -0
  363. package/dist/functions/tests.d.ts.map +1 -0
  364. package/dist/functions/timers.d.ts +139 -0
  365. package/dist/functions/timers.d.ts.map +1 -0
  366. package/dist/functions/triggers.d.ts +203 -0
  367. package/dist/functions/triggers.d.ts.map +1 -0
  368. package/dist/functions/types.d.ts +151 -0
  369. package/dist/functions/types.d.ts.map +1 -0
  370. package/dist/src/types/types.d.ts +364 -0
  371. package/dist/src/types/types.d.ts.map +1 -0
  372. package/package.json +192 -0
  373. package/scripts/app-install-cli.ts +286 -0
  374. package/scripts/assemble-frontend.sh +79 -0
  375. package/scripts/assemble-functions.sh +62 -0
  376. package/scripts/assemble.sh +35 -0
  377. package/scripts/boundary-check.sh +106 -0
  378. package/scripts/build-manifest.sh +80 -0
  379. package/scripts/check-core-integrity.sh +82 -0
  380. package/scripts/ingest-chunks.cjs +202 -0
  381. package/scripts/kb-chunk-parser.cjs +312 -0
  382. package/scripts/kb-chunk-parser.ts +330 -0
  383. package/scripts/load-test-app-install.ts +484 -0
  384. package/scripts/netlify-dev-wrapper.sh +22 -0
  385. package/scripts/verify-integrity.sh +69 -0
@@ -0,0 +1,626 @@
1
+ /**
2
+ * @module permissions
3
+ * @audience both
4
+ * @layer shared-core
5
+ * @stability stable
6
+ *
7
+ * Single source of truth for all authorization in Spine. Exports one singleton —
8
+ * `PermissionEngine` — that routes every access check to one of three permission
9
+ * surfaces based on the table being accessed:
10
+ *
11
+ * First surface — runtime data (items, accounts, people, threads, messages…)
12
+ * Schema-driven: permissions are encoded in `design_schema.record_permissions`
13
+ * and `design_schema.fields[x].permissions` stamped on the record at creation.
14
+ *
15
+ * Second surface — config objects (apps, pipelines, triggers, roles, types…)
16
+ * Role-driven: system_admin full access, machine read, others denied.
17
+ *
18
+ * Third surface — system metadata (logs, pipeline_executions, link_types…)
19
+ * Ownership-driven: users read their own, system_admin sees all.
20
+ *
21
+ * INVARIANT: system_admin bypasses ALL surface checks. No other bypass exists.
22
+ * INVARIANT: missing or empty `design_schema` on a first-surface record is an
23
+ * explicit deny — not a free pass. RLS controls row access; design_schema
24
+ * controls what the principal can do with the row.
25
+ * INVARIANT: never import or instantiate `_PermissionEngineInternal` directly.
26
+ * Always import the `PermissionEngine` singleton or the named legacy exports.
27
+ *
28
+ * @seeAlso db.ts (adminDb used for schema and person lookups)
29
+ * @seeAlso principal.ts (Principal interface, isSystemAdmin, getPrincipalDb)
30
+ * @seeAlso middleware.ts (CoreContext shape, ctx.db, ctx.principal)
31
+ * @seeAlso schema-utils.ts (formatFieldData, sanitizeFieldData called during sanitization)
32
+ * @seeAlso index.ts (stable export surface for custom code)
33
+ */
34
+ import { Principal } from './principal';
35
+ import { CoreContext } from './middleware';
36
+ /**
37
+ * Result of a permission resolution for a principal + record + action combination.
38
+ *
39
+ * Returned by `resolveFirstSurfacePermissions`. Captures both record-level CRUD
40
+ * flags and per-field read/write flags derived from `design_schema`.
41
+ *
42
+ * All flags default to `false` on any error or missing schema — never assume
43
+ * a missing flag means "allowed".
44
+ *
45
+ * @inputSpec none — this is a pure output type
46
+ * @outputSpec canCreate: boolean — principal may create records of this type
47
+ * @outputSpec canRead: boolean — principal may read this record
48
+ * @outputSpec canUpdate: boolean — principal may update this record
49
+ * @outputSpec canDelete: boolean — principal may delete this record
50
+ * @outputSpec fieldPermissions: Record<fieldName, {read, write}> — per-field flags
51
+ * derived from design_schema.fields[x].permissions merged across all roles
52
+ * @calledBy resolveFirstSurfacePermissions (producer), sanitizeFirstSurfaceRecordData,
53
+ * validateFirstSurfaceUpdatePermissions, canAccessFirstSurfaceRecord (consumers)
54
+ */
55
+ export interface PermissionResult {
56
+ canCreate: boolean;
57
+ canRead: boolean;
58
+ canUpdate: boolean;
59
+ canDelete: boolean;
60
+ fieldPermissions: Record<string, {
61
+ read: boolean;
62
+ write: boolean;
63
+ }>;
64
+ }
65
+ type RequestContext = CoreContext;
66
+ /**
67
+ * The single permission engine for all authorization in Spine.
68
+ *
69
+ * Instantiated once as a module-level singleton (`PermissionEngine`). Routes
70
+ * every check through one of three surfaces based on table classification.
71
+ * All public methods are async and never throw — on any internal error they
72
+ * fall back to a deny result to avoid accidental permission grants.
73
+ *
74
+ * Do not instantiate directly. Import `PermissionEngine` or use the named
75
+ * legacy exports (`sanitizeRecordData`, `validateUpdatePermissions`, etc.).
76
+ *
77
+ * @audience both
78
+ * @stability stable
79
+ * @calledBy All 19 API handlers via sanitizeRecordData / validateUpdatePermissions
80
+ * @calledBy admin-data.ts (primary consumer for runtime data)
81
+ * @testUnit tests/unit/permissions.test.ts
82
+ * @testIntegration tests/integration/isolation.test.ts, admin-data-accounts.test.ts
83
+ */
84
+ declare class _PermissionEngineInternal {
85
+ private static instance;
86
+ private readonly SECOND_SURFACE_TABLES;
87
+ private readonly THIRD_SURFACE_TABLES;
88
+ private constructor();
89
+ /**
90
+ * Classifies a table name into one of Spine's three permission surfaces.
91
+ *
92
+ * Surface membership is determined by static set membership — if a table is
93
+ * not in SECOND_SURFACE_TABLES or THIRD_SURFACE_TABLES, it defaults to first.
94
+ * This is intentionally conservative: unknown tables get the most restrictive
95
+ * surface (first), which requires a valid design_schema to grant any access.
96
+ *
97
+ * @param tableName - Table name string (e.g. 'items', 'pipelines', 'logs')
98
+ * @returns 'first' | 'second' | 'third' — surface classification
99
+ * @throws never
100
+ * @inputSpec tableName: string — any string; unknown names → 'first'
101
+ * @outputSpec 'first' | 'second' | 'third'
102
+ * @sideEffects none
103
+ * @calledBy canAccessRecord, sanitizeRecordData, validateUpdatePermissions
104
+ */
105
+ private detectSurface;
106
+ /**
107
+ * Extracts a table/type name from a record to use for surface classification.
108
+ *
109
+ * Tries multiple fields in priority order: `record.table_name` (explicitly
110
+ * set by some handlers), `record.type`, `record.item_type`, then the
111
+ * `typeSlug` param. Falls back to `'unknown'` which routes to first surface.
112
+ *
113
+ * @param record - The record object being classified
114
+ * @param typeSlug - Optional caller-provided type slug (used as last resort)
115
+ * @returns string — table name used to classify the permission surface
116
+ * @throws never
117
+ * @inputSpec record: object — any record; missing fields are safely ignored
118
+ * @inputSpec typeSlug: string | undefined — optional fallback
119
+ * @outputSpec string — one of the known table names, or 'unknown'
120
+ * @sideEffects none
121
+ * @calledBy canAccessRecord, sanitizeRecordData, validateUpdatePermissions
122
+ */
123
+ private extractTableName;
124
+ /**
125
+ * Returns the singleton instance. Called once at module load time to
126
+ * initialise `PermissionEngine`. Not for direct use outside this file.
127
+ *
128
+ * @returns _PermissionEngineInternal — the single shared instance
129
+ * @throws never
130
+ * @sideEffects creates instance on first call (subsequent calls return cached)
131
+ * @calledBy module initialisation (bottom of this file)
132
+ */
133
+ static getInstance(): _PermissionEngineInternal;
134
+ /**
135
+ * Resolves record-level and field-level permissions for a human principal
136
+ * acting on a first-surface (runtime data) record.
137
+ *
138
+ * Resolution steps:
139
+ * 1. Load `design_schema` from the type record if not pre-stamped on the record
140
+ * 2. Look up the person's role via `people.role_id` FK (single DB query)
141
+ * 3. Evaluate `design_schema.record_permissions[role]` array for CRUD flags
142
+ * 4. Evaluate `design_schema.fields[x].permissions[role]` for field flags
143
+ * 5. Apply `'all'` wildcard role key if present (grants to all authenticated)
144
+ * 6. For fields with no explicit permission, inherit from record-level flags
145
+ *
146
+ * Returns all-deny `PermissionResult` on any error — never throws.
147
+ *
148
+ * @param personId - UUID of the person making the request (from principal.id)
149
+ * @param accountId - UUID of the account context for the operation
150
+ * @param typeSlug - Slug of the type to look up design_schema if not pre-stamped
151
+ * @param _action - CRUD action (currently used for context; merge logic is role-based)
152
+ * @param designSchema - Pre-loaded design_schema object (skips DB lookup if provided)
153
+ *
154
+ * @inputSpec personId: string — valid UUID, must exist in people table with is_active=true
155
+ * @inputSpec accountId: string — valid UUID of accessible account
156
+ * @inputSpec typeSlug: string — slug of a type in the types table with is_active=true
157
+ * @inputSpec designSchema: object | undefined — if provided, must have record_permissions
158
+ * @outputSpec PermissionResult — all flags false on error/missing schema
159
+ * @throws never — catches all errors, returns defaultResult
160
+ * @sideEffects DB read: types table (if schema not pre-stamped), people table (role lookup)
161
+ * @calledBy canAccessFirstSurfaceRecord, sanitizeFirstSurfaceRecordData,
162
+ * validateFirstSurfaceUpdatePermissions
163
+ * @calls adminDb.from('types'), adminDb.from('people')
164
+ * @testUnit tests/unit/permissions.test.ts — 'resolveFirstSurfacePermissions' describe block
165
+ *
166
+ * @example Import usage (v2-custom/)
167
+ * ```ts
168
+ * import { PermissionEngine } from '../_shared/index'
169
+ * const perms = await PermissionEngine.resolveFirstSurfacePermissions(
170
+ * ctx.principal.id, ctx.accountId, 'ticket', 'read'
171
+ * )
172
+ * if (!perms.canRead) return { error: 'Forbidden' }
173
+ * ```
174
+ */
175
+ resolveFirstSurfacePermissions(personId: string, accountId: string, typeSlug: string, _action: 'create' | 'read' | 'update' | 'delete', designSchema?: any): Promise<PermissionResult>;
176
+ /**
177
+ * Checks whether the principal in `ctx` may perform `action` on a second-surface
178
+ * config object (apps, pipelines, triggers, roles, types, etc.).
179
+ *
180
+ * Rules:
181
+ * - system_admin: full access to all actions
182
+ * - machine principal: read-only
183
+ * - all others: denied
184
+ *
185
+ * @param ctx - Request context containing principal
186
+ * @param action - CRUD action being attempted
187
+ * @returns boolean — true if access is allowed
188
+ * @throws never
189
+ * @inputSpec ctx.principal: Principal — must be resolved (not anonymous)
190
+ * @inputSpec action: 'create' | 'read' | 'update' | 'delete'
191
+ * @outputSpec boolean — true = allowed, false = denied
192
+ * @sideEffects none
193
+ * @calledBy canAccessRecord (surface='second'), validateConfigObjectPermissions
194
+ */
195
+ private canAccessConfigObject;
196
+ /**
197
+ * Strips fields from a second-surface config record based on the principal's access.
198
+ *
199
+ * system_admin and machine principals receive the full record. All others
200
+ * receive only `{ id, created_at, updated_at }`. This is intentionally strict
201
+ * — config objects contain sensitive pipeline logic, schema definitions, and
202
+ * integration credentials that must not leak to end users.
203
+ *
204
+ * @param ctx - Request context
205
+ * @param record - The config record to sanitize
206
+ * @returns Sanitized record — full record or minimal stub
207
+ * @throws never
208
+ * @inputSpec ctx.principal: Principal — resolved principal
209
+ * @inputSpec record: object — must have id, created_at, updated_at at minimum
210
+ * @outputSpec object — full record for admin/machine, { id, created_at, updated_at } for others
211
+ * @sideEffects none
212
+ * @calledBy sanitizeRecordData (surface='second')
213
+ */
214
+ private sanitizeConfigObject;
215
+ /**
216
+ * Validates whether the principal may perform `action` on a second-surface record.
217
+ * Thin wrapper around `canAccessConfigObject` that returns a typed result object
218
+ * suitable for returning directly from handler validation checks.
219
+ *
220
+ * @param ctx - Request context
221
+ * @param action - CRUD action being validated
222
+ * @returns { valid: boolean, error?: string }
223
+ * @throws never
224
+ * @inputSpec ctx.principal: Principal — resolved principal
225
+ * @inputSpec action: 'create' | 'read' | 'update' | 'delete'
226
+ * @outputSpec valid: boolean — true if action is permitted
227
+ * @outputSpec error: string | undefined — human-readable denial reason if !valid
228
+ * @sideEffects none
229
+ * @calledBy validateUpdatePermissions (surface='second')
230
+ */
231
+ private validateConfigObjectPermissions;
232
+ /**
233
+ * Checks whether the principal may access a third-surface system metadata record
234
+ * (logs, pipeline_executions, trigger_executions, link_types, links).
235
+ *
236
+ * Rules:
237
+ * - system_admin: full access
238
+ * - machine principal: full access
239
+ * - human principal (read only):
240
+ * - owns the record (created_by === principal.id), OR
241
+ * - record is scoped to the principal's account (account_id === ctx.accountId), OR
242
+ * - record references the principal directly (person_id === principal.id)
243
+ * - human principal (create/update/delete): always denied
244
+ *
245
+ * @param ctx - Request context
246
+ * @param record - The system metadata record being accessed
247
+ * @param action - CRUD action being attempted
248
+ * @returns boolean — true if access is allowed
249
+ * @throws never
250
+ * @inputSpec ctx.principal: Principal — resolved principal
251
+ * @inputSpec record: object — must have at least one of: created_by, account_id, person_id
252
+ * @inputSpec action: 'create' | 'read' | 'update' | 'delete'
253
+ * @outputSpec boolean
254
+ * @sideEffects none
255
+ * @calledBy canAccessRecord (surface='third'), sanitizeSystemMetadata,
256
+ * validateSystemMetadataPermissions
257
+ */
258
+ private canAccessSystemMetadata;
259
+ /**
260
+ * Strips fields from a third-surface system metadata record based on ownership.
261
+ *
262
+ * system_admin and machine principals receive the full record. Human principals
263
+ * who pass `canAccessSystemMetadata` receive the full record. All others
264
+ * receive only `{ id, created_at, updated_at }`.
265
+ *
266
+ * @param ctx - Request context
267
+ * @param record - The system metadata record to sanitize
268
+ * @returns Sanitized record
269
+ * @throws never
270
+ * @inputSpec record: object — must have id, created_at, updated_at
271
+ * @outputSpec object — full record for system_admin/machine/owner, minimal stub for others
272
+ * @sideEffects none
273
+ * @calledBy sanitizeRecordData (surface='third')
274
+ */
275
+ private sanitizeSystemMetadata;
276
+ /**
277
+ * Validates whether the principal may perform `action` on a third-surface record.
278
+ * Delegates to `canAccessSystemMetadata` and wraps the result.
279
+ *
280
+ * @param ctx - Request context
281
+ * @param record - The system metadata record
282
+ * @param action - CRUD action being validated
283
+ * @returns { valid: boolean, error?: string }
284
+ * @throws never
285
+ * @inputSpec record: object — the record being written/read
286
+ * @outputSpec valid: boolean — true if action is permitted
287
+ * @outputSpec error: string | undefined — denial reason if !valid
288
+ * @sideEffects none
289
+ * @calledBy validateUpdatePermissions (surface='third')
290
+ */
291
+ private validateSystemMetadataPermissions;
292
+ /**
293
+ * Returns true if the principal in `ctx` holds the `system_admin` role.
294
+ *
295
+ * This is the canonical system_admin check used by all three surfaces and
296
+ * the unified principal methods. It is the ONLY mechanism for bypassing
297
+ * surface-level permission checks — there is no other bypass in the engine.
298
+ *
299
+ * @param ctx - Request context with resolved principal
300
+ * @returns boolean — true if principal.roles includes 'system_admin'
301
+ * @throws never
302
+ * @inputSpec ctx.principal: Principal — principal.roles: string[]
303
+ * @outputSpec boolean — false if principal is null, anonymous, or has no roles
304
+ * @sideEffects none
305
+ * @calledBy canAccessRecord, sanitizeRecordData, validateUpdatePermissions,
306
+ * canAccessConfigObject, sanitizeConfigObject, sanitizeSystemMetadata,
307
+ * canPrincipalAccessRecord
308
+ * @testUnit tests/unit/permissions.test.ts — 'isSystemAdmin' describe block
309
+ */
310
+ isSystemAdmin(ctx: RequestContext): boolean;
311
+ /**
312
+ * Checks whether the principal in `ctx` may perform `action` on `record`.
313
+ *
314
+ * Routes to the correct surface handler based on `record`'s table name:
315
+ * - second surface tables → `canAccessConfigObject`
316
+ * - third surface tables → `canAccessSystemMetadata`
317
+ * - everything else (first surface) → `canAccessFirstSurfaceRecord`
318
+ *
319
+ * system_admin always returns true before surface routing.
320
+ *
321
+ * @param ctx - Request context with resolved principal
322
+ * @param record - The record being accessed (used for surface detection only)
323
+ * @param action - CRUD action being attempted
324
+ * @returns Promise<boolean> — true if access is allowed
325
+ * @throws never — all surface handlers catch errors and return false
326
+ * @inputSpec ctx.principal: Principal — must be resolved
327
+ * @inputSpec record: object — used for table_name/type/item_type extraction
328
+ * @inputSpec action: 'create' | 'read' | 'update' | 'delete'
329
+ * @outputSpec boolean — false for anonymous principals, missing records, unknown types
330
+ * @sideEffects DB read (first surface only): types and people tables
331
+ * @calledBy API handlers where explicit access gate is needed (rare — most use sanitize)
332
+ * @testUnit tests/unit/permissions.test.ts — 'canAccessRecord' describe block
333
+ */
334
+ canAccessRecord(ctx: RequestContext, record: any, action: 'create' | 'read' | 'update' | 'delete'): Promise<boolean>;
335
+ /**
336
+ * Access check for first-surface (runtime data) records.
337
+ *
338
+ * Delegates to `resolveFirstSurfacePermissions` to evaluate the design_schema
339
+ * permission model. For 'own' access level, additionally checks record ownership
340
+ * via `created_by === principal.id`.
341
+ *
342
+ * Returns false for anonymous principals and any principal without a valid accountId.
343
+ *
344
+ * @param ctx - Request context
345
+ * @param record - The first-surface record being accessed
346
+ * @param action - CRUD action
347
+ * @returns Promise<boolean>
348
+ * @throws never
349
+ * @inputSpec ctx.principal: not anonymous, ctx.accountId: non-empty string
350
+ * @inputSpec record: must have account_id or item_type/type for schema resolution
351
+ * @outputSpec boolean — false for anonymous, missing schema, insufficient permissions
352
+ * @sideEffects DB read: types and people tables (via resolveFirstSurfacePermissions)
353
+ * @calledBy canAccessRecord (surface='first'), canPrincipalAccessRecord (human branch)
354
+ */
355
+ private canAccessFirstSurfaceRecord;
356
+ /**
357
+ * Strips and formats a record's fields based on the principal's permissions.
358
+ *
359
+ * This is the primary output filter called by every API handler before returning
360
+ * data to the client. Routes to the correct surface handler, which applies
361
+ * field-level filtering from the record's stamped `design_schema`.
362
+ *
363
+ * system_admin receives the full record unchanged.
364
+ *
365
+ * For first-surface records with missing `design_schema` or no `record_permissions`,
366
+ * returns `{ id }` only — explicit deny, not a pass-through.
367
+ *
368
+ * @param ctx - Request context with resolved principal
369
+ * @param record - The record to sanitize (should be the raw DB row)
370
+ * @param typeSlug - Type slug used to classify the surface and look up schema
371
+ * if not already stamped on the record. Optional for second/third surfaces.
372
+ * @returns Promise<object> — sanitized record safe to return to the client
373
+ * @throws never
374
+ * @inputSpec ctx.principal: Principal — resolved, may be anonymous
375
+ * @inputSpec record: object — raw DB row, must have id at minimum
376
+ * @inputSpec typeSlug: string | undefined — slug of the type (e.g. 'item', 'account')
377
+ * @outputSpec object — filtered record; field set depends on principal's role permissions
378
+ * @outputSpec system_admin: full record unchanged
379
+ * @outputSpec unauthenticated: { id, created_at, updated_at } only
380
+ * @outputSpec first surface, no schema: { id } only
381
+ * @sideEffects DB read (first surface): types and people tables via resolveFirstSurface
382
+ * @calledBy All 19 API handlers — this is the most-called method in the engine
383
+ * @calls sanitizeFirstSurfaceRecordData | sanitizeConfigObject | sanitizeSystemMetadata
384
+ * @testUnit tests/unit/permissions.test.ts — 'sanitizeRecordData' describe block
385
+ * @testIntegration tests/integration/admin-data-accounts.test.ts
386
+ *
387
+ * @example API handler usage
388
+ * ```ts
389
+ * const sanitized = await sanitizeRecordData(ctx, record, 'item')
390
+ * return { data: sanitized }
391
+ * ```
392
+ *
393
+ * @example Import usage (v2-custom/)
394
+ * ```ts
395
+ * import { sanitizeRecordData } from '../_shared/index'
396
+ * const safe = await sanitizeRecordData(ctx, rawRecord, 'ticket')
397
+ * ```
398
+ */
399
+ sanitizeRecordData(ctx: RequestContext, record: any, typeSlug?: string): Promise<any>;
400
+ /**
401
+ * Field-level filter and formatter for first-surface (runtime data) records.
402
+ *
403
+ * Steps:
404
+ * 1. Return minimal stub for anonymous principals
405
+ * 2. Check `record.design_schema.record_permissions` — deny if missing
406
+ * 3. Resolve permissions via `resolveFirstSurfacePermissions`
407
+ * 4. Return minimal stub if `!perms.canRead`
408
+ * 5. For each field in `record.data`, include only if `fieldPerms.read === true`
409
+ * 6. Apply `formatFieldData` from schema-utils if validation_schema specifies a data_type
410
+ * 7. Strip `record.metadata` (legacy field, migrated to `data`)
411
+ *
412
+ * @param ctx - Request context
413
+ * @param record - First-surface DB row with design_schema and data fields
414
+ * @param typeSlug - Type slug for schema lookup
415
+ * @returns Promise<object> — filtered and formatted record
416
+ * @throws never
417
+ * @inputSpec record.design_schema: object with record_permissions — deny if missing
418
+ * @inputSpec record.data: object — JSONB data fields; only permitted fields returned
419
+ * @outputSpec object — sanitized record matching the principal's field permissions
420
+ * @sideEffects DB read: types and people via resolveFirstSurfacePermissions
421
+ * @calledBy sanitizeRecordData (surface='first')
422
+ * @calls resolveFirstSurfacePermissions, schema-utils.formatFieldData
423
+ */
424
+ private sanitizeFirstSurfaceRecordData;
425
+ /**
426
+ * Validates that the principal has write permission for every field in `updateData`,
427
+ * and sanitizes the data using the validation schema before returning it.
428
+ *
429
+ * Routes to the correct surface handler. system_admin bypasses all checks and
430
+ * receives `updateData` unchanged (with `sanitizedData` set to `updateData`).
431
+ *
432
+ * For first-surface records:
433
+ * - Each field in `updateData.data` must have `fieldPerms.write === true`
434
+ * - Fields are sanitized via `sanitizeFieldData` from schema-utils
435
+ * - Returns `{ valid: false, error }` on the first denied or invalid field
436
+ *
437
+ * @param ctx - Request context with resolved principal
438
+ * @param updateData - The payload being written (may contain `data` and/or `metadata`)
439
+ * @param existingRecord - The current DB row (used for schema + account_id resolution)
440
+ * @param typeSlug - Type slug for surface classification and schema lookup
441
+ * @returns Promise<{ valid: boolean, error?: string, sanitizedData?: any }>
442
+ * @throws never
443
+ * @inputSpec ctx.principal: Principal — resolved, non-anonymous required for first surface
444
+ * @inputSpec updateData: object — payload with data: {} and/or metadata: {}
445
+ * @inputSpec existingRecord: object — must have design_schema, account_id
446
+ * @outputSpec valid: boolean — false on first permission or validation failure
447
+ * @outputSpec error: string | undefined — field name + reason when !valid
448
+ * @outputSpec sanitizedData: object | undefined — cleaned payload when valid
449
+ * @sideEffects DB read (first surface): types and people via resolveFirstSurfacePermissions
450
+ * @calledBy admin-data.ts (update handler), and any handler that accepts user writes
451
+ * @calls validateFirstSurfaceUpdatePermissions | validateConfigObjectPermissions |
452
+ * validateSystemMetadataPermissions
453
+ * @testUnit tests/unit/permissions.test.ts — 'validateUpdatePermissions' describe block
454
+ *
455
+ * @example API handler usage
456
+ * ```ts
457
+ * const { valid, error, sanitizedData } = await validateUpdatePermissions(
458
+ * ctx, body, existingRecord, 'item'
459
+ * )
460
+ * if (!valid) return { error }
461
+ * await ctx.db.from('items').update(sanitizedData).eq('id', id)
462
+ * ```
463
+ */
464
+ validateUpdatePermissions(ctx: RequestContext, updateData: any, existingRecord: any, typeSlug?: string): Promise<{
465
+ valid: boolean;
466
+ error?: string;
467
+ }>;
468
+ /**
469
+ * Field-level write validation and sanitization for first-surface update payloads.
470
+ *
471
+ * Checks every field in `updateData.data` (and legacy `updateData.metadata`) against
472
+ * the principal's write permissions. Sanitizes each permitted field through
473
+ * `sanitizeFieldData` for type coercion and constraint validation. Returns on
474
+ * the first denied or invalid field — does not accumulate errors.
475
+ *
476
+ * @param ctx - Request context
477
+ * @param updateData - Incoming update payload
478
+ * @param existingRecord - Existing DB row with design_schema stamped at creation
479
+ * @param typeSlug - Type slug for schema lookup
480
+ * @returns Promise<{ valid: boolean, error?: string, sanitizedData?: any }>
481
+ * @throws never
482
+ * @inputSpec existingRecord.design_schema.record_permissions — deny if missing
483
+ * @inputSpec updateData.data: object — all fields must have fieldPerms.write=true
484
+ * @outputSpec sanitizedData: object — only present when valid=true
485
+ * @sideEffects DB read: types and people via resolveFirstSurfacePermissions
486
+ * @calledBy validateUpdatePermissions (surface='first')
487
+ * @calls resolveFirstSurfacePermissions, schema-utils.sanitizeFieldData
488
+ */
489
+ private validateFirstSurfaceUpdatePermissions;
490
+ /**
491
+ * Unified permission check for all principal types (human, machine, cron, trigger).
492
+ *
493
+ * This is the preferred method when you have a `Principal` directly rather than
494
+ * a full `RequestContext`. Used by the Unified Principal Architecture to check
495
+ * access without constructing a fake context.
496
+ *
497
+ * Resolution:
498
+ * 1. system_admin (human with 'system_admin' role) → always true
499
+ * 2. machine principal → scope check via `checkMachineScope`
500
+ * 3. human principal with accountId → `canAccessFirstSurfaceRecord` (constructs minimal ctx)
501
+ * 4. all others → false
502
+ *
503
+ * @param principal - The fully resolved Principal from `resolvePrincipal()`
504
+ * @param record - The record being accessed; must include account_id and type for scope matching
505
+ * @param action - CRUD action being attempted
506
+ * @returns Promise<boolean> — true if the principal may perform the action
507
+ * @throws never
508
+ * @inputSpec principal: Principal — must be resolved (not ANONYMOUS_PRINCIPAL for useful results)
509
+ * @inputSpec record.account_id: string — required for human principals
510
+ * @inputSpec record.type: string | undefined — used for machine scope matching
511
+ * @outputSpec boolean
512
+ * @sideEffects DB read (human principal): types and people tables
513
+ * @calledBy Handlers that receive a Principal directly (e.g. CLI, import callers)
514
+ * @calls checkMachineScope, canAccessFirstSurfaceRecord
515
+ * @testUnit tests/unit/permissions.test.ts — 'canPrincipalAccessRecord' describe block
516
+ *
517
+ * @example Import usage (v2-custom/)
518
+ * ```ts
519
+ * import { PermissionEngine } from '../_shared/index'
520
+ * const allowed = await PermissionEngine.canPrincipalAccessRecord(
521
+ * principal, { account_id: accountId, type: 'item' }, 'create'
522
+ * )
523
+ * ```
524
+ *
525
+ * @example CLI usage
526
+ * ```bash
527
+ * # Access checks happen automatically when CLI constructs CoreContext
528
+ * spine items create --data '{"title":"Test"}'
529
+ * ```
530
+ */
531
+ canPrincipalAccessRecord(principal: Principal, record: {
532
+ account_id: string;
533
+ type?: string;
534
+ [key: string]: any;
535
+ }, action: 'create' | 'read' | 'update' | 'delete'): Promise<boolean>;
536
+ /**
537
+ * Evaluates whether a machine principal's scopes permit the requested action.
538
+ *
539
+ * Scope matching supports three patterns (evaluated in order):
540
+ * 1. Exact match: `'items:read'` matches `'items:read'`
541
+ * 2. Wildcard action: `'items:*'` matches any action on `items`
542
+ * 3. Global wildcard: `'*:*'` matches any resource and any action
543
+ *
544
+ * The required scope is constructed as `<record.type>:<action>`. If `record.type`
545
+ * is absent, `'resource'` is used as the resource name.
546
+ *
547
+ * @param principal - Machine principal (principal.type must be 'machine')
548
+ * @param record - The record being accessed (record.type used as resource name)
549
+ * @param action - The CRUD action string
550
+ * @returns boolean — true if any scope in principal.scopes grants the action
551
+ * @throws never
552
+ * @inputSpec principal.type: 'machine' — returns false for non-machine principals
553
+ * @inputSpec principal.scopes: string[] — list of granted scope strings
554
+ * @inputSpec record.type: string | undefined — resource name portion of scope check
555
+ * @outputSpec boolean
556
+ * @sideEffects none
557
+ * @calledBy canPrincipalAccessRecord (machine branch)
558
+ * @testUnit tests/unit/permissions.test.ts — 'checkMachineScope' describe block
559
+ */
560
+ private checkMachineScope;
561
+ /**
562
+ * Returns a structured summary of a principal's permission posture for use
563
+ * in audit log entries.
564
+ *
565
+ * Does not perform any access check — purely descriptive. The returned object
566
+ * is safe to serialize into the `metadata` column of the `logs` table.
567
+ *
568
+ * @param principal - The resolved principal to summarize
569
+ * @returns object — summary safe for audit log serialization
570
+ * @throws never
571
+ * @inputSpec principal: Principal — any resolved principal including ANONYMOUS
572
+ * @outputSpec { type, roles, is_system_admin } for human principals
573
+ * @outputSpec { type, machine_type, scopes, is_internal } for machine principals
574
+ * @outputSpec { type: 'unknown' } for all other types
575
+ * @sideEffects none
576
+ * @calledBy audit.ts (emitAudit), any handler that logs permission context
577
+ * @testUnit tests/unit/permissions.test.ts — 'getPrincipalPermissionSummary' describe block
578
+ *
579
+ * @example
580
+ * ```ts
581
+ * await emitAudit(ctx, 'record.read', record.id, {
582
+ * permissions: PermissionEngine.getPrincipalPermissionSummary(ctx.principal)
583
+ * })
584
+ * ```
585
+ */
586
+ getPrincipalPermissionSummary(principal: Principal): object;
587
+ }
588
+ /**
589
+ * The single shared PermissionEngine instance.
590
+ *
591
+ * This is the ONLY export that should be used for permission checks. Import this
592
+ * directly or use the named legacy aliases below. Do not instantiate
593
+ * `_PermissionEngineInternal` yourself.
594
+ *
595
+ * @stability stable
596
+ * @audience both
597
+ * @calledBy All 19 API handlers, tests, and custom code in v2-custom/
598
+ *
599
+ * @example API handler
600
+ * ```ts
601
+ * import { PermissionEngine } from './_shared/permissions'
602
+ * const sanitized = await PermissionEngine.sanitizeRecordData(ctx, record, 'item')
603
+ * ```
604
+ *
605
+ * @example Import usage (v2-custom/)
606
+ * ```ts
607
+ * import { PermissionEngine } from '../_shared/index'
608
+ * const allowed = await PermissionEngine.canPrincipalAccessRecord(principal, record, 'read')
609
+ * ```
610
+ */
611
+ export declare const PermissionEngine: _PermissionEngineInternal;
612
+ /**
613
+ * Legacy named exports — bound methods on the singleton for backward compatibility.
614
+ * Prefer importing `PermissionEngine` and calling methods on it directly.
615
+ * These will be removed in a future version.
616
+ *
617
+ * @deprecated Use `PermissionEngine.<methodName>()` instead.
618
+ * @stability internal
619
+ */
620
+ export declare const resolveFirstSurfacePermissions: any;
621
+ export declare const isSystemAdmin: any;
622
+ export declare const canAccessRecord: any;
623
+ export declare const sanitizeRecordData: any;
624
+ export declare const validateUpdatePermissions: any;
625
+ export {};
626
+ //# sourceMappingURL=permissions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../../../.framework/functions/_shared/permissions.ts"],"names":[],"mappings":"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"}