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,257 @@
1
+ /**
2
+ * @module src/pages/admin/TestingDashboard
3
+ * @audience installer
4
+ * @layer frontend-page
5
+ * @stability stable
6
+ *
7
+ * Admin Testing dashboard. Shows per-suite health cards (unit, integration,
8
+ * api, ui) and a table of the 20 most recent test runs. Read-only — tests
9
+ * are triggered by the agentic IDE, not from this UI.
10
+ *
11
+ * Route: /admin/testing
12
+ *
13
+ * @seeAlso src/pages/admin/TestRunDetailPage.tsx
14
+ * @seeAlso functions/tests.ts (data source)
15
+ * @seeAlso migrations_dayzero/008_test_runs.sql
16
+ */
17
+
18
+ import React from 'react'
19
+ import { useNavigate } from 'react-router-dom'
20
+ import { useApi } from '../../hooks/useApi'
21
+ import { apiFetch } from '../../lib/api'
22
+ import { AgentView } from '../../components/shared/AgentView'
23
+ import { FlaskConical, CheckCircle, XCircle, Clock, RefreshCw } from 'lucide-react';
24
+ import { LoadingSpinner } from '../../components/ui/LoadingSpinner'
25
+ import { formatDateTime } from '../../lib/utils'
26
+
27
+ // ─── TYPES ───────────────────────────────────────────────────────────────────
28
+
29
+ interface SuiteStat {
30
+ suite: string
31
+ total_runs: number
32
+ last_status: string | null
33
+ last_run_at: string | null
34
+ last_passed: number | null
35
+ last_failed: number | null
36
+ last_total: number | null
37
+ }
38
+
39
+ interface TestRun {
40
+ id: string
41
+ suite: string
42
+ status: string
43
+ started_at: string
44
+ finished_at: string | null
45
+ duration_ms: number | null
46
+ total: number | null
47
+ passed: number | null
48
+ failed: number | null
49
+ skipped: number | null
50
+ triggered_by: string | null
51
+ }
52
+
53
+ // ─── HELPERS ─────────────────────────────────────────────────────────────────
54
+
55
+ const SUITE_LABELS: Record<string, string> = {
56
+ unit: 'Unit',
57
+ integration: 'Integration',
58
+ api: 'API',
59
+ ui: 'UI',
60
+ }
61
+
62
+ function StatusBadge({ status }: { status: string | null }) {
63
+ if (!status) return <span className="text-gray-400 text-xs">—</span>
64
+ const color =
65
+ status === 'passed' ? 'bg-green-100 text-green-800' :
66
+ status === 'failed' ? 'bg-red-100 text-red-800' :
67
+ status === 'running' ? 'bg-blue-100 text-blue-800' :
68
+ 'bg-gray-100 text-gray-600'
69
+ return (
70
+ <span className={`inline-flex items-center px-2 py-0.5 rounded text-xs font-medium ${color}`}>
71
+ {status}
72
+ </span>
73
+ )
74
+ }
75
+
76
+ function durationLabel(ms: number | null): string {
77
+ if (ms == null) return '—'
78
+ if (ms < 1000) return `${ms}ms`
79
+ return `${(ms / 1000).toFixed(1)}s`
80
+ }
81
+
82
+ // ─── SUITE HEALTH CARD ───────────────────────────────────────────────────────
83
+
84
+ function SuiteCard({ stat }: { stat: SuiteStat }) {
85
+ const label = SUITE_LABELS[stat.suite] ?? stat.suite
86
+ const passRate = stat.last_total
87
+ ? Math.round(((stat.last_passed ?? 0) / stat.last_total) * 100)
88
+ : null
89
+
90
+ return (
91
+ <div className="bg-white border border-gray-200 rounded-lg p-4 flex flex-col gap-2">
92
+ <div className="flex items-center justify-between">
93
+ <span className="text-sm font-semibold text-gray-700">{label}</span>
94
+ <StatusBadge status={stat.last_status} />
95
+ </div>
96
+ {stat.last_run_at ? (
97
+ <>
98
+ <div className="text-xs text-gray-500">
99
+ Last run {formatDateTime(stat.last_run_at)}
100
+ </div>
101
+ <div className="flex items-center gap-3 text-xs">
102
+ <span className="text-green-600 font-medium">{stat.last_passed ?? 0}✓</span>
103
+ <span className="text-red-500 font-medium">{stat.last_failed ?? 0}✗</span>
104
+ {passRate !== null && (
105
+ <span className="text-gray-500">{passRate}% pass</span>
106
+ )}
107
+ </div>
108
+ </>
109
+ ) : (
110
+ <div className="text-xs text-gray-400">No runs yet</div>
111
+ )}
112
+ <div className="text-xs text-gray-400">{stat.total_runs} total run{stat.total_runs !== 1 ? 's' : ''}</div>
113
+ </div>
114
+ )
115
+ }
116
+
117
+ // ─── PAGE ────────────────────────────────────────────────────────────────────
118
+
119
+ export default function TestingDashboard() {
120
+ const navigate = useNavigate()
121
+
122
+ const { data: statsData, loading: statsLoading, execute: refreshStats } = useApi(
123
+ () => apiFetch('/.netlify/functions/tests?action=stats').then(r => r.json()),
124
+ { immediate: true }
125
+ )
126
+
127
+ const { data: runsData, loading: runsLoading, execute: refreshRuns } = useApi(
128
+ () => apiFetch('/.netlify/functions/tests?action=list&limit=20').then(r => r.json()),
129
+ { immediate: true }
130
+ )
131
+
132
+ const loading = statsLoading || runsLoading
133
+
134
+ function handleRefresh() {
135
+ refreshStats()
136
+ refreshRuns()
137
+ }
138
+
139
+ // API returns { data: { data: [...], error: null }, error: null, meta: {...} }
140
+ const stats: SuiteStat[] = (statsData as any)?.data?.data ?? []
141
+ const runs: TestRun[] = (runsData as any)?.data?.data ?? []
142
+
143
+ return (
144
+ <div className="p-6 max-w-6xl mx-auto">
145
+ {/* Header */}
146
+ <div className="flex items-center justify-between mb-6">
147
+ <div className="flex items-center gap-2">
148
+ <FlaskConical className="w-6 h-6 text-gray-500" />
149
+ <h1 className="text-xl font-semibold text-gray-900">Testing</h1>
150
+ </div>
151
+ <button
152
+ onClick={handleRefresh}
153
+ className="inline-flex items-center gap-1.5 text-sm text-gray-500 hover:text-gray-800 transition-colors"
154
+ >
155
+ <RefreshCw className={`w-4 h-4 ${loading ? 'animate-spin' : ''}`} />
156
+ Refresh
157
+ </button>
158
+ </div>
159
+
160
+ {/* Suite health cards */}
161
+ {statsLoading ? (
162
+ <div className="flex justify-center py-8"><LoadingSpinner /></div>
163
+ ) : (
164
+ <div className="grid grid-cols-2 lg:grid-cols-4 gap-4 mb-8">
165
+ {['unit', 'integration', 'api', 'ui'].map(suite => {
166
+ const stat = stats.find(s => s.suite === suite) ?? {
167
+ suite, total_runs: 0, last_status: null, last_run_at: null,
168
+ last_passed: null, last_failed: null, last_total: null
169
+ }
170
+ return <SuiteCard key={suite} stat={stat} />
171
+ })}
172
+ </div>
173
+ )}
174
+
175
+ {/* Recent runs table */}
176
+ <div className="bg-white border border-gray-200 rounded-lg overflow-hidden">
177
+ <div className="px-4 py-3 border-b border-gray-100 flex items-center gap-2">
178
+ <Clock className="w-4 h-4 text-gray-400" />
179
+ <span className="text-sm font-medium text-gray-700">Recent Runs</span>
180
+ </div>
181
+
182
+ {runsLoading ? (
183
+ <div className="flex justify-center py-8"><LoadingSpinner /></div>
184
+ ) : runs.length === 0 ? (
185
+ <div className="text-center py-12 text-gray-400 text-sm">
186
+ No test runs yet. Trigger a test suite from the IDE.
187
+ </div>
188
+ ) : (
189
+ <table className="w-full text-sm">
190
+ <thead className="bg-gray-50 text-xs font-medium text-gray-500 uppercase tracking-wide">
191
+ <tr>
192
+ <th className="px-4 py-2 text-left">Suite</th>
193
+ <th className="px-4 py-2 text-left">Status</th>
194
+ <th className="px-4 py-2 text-left">Started</th>
195
+ <th className="px-4 py-2 text-right">Pass</th>
196
+ <th className="px-4 py-2 text-right">Fail</th>
197
+ <th className="px-4 py-2 text-right">Total</th>
198
+ <th className="px-4 py-2 text-right">Duration</th>
199
+ </tr>
200
+ </thead>
201
+ <tbody className="divide-y divide-gray-50">
202
+ {runs.map(run => (
203
+ <tr
204
+ key={run.id}
205
+ className="hover:bg-gray-50 cursor-pointer transition-colors"
206
+ onClick={() => navigate(`/spine-framework/admin/testing/${run.id}`)}
207
+ >
208
+ <td className="px-4 py-2.5">
209
+ <span className="font-medium text-gray-700">
210
+ {SUITE_LABELS[run.suite] ?? run.suite}
211
+ </span>
212
+ </td>
213
+ <td className="px-4 py-2.5">
214
+ <StatusBadge status={run.status} />
215
+ </td>
216
+ <td className="px-4 py-2.5 text-gray-500">
217
+ {formatDateTime(run.started_at)}
218
+ </td>
219
+ <td className="px-4 py-2.5 text-right text-green-600 font-medium">
220
+ {run.passed ?? '—'}
221
+ </td>
222
+ <td className="px-4 py-2.5 text-right text-red-500 font-medium">
223
+ {run.failed ?? '—'}
224
+ </td>
225
+ <td className="px-4 py-2.5 text-right text-gray-500">
226
+ {run.total ?? '—'}
227
+ </td>
228
+ <td className="px-4 py-2.5 text-right text-gray-400">
229
+ {durationLabel(run.duration_ms)}
230
+ </td>
231
+ </tr>
232
+ ))}
233
+ </tbody>
234
+ </table>
235
+ )}
236
+ </div>
237
+
238
+ {/* Empty state hint */}
239
+ {!loading && runs.length > 0 && (
240
+ <p className="mt-3 text-xs text-gray-400 text-center">
241
+ Click any row to view individual test case results
242
+ </p>
243
+ )}
244
+
245
+ {/* Agent View — for developers and agentic IDEs */}
246
+ {!loading && stats.length > 0 && runs.length > 0 && (
247
+ <AgentView
248
+ data={{ suite_stats: stats, recent_runs: runs.slice(0, 5) }}
249
+ endpoint="/.netlify/functions/tests"
250
+ method="GET"
251
+ query={{ action: 'stats' }}
252
+ title="Agent View — Test Data API"
253
+ />
254
+ )}
255
+ </div>
256
+ )
257
+ }
@@ -0,0 +1,151 @@
1
+ /**
2
+ * @module src/pages/admin/TimerDetailPage
3
+ */
4
+ import { useState, useEffect } from 'react'
5
+ import { useParams, useNavigate } from 'react-router-dom'
6
+ import { apiFetch } from '../../lib/api'
7
+ import { Button } from '../../components/ui/button'
8
+ import { Input } from '../../components/ui/input'
9
+ import { Textarea } from '../../components/ui/textarea'
10
+ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../../components/ui/select'
11
+ import { Checkbox } from '../../components/ui/checkbox'
12
+ import { Label } from '../../components/ui/label'
13
+ import { Card, CardContent, CardHeader, CardTitle } from '../../components/ui/card'
14
+ import { Skeleton } from '../../components/ui/skeleton'
15
+ import { Alert, AlertDescription, AlertTitle } from '../../components/ui/alert'
16
+ import { Badge } from '../../components/ui/badge'
17
+ import { ArrowLeft, Clock, AlertCircle } from 'lucide-react'
18
+ import { formatDateTime } from '../../lib/utils'
19
+
20
+ interface Timer {
21
+ id: string
22
+ name: string
23
+ description?: string
24
+ schedule: string
25
+ timer_type: 'interval' | 'cron' | 'once'
26
+ interval_seconds?: number
27
+ next_run?: string
28
+ last_run?: string
29
+ last_run_status?: 'success' | 'failed'
30
+ is_active: boolean
31
+ target_type: string
32
+ target_action: string
33
+ target_config: Record<string, any>
34
+ created_at: string
35
+ updated_at: string
36
+ }
37
+
38
+ const TIMER_TYPES = [
39
+ { value: 'interval', label: 'Interval' },
40
+ { value: 'cron', label: 'Cron Expression' },
41
+ { value: 'once', label: 'One-time' }
42
+ ]
43
+
44
+ export function TimerDetailPage() {
45
+ const { id } = useParams<{ id: string }>()
46
+ const navigate = useNavigate()
47
+ const isCreateMode = !id || id === 'new'
48
+ const [timer, setTimer] = useState<Timer | null>(null)
49
+ const [loading, setLoading] = useState(true)
50
+ const [error, setError] = useState<string | null>(null)
51
+ const [isEditing, setIsEditing] = useState(isCreateMode)
52
+ const [formData, setFormData] = useState({ name: '', description: '', schedule: '', timer_type: 'interval' as const, interval_seconds: 3600, is_active: true, target_type: '', target_action: '', target_config: '{}' })
53
+
54
+ useEffect(() => {
55
+ if (isCreateMode) {
56
+ setLoading(false)
57
+ return
58
+ }
59
+ setLoading(true)
60
+ const fetchTimer = async () => {
61
+ try {
62
+ const response = await apiFetch(`/api/timers?action=get&id=${id}`)
63
+ if (!response.ok) throw new Error('Failed to fetch timer')
64
+ const result = await response.json()
65
+ const data = result.data
66
+ setTimer(data)
67
+ setFormData({
68
+ name: data.name, description: data.description || '', schedule: data.schedule, timer_type: data.timer_type,
69
+ interval_seconds: data.interval_seconds || 3600, is_active: data.is_active, target_type: data.target_type,
70
+ target_action: data.target_action, target_config: JSON.stringify(data.target_config || {}, null, 2)
71
+ })
72
+ } catch (err) {
73
+ setError(err instanceof Error ? err.message : 'Failed to load timer')
74
+ } finally {
75
+ setLoading(false)
76
+ }
77
+ }
78
+ fetchTimer()
79
+ }, [id, isCreateMode])
80
+
81
+ const handleSave = async () => {
82
+ try {
83
+ let parsedConfig = {}
84
+ try { parsedConfig = JSON.parse(formData.target_config) } catch { throw new Error('Invalid target config JSON') }
85
+ const url = isCreateMode ? '/api/timers?action=create' : `/api/timers?action=update&id=${id}`
86
+ const method = isCreateMode ? 'POST' : 'PATCH'
87
+ const response = await apiFetch(url, { method, headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ ...formData, target_config: parsedConfig }) })
88
+ if (!response.ok) throw new Error('Failed to save timer')
89
+ if (isCreateMode) {
90
+ const result = await response.json()
91
+ navigate(`/spine-framework/admin/configs/timers/${result.data?.id || result.id}`)
92
+ } else setIsEditing(false)
93
+ } catch (err) {
94
+ setError(err instanceof Error ? err.message : 'Failed to save')
95
+ }
96
+ }
97
+
98
+ if (loading) return (
99
+ <div className="space-y-6">
100
+ <Skeleton className="h-8 w-48" />
101
+ <Card><CardHeader><Skeleton className="h-6 w-32" /></CardHeader><CardContent className="space-y-4"><Skeleton className="h-4 w-full" /><Skeleton className="h-4 w-2/3" /></CardContent></Card>
102
+ </div>
103
+ )
104
+
105
+ if (error && !isCreateMode) return (
106
+ <Alert variant="destructive"><AlertCircle className="h-4 w-4" /><AlertTitle>Error</AlertTitle><AlertDescription>{error}</AlertDescription></Alert>
107
+ )
108
+
109
+ return (
110
+ <div className="space-y-6">
111
+ <div className="flex items-center justify-between">
112
+ <div className="flex items-center gap-4">
113
+ <Button variant="ghost" onClick={() => isCreateMode ? navigate('/spine-framework/admin/configs/timers') : navigate(-1)}><ArrowLeft className="h-5 w-5" /></Button>
114
+ <h1 className="text-2xl font-bold">{isCreateMode ? 'Create Timer' : timer?.name}</h1>
115
+ </div>
116
+ <div className="flex gap-2">
117
+ {isEditing ? (
118
+ <><Button variant="outline" onClick={() => isCreateMode ? navigate(-1) : setIsEditing(false)}>Cancel</Button><Button onClick={handleSave}>{isCreateMode ? 'Create' : 'Save'}</Button></>
119
+ ) : !isCreateMode && <Button onClick={() => setIsEditing(true)}>Edit</Button>}
120
+ </div>
121
+ </div>
122
+
123
+ <Card><CardContent className="p-6">
124
+ <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
125
+ <div className="space-y-4">
126
+ <h3 className="text-sm font-medium text-muted-foreground">Configuration</h3>
127
+ <div className="space-y-2"><Label>Name</Label>{isEditing ? <Input value={formData.name} onChange={e => setFormData({...formData, name: e.target.value})} /> : <div className="text-sm">{timer?.name}</div>}</div>
128
+ <div className="space-y-2"><Label>Type</Label>{isEditing ? <Select value={formData.timer_type} onValueChange={v => setFormData({...formData, timer_type: v as any})}><SelectTrigger><SelectValue /></SelectTrigger><SelectContent>{TIMER_TYPES.map(t => <SelectItem key={t.value} value={t.value}>{t.label}</SelectItem>)}</SelectContent></Select> : <Badge>{timer?.timer_type}</Badge>}</div>
129
+ {formData.timer_type === 'interval' && <div className="space-y-2"><Label>Interval (seconds)</Label>{isEditing ? <Input type="number" value={formData.interval_seconds} onChange={e => setFormData({...formData, interval_seconds: parseInt(e.target.value)})} /> : <div className="text-sm">{timer?.interval_seconds}s</div>}</div>}
130
+ <div className="space-y-2"><Label>Schedule/Cron</Label>{isEditing ? <Input value={formData.schedule} onChange={e => setFormData({...formData, schedule: e.target.value})} placeholder={formData.timer_type === 'interval' ? '3600' : '0 */6 * * *'} /> : <div className="text-sm font-mono">{timer?.schedule}</div>}</div>
131
+ <div className="space-y-2"><Label>Active</Label>{isEditing ? <div className="flex items-center gap-2"><Checkbox id="active" checked={formData.is_active} onCheckedChange={c => setFormData({...formData, is_active: c === true})} /><Label htmlFor="active">Enabled</Label></div> : <div className="text-sm">{timer?.is_active ? 'Yes' : 'No'}</div>}</div>
132
+ </div>
133
+ <div className="space-y-4">
134
+ <h3 className="text-sm font-medium text-muted-foreground">Execution</h3>
135
+ {!isCreateMode && (
136
+ <>
137
+ <div className="flex justify-between"><span className="text-sm text-muted-foreground">Next Run</span><span className="text-sm">{timer?.next_run ? formatDateTime(timer.next_run) : '—'}</span></div>
138
+ <div className="flex justify-between"><span className="text-sm text-muted-foreground">Last Run</span><span className="text-sm">{timer?.last_run ? formatDateTime(timer.last_run) : '—'}</span></div>
139
+ <div className="flex justify-between"><span className="text-sm text-muted-foreground">Last Status</span><Badge variant={timer?.last_run_status === 'success' ? 'default' : 'destructive'}>{timer?.last_run_status || '—'}</Badge></div>
140
+ </>
141
+ )}
142
+ <div className="space-y-2"><Label>Target Type</Label>{isEditing ? <Input value={formData.target_type} onChange={e => setFormData({...formData, target_type: e.target.value})} placeholder="e.g., function, pipeline" /> : <div className="text-sm">{timer?.target_type}</div>}</div>
143
+ <div className="space-y-2"><Label>Target Action</Label>{isEditing ? <Input value={formData.target_action} onChange={e => setFormData({...formData, target_action: e.target.value})} placeholder="e.g., execute" /> : <div className="text-sm">{timer?.target_action}</div>}</div>
144
+ </div>
145
+ </div>
146
+ <div className="mt-6 space-y-2"><Label>Description</Label>{isEditing ? <Textarea value={formData.description} onChange={e => setFormData({...formData, description: e.target.value})} rows={3} /> : <div className="text-sm">{timer?.description || '—'}</div>}</div>
147
+ <div className="mt-6 space-y-2"><Label>Target Config (JSON)</Label>{isEditing ? <Textarea value={formData.target_config} onChange={e => setFormData({...formData, target_config: e.target.value})} rows={6} className="font-mono text-sm" /> : <pre className="text-sm bg-muted p-3 rounded">{JSON.stringify(timer?.target_config || {}, null, 2)}</pre>}</div>
148
+ </CardContent></Card>
149
+ </div>
150
+ )
151
+ }