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,387 @@
1
+ /**
2
+ * @module src/pages/admin/SimpleDashboard
3
+ * @audience installer
4
+ * @layer frontend-page
5
+ * @stability testing
6
+ *
7
+ * A simple dashboard that works within the existing admin layout.
8
+ * No layout conflicts - just content.
9
+ */
10
+
11
+ import { useState } from 'react'
12
+ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '../../components/ui/card'
13
+ import { Button } from '../../components/ui/button'
14
+ import { Input } from '../../components/ui/input'
15
+ import { Badge } from '../../components/ui/badge'
16
+ import {
17
+ Select,
18
+ SelectContent,
19
+ SelectItem,
20
+ SelectTrigger,
21
+ SelectValue,
22
+ } from '../../components/ui/select'
23
+ import { Switch } from '../../components/ui/switch'
24
+ import {
25
+ Tabs,
26
+ TabsContent,
27
+ TabsList,
28
+ TabsTrigger,
29
+ } from '../../components/ui/tabs'
30
+ import { Alert, AlertDescription, AlertTitle } from '../../components/ui/alert'
31
+ import {
32
+ Plus,
33
+ Users,
34
+ FileText,
35
+ BarChart3,
36
+ Search,
37
+ Filter,
38
+ Download,
39
+ Eye,
40
+ ChevronRight,
41
+ Database,
42
+ Shield,
43
+ CheckCircle,
44
+ AlertTriangle,
45
+ TrendingUp,
46
+ Activity,
47
+ Settings
48
+ } from 'lucide-react'
49
+
50
+ export function SimpleDashboard() {
51
+ const [selectedTab, setSelectedTab] = useState('overview')
52
+ const [searchQuery, setSearchQuery] = useState('')
53
+ const [notifications, setNotifications] = useState(true)
54
+
55
+ return (
56
+ <div className="space-y-6">
57
+ {/* Page Header */}
58
+ <div className="flex items-center justify-between">
59
+ <div>
60
+ <h2 className="text-3xl font-bold tracking-tight">Dashboard</h2>
61
+ <p className="text-muted-foreground">
62
+ Monitor your system performance and key metrics
63
+ </p>
64
+ </div>
65
+ <div className="flex items-center gap-2">
66
+ <Badge variant="outline" className="bg-green-50 text-green-700 border-green-200 dark:bg-green-900/20 dark:text-green-400 dark:border-green-800">
67
+ <CheckCircle className="w-3 h-3 mr-1" />
68
+ System Healthy
69
+ </Badge>
70
+ <Button>
71
+ <Plus className="w-4 h-4 mr-2" />
72
+ New Project
73
+ </Button>
74
+ </div>
75
+ </div>
76
+
77
+ {/* Search and Filter Bar */}
78
+ <Card>
79
+ <CardContent className="pt-6">
80
+ <div className="flex flex-col gap-4 sm:flex-row sm:items-center">
81
+ <div className="relative flex-1">
82
+ <Search className="absolute left-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-muted-foreground" />
83
+ <Input
84
+ placeholder="Search projects, users, or data..."
85
+ value={searchQuery}
86
+ onChange={(e) => setSearchQuery(e.target.value)}
87
+ className="pl-10"
88
+ />
89
+ </div>
90
+ <div className="flex gap-2">
91
+ <Button variant="outline" size="sm">
92
+ <Filter className="h-4 w-4 mr-2" />
93
+ Filter
94
+ </Button>
95
+ <Button variant="outline" size="sm">
96
+ <Download className="h-4 w-4 mr-2" />
97
+ Export
98
+ </Button>
99
+ </div>
100
+ </div>
101
+ </CardContent>
102
+ </Card>
103
+
104
+ {/* Stats Cards */}
105
+ <div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4">
106
+ <Card className="relative overflow-hidden">
107
+ <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
108
+ <CardTitle className="text-sm font-medium">Total Users</CardTitle>
109
+ <Users className="h-4 w-4 text-muted-foreground" />
110
+ </CardHeader>
111
+ <CardContent>
112
+ <div className="text-2xl font-bold">2,847</div>
113
+ <p className="text-xs text-muted-foreground flex items-center">
114
+ <TrendingUp className="w-3 h-3 mr-1 text-green-600" />
115
+ +12% from last month
116
+ </p>
117
+ </CardContent>
118
+ <div className="absolute top-0 right-0 h-16 w-16 bg-gradient-to-br from-blue-500/10 to-transparent rounded-bl-2xl"></div>
119
+ </Card>
120
+
121
+ <Card className="relative overflow-hidden">
122
+ <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
123
+ <CardTitle className="text-sm font-medium">Active Projects</CardTitle>
124
+ <FileText className="h-4 w-4 text-muted-foreground" />
125
+ </CardHeader>
126
+ <CardContent>
127
+ <div className="text-2xl font-bold">142</div>
128
+ <p className="text-xs text-muted-foreground flex items-center">
129
+ <TrendingUp className="w-3 h-3 mr-1 text-green-600" />
130
+ +5% from last month
131
+ </p>
132
+ </CardContent>
133
+ <div className="absolute top-0 right-0 h-16 w-16 bg-gradient-to-br from-green-500/10 to-transparent rounded-bl-2xl"></div>
134
+ </Card>
135
+
136
+ <Card className="relative overflow-hidden">
137
+ <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
138
+ <CardTitle className="text-sm font-medium">Data Processed</CardTitle>
139
+ <Database className="h-4 w-4 text-muted-foreground" />
140
+ </CardHeader>
141
+ <CardContent>
142
+ <div className="text-2xl font-bold">1.2M</div>
143
+ <p className="text-xs text-muted-foreground flex items-center">
144
+ <TrendingUp className="w-3 h-3 mr-1 text-green-600" />
145
+ +18% from last month
146
+ </p>
147
+ </CardContent>
148
+ <div className="absolute top-0 right-0 h-16 w-16 bg-gradient-to-br from-purple-500/10 to-transparent rounded-bl-2xl"></div>
149
+ </Card>
150
+
151
+ <Card className="relative overflow-hidden">
152
+ <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
153
+ <CardTitle className="text-sm font-medium">System Health</CardTitle>
154
+ <Activity className="h-4 w-4 text-muted-foreground" />
155
+ </CardHeader>
156
+ <CardContent>
157
+ <div className="text-2xl font-bold">98.5%</div>
158
+ <p className="text-xs text-muted-foreground flex items-center">
159
+ <AlertTriangle className="w-3 h-3 mr-1 text-yellow-600" />
160
+ -0.5% from last month
161
+ </p>
162
+ </CardContent>
163
+ <div className="absolute top-0 right-0 h-16 w-16 bg-gradient-to-br from-orange-500/10 to-transparent rounded-bl-2xl"></div>
164
+ </Card>
165
+ </div>
166
+
167
+ {/* Main Content Tabs */}
168
+ <Tabs value={selectedTab} onValueChange={setSelectedTab} className="space-y-4">
169
+ <TabsList className="grid w-full grid-cols-4">
170
+ <TabsTrigger value="overview">Overview</TabsTrigger>
171
+ <TabsTrigger value="analytics">Analytics</TabsTrigger>
172
+ <TabsTrigger value="reports">Reports</TabsTrigger>
173
+ <TabsTrigger value="settings">Settings</TabsTrigger>
174
+ </TabsList>
175
+
176
+ <TabsContent value="overview" className="space-y-4">
177
+ <div className="grid gap-6 lg:grid-cols-3">
178
+ {/* Recent Activity */}
179
+ <Card className="lg:col-span-2">
180
+ <CardHeader>
181
+ <CardTitle>Recent Activity</CardTitle>
182
+ <CardDescription>
183
+ Latest system events and user actions
184
+ </CardDescription>
185
+ </CardHeader>
186
+ <CardContent>
187
+ <div className="space-y-4">
188
+ <div className="flex items-center gap-4 p-4 rounded-lg border border-border/50 bg-card/50 hover:bg-card transition-colors">
189
+ <div className="h-10 w-10 rounded-full bg-primary/10 flex items-center justify-center">
190
+ <Users className="h-5 w-5 text-primary" />
191
+ </div>
192
+ <div className="flex-1 min-w-0">
193
+ <p className="font-medium truncate">New user registration</p>
194
+ <p className="text-sm text-muted-foreground">John Doe joined 2 minutes ago</p>
195
+ </div>
196
+ <ChevronRight className="h-4 w-4 text-muted-foreground flex-shrink-0" />
197
+ </div>
198
+
199
+ <div className="flex items-center gap-4 p-4 rounded-lg border border-border/50 bg-card/50 hover:bg-card transition-colors">
200
+ <div className="h-10 w-10 rounded-full bg-secondary/10 flex items-center justify-center">
201
+ <FileText className="h-5 w-5 text-secondary-foreground" />
202
+ </div>
203
+ <div className="flex-1 min-w-0">
204
+ <p className="font-medium truncate">Report generated</p>
205
+ <p className="text-sm text-muted-foreground">Monthly analytics report completed</p>
206
+ </div>
207
+ <ChevronRight className="h-4 w-4 text-muted-foreground flex-shrink-0" />
208
+ </div>
209
+
210
+ <div className="flex items-center gap-4 p-4 rounded-lg border border-border/50 bg-card/50 hover:bg-card transition-colors">
211
+ <div className="h-10 w-10 rounded-full bg-destructive/10 flex items-center justify-center">
212
+ <AlertTriangle className="h-5 w-5 text-destructive" />
213
+ </div>
214
+ <div className="flex-1 min-w-0">
215
+ <p className="font-medium truncate">System alert</p>
216
+ <p className="text-sm text-muted-foreground">High memory usage detected</p>
217
+ </div>
218
+ <ChevronRight className="h-4 w-4 text-muted-foreground flex-shrink-0" />
219
+ </div>
220
+ </div>
221
+ </CardContent>
222
+ </Card>
223
+
224
+ {/* Quick Actions */}
225
+ <Card>
226
+ <CardHeader>
227
+ <CardTitle>Quick Actions</CardTitle>
228
+ <CardDescription>
229
+ Common tasks and shortcuts
230
+ </CardDescription>
231
+ </CardHeader>
232
+ <CardContent className="space-y-3">
233
+ <Button className="w-full justify-start gap-2">
234
+ <Plus className="h-4 w-4" />
235
+ Create New Project
236
+ </Button>
237
+ <Button variant="outline" className="w-full justify-start gap-2">
238
+ <Users className="h-4 w-4" />
239
+ Invite Team Member
240
+ </Button>
241
+ <Button variant="outline" className="w-full justify-start gap-2">
242
+ <Download className="h-4 w-4" />
243
+ Export Report
244
+ </Button>
245
+ <Button variant="outline" className="w-full justify-start gap-2">
246
+ <Settings className="h-4 w-4" />
247
+ System Settings
248
+ </Button>
249
+ </CardContent>
250
+ </Card>
251
+ </div>
252
+ </TabsContent>
253
+
254
+ <TabsContent value="analytics" className="space-y-4">
255
+ <Card>
256
+ <CardHeader>
257
+ <CardTitle>Analytics Dashboard</CardTitle>
258
+ <CardDescription>
259
+ System performance and usage metrics
260
+ </CardDescription>
261
+ </CardHeader>
262
+ <CardContent>
263
+ <div className="h-64 flex items-center justify-center border-2 border-dashed border-border rounded-lg bg-muted/20">
264
+ <div className="text-center">
265
+ <BarChart3 className="h-12 w-12 text-muted-foreground mx-auto mb-4" />
266
+ <p className="text-muted-foreground">Analytics charts would be displayed here</p>
267
+ <p className="text-sm text-muted-foreground mt-2">Integration with charting library needed</p>
268
+ </div>
269
+ </div>
270
+ </CardContent>
271
+ </Card>
272
+ </TabsContent>
273
+
274
+ <TabsContent value="reports" className="space-y-4">
275
+ <Card>
276
+ <CardHeader>
277
+ <CardTitle>Reports</CardTitle>
278
+ <CardDescription>
279
+ Generated reports and documentation
280
+ </CardDescription>
281
+ </CardHeader>
282
+ <CardContent>
283
+ <div className="space-y-4">
284
+ {[
285
+ { name: 'Monthly Analytics', date: '2024-01-15', status: 'completed' },
286
+ { name: 'User Activity Report', date: '2024-01-14', status: 'completed' },
287
+ { name: 'System Performance', date: '2024-01-13', status: 'processing' },
288
+ ].map((report, index) => (
289
+ <div key={index} className="flex items-center justify-between p-4 border border-border/50 rounded-lg bg-card/50">
290
+ <div className="flex items-center gap-3">
291
+ <FileText className="h-5 w-5 text-muted-foreground" />
292
+ <div className="min-w-0 flex-1">
293
+ <p className="font-medium truncate">{report.name}</p>
294
+ <p className="text-sm text-muted-foreground">{report.date}</p>
295
+ </div>
296
+ </div>
297
+ <div className="flex items-center gap-2">
298
+ <Badge variant={report.status === 'completed' ? 'default' : 'secondary'}>
299
+ {report.status}
300
+ </Badge>
301
+ <Button variant="ghost" size="sm">
302
+ <Eye className="h-4 w-4" />
303
+ </Button>
304
+ </div>
305
+ </div>
306
+ ))}
307
+ </div>
308
+ </CardContent>
309
+ </Card>
310
+ </TabsContent>
311
+
312
+ <TabsContent value="settings" className="space-y-4">
313
+ <div className="grid gap-6 lg:grid-cols-2">
314
+ <Card>
315
+ <CardHeader>
316
+ <CardTitle>Preferences</CardTitle>
317
+ <CardDescription>
318
+ Customize your experience
319
+ </CardDescription>
320
+ </CardHeader>
321
+ <CardContent className="space-y-6">
322
+ <div className="flex items-center justify-between">
323
+ <div className="space-y-0.5">
324
+ <label className="text-sm font-medium">Notifications</label>
325
+ <p className="text-sm text-muted-foreground">
326
+ Receive system notifications
327
+ </p>
328
+ </div>
329
+ <Switch
330
+ checked={notifications}
331
+ onCheckedChange={setNotifications}
332
+ />
333
+ </div>
334
+
335
+ <div className="space-y-2">
336
+ <label className="text-sm font-medium">Theme</label>
337
+ <Select>
338
+ <SelectTrigger>
339
+ <SelectValue placeholder="Select theme" />
340
+ </SelectTrigger>
341
+ <SelectContent>
342
+ <SelectItem value="light">Light</SelectItem>
343
+ <SelectItem value="dark">Dark</SelectItem>
344
+ <SelectItem value="system">System</SelectItem>
345
+ </SelectContent>
346
+ </Select>
347
+ </div>
348
+ </CardContent>
349
+ </Card>
350
+
351
+ <Card>
352
+ <CardHeader>
353
+ <CardTitle>Security</CardTitle>
354
+ <CardDescription>
355
+ Manage your security settings
356
+ </CardDescription>
357
+ </CardHeader>
358
+ <CardContent className="space-y-6">
359
+ <Alert>
360
+ <Shield className="h-4 w-4" />
361
+ <AlertTitle>Two-factor authentication</AlertTitle>
362
+ <AlertDescription>
363
+ Add an extra layer of security to your account
364
+ </AlertDescription>
365
+ </Alert>
366
+
367
+ <div className="space-y-4">
368
+ <div className="space-y-2">
369
+ <label className="text-sm font-medium">Current Password</label>
370
+ <Input type="password" />
371
+ </div>
372
+
373
+ <div className="space-y-2">
374
+ <label className="text-sm font-medium">New Password</label>
375
+ <Input type="password" />
376
+ </div>
377
+
378
+ <Button className="w-full">Update Password</Button>
379
+ </div>
380
+ </CardContent>
381
+ </Card>
382
+ </div>
383
+ </TabsContent>
384
+ </Tabs>
385
+ </div>
386
+ )
387
+ }
@@ -0,0 +1,172 @@
1
+ /**
2
+ * @module src/pages/admin/TestRunDetailPage
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 { DataTable } from '../../components/ui/DataTable'
18
+ import { ArrowLeft, Beaker, AlertCircle } from 'lucide-react'
19
+ import { formatDateTime } from '../../lib/utils'
20
+
21
+ interface TestRun {
22
+ id: string
23
+ name: string
24
+ description?: string
25
+ test_type: 'unit' | 'integration' | 'e2e' | 'performance'
26
+ status: 'pending' | 'running' | 'passed' | 'failed' | 'skipped'
27
+ started_at?: string
28
+ completed_at?: string
29
+ duration_ms?: number
30
+ results: Array<{ name: string; status: string; message?: string; duration_ms?: number }>
31
+ config: Record<string, any>
32
+ created_at: string
33
+ updated_at: string
34
+ }
35
+
36
+ const TEST_TYPES = [
37
+ { value: 'unit', label: 'Unit Test' },
38
+ { value: 'integration', label: 'Integration Test' },
39
+ { value: 'e2e', label: 'End-to-End Test' },
40
+ { value: 'performance', label: 'Performance Test' }
41
+ ]
42
+
43
+ const STATUSES = [
44
+ { value: 'pending', label: 'Pending' },
45
+ { value: 'running', label: 'Running' },
46
+ { value: 'passed', label: 'Passed' },
47
+ { value: 'failed', label: 'Failed' },
48
+ { value: 'skipped', label: 'Skipped' }
49
+ ]
50
+
51
+ export function TestRunDetailPage() {
52
+ const { id } = useParams<{ id: string }>()
53
+ const navigate = useNavigate()
54
+ const isCreateMode = !id || id === 'new'
55
+ const [testRun, setTestRun] = useState<TestRun | null>(null)
56
+ const [loading, setLoading] = useState(true)
57
+ const [error, setError] = useState<string | null>(null)
58
+ const [isEditing, setIsEditing] = useState(isCreateMode)
59
+ const [formData, setFormData] = useState({
60
+ name: '', description: '', test_type: 'unit' as const, config: '{}', status: 'pending' as const
61
+ })
62
+
63
+ useEffect(() => {
64
+ if (isCreateMode) {
65
+ setLoading(false)
66
+ return
67
+ }
68
+ setLoading(true)
69
+ const fetchTestRun = async () => {
70
+ try {
71
+ const response = await apiFetch(`/api/test-runs?action=get&id=${id}`)
72
+ if (!response.ok) throw new Error('Failed to fetch test run')
73
+ const result = await response.json()
74
+ const data = result.data
75
+ setTestRun(data)
76
+ setFormData({
77
+ name: data.name, description: data.description || '', test_type: data.test_type, status: data.status,
78
+ config: JSON.stringify(data.config || {}, null, 2)
79
+ })
80
+ } catch (err) {
81
+ setError(err instanceof Error ? err.message : 'Failed to load test run')
82
+ } finally {
83
+ setLoading(false)
84
+ }
85
+ }
86
+ fetchTestRun()
87
+ }, [id, isCreateMode])
88
+
89
+ const handleSave = async () => {
90
+ try {
91
+ let parsedConfig = {}
92
+ try { parsedConfig = JSON.parse(formData.config) } catch {}
93
+ const url = isCreateMode ? '/api/test-runs?action=create' : `/api/test-runs?action=update&id=${id}`
94
+ const method = isCreateMode ? 'POST' : 'PATCH'
95
+ const response = await apiFetch(url, { method, headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ ...formData, config: parsedConfig }) })
96
+ if (!response.ok) throw new Error('Failed to save test run')
97
+ if (isCreateMode) {
98
+ const result = await response.json()
99
+ navigate(`/spine-framework/admin/configs/test-runs/${result.data?.id || result.id}`)
100
+ } else setIsEditing(false)
101
+ } catch (err) {
102
+ setError(err instanceof Error ? err.message : 'Failed to save')
103
+ }
104
+ }
105
+
106
+ if (loading) return (
107
+ <div className="space-y-6">
108
+ <Skeleton className="h-8 w-48" />
109
+ <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>
110
+ </div>
111
+ )
112
+
113
+ if (error && !isCreateMode) return (
114
+ <Alert variant="destructive"><AlertCircle className="h-4 w-4" /><AlertTitle>Error</AlertTitle><AlertDescription>{error}</AlertDescription></Alert>
115
+ )
116
+
117
+ const resultColumns = [
118
+ { key: 'name' as keyof any, title: 'Test' },
119
+ { key: 'status' as keyof any, title: 'Status', render: (v: string) => <Badge variant={v === 'passed' ? 'default' : v === 'failed' ? 'destructive' : 'outline'}>{v}</Badge> },
120
+ { key: 'duration_ms' as keyof any, title: 'Duration', render: (v?: number) => v ? `${v}ms` : '—' },
121
+ { key: 'message' as keyof any, title: 'Message' }
122
+ ]
123
+
124
+ return (
125
+ <div className="space-y-6">
126
+ <div className="flex items-center justify-between">
127
+ <div className="flex items-center gap-4">
128
+ <Button variant="ghost" onClick={() => isCreateMode ? navigate('/spine-framework/admin/configs/testing') : navigate(-1)}><ArrowLeft className="h-5 w-5" /></Button>
129
+ <div>
130
+ <h1 className="text-2xl font-bold">{isCreateMode ? 'Create Test Run' : testRun?.name}</h1>
131
+ {testRun && <Badge variant={testRun.status === 'passed' ? 'default' : testRun.status === 'failed' ? 'destructive' : 'secondary'}>{testRun.status}</Badge>}
132
+ </div>
133
+ </div>
134
+ <div className="flex gap-2">
135
+ {isEditing ? (
136
+ <><Button variant="outline" onClick={() => isCreateMode ? navigate(-1) : setIsEditing(false)}>Cancel</Button><Button onClick={handleSave}>{isCreateMode ? 'Create' : 'Save'}</Button></>
137
+ ) : !isCreateMode && <Button onClick={() => setIsEditing(true)}>Edit</Button>}
138
+ </div>
139
+ </div>
140
+
141
+ <Card><CardContent className="p-6">
142
+ <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
143
+ <div className="space-y-4">
144
+ <h3 className="text-sm font-medium text-muted-foreground">Test Configuration</h3>
145
+ <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">{testRun?.name}</div>}</div>
146
+ <div className="space-y-2"><Label>Type</Label>{isEditing ? <Select value={formData.test_type} onValueChange={v => setFormData({...formData, test_type: v as any})}><SelectTrigger><SelectValue /></SelectTrigger><SelectContent>{TEST_TYPES.map(t => <SelectItem key={t.value} value={t.value}>{t.label}</SelectItem>)}</SelectContent></Select> : <Badge>{testRun?.test_type}</Badge>}</div>
147
+ <div className="space-y-2"><Label>Status</Label>{isEditing ? <Select value={formData.status} onValueChange={v => setFormData({...formData, status: v as any})}><SelectTrigger><SelectValue /></SelectTrigger><SelectContent>{STATUSES.map(s => <SelectItem key={s.value} value={s.value}>{s.label}</SelectItem>)}</SelectContent></Select> : <Badge>{testRun?.status}</Badge>}</div>
148
+ </div>
149
+ <div className="space-y-4">
150
+ <h3 className="text-sm font-medium text-muted-foreground">Execution Info</h3>
151
+ {!isCreateMode && (
152
+ <>
153
+ <div className="flex justify-between"><span className="text-sm text-muted-foreground">Started</span><span className="text-sm">{testRun?.started_at ? formatDateTime(testRun.started_at) : '—'}</span></div>
154
+ <div className="flex justify-between"><span className="text-sm text-muted-foreground">Completed</span><span className="text-sm">{testRun?.completed_at ? formatDateTime(testRun.completed_at) : '—'}</span></div>
155
+ <div className="flex justify-between"><span className="text-sm text-muted-foreground">Duration</span><span className="text-sm">{testRun?.duration_ms ? `${testRun.duration_ms}ms` : '—'}</span></div>
156
+ <div className="flex justify-between"><span className="text-sm text-muted-foreground">Results</span><span className="text-sm">{testRun?.results?.length || 0} tests</span></div>
157
+ </>
158
+ )}
159
+ </div>
160
+ </div>
161
+ <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">{testRun?.description || '—'}</div>}</div>
162
+ <div className="mt-6 space-y-2"><Label>Config (JSON)</Label>{isEditing ? <Textarea value={formData.config} onChange={e => setFormData({...formData, config: e.target.value})} rows={6} className="font-mono text-sm" /> : <pre className="text-sm bg-muted p-3 rounded">{JSON.stringify(testRun?.config || {}, null, 2)}</pre>}</div>
163
+ </CardContent></Card>
164
+
165
+ {!isCreateMode && testRun?.results && (
166
+ <Card><CardHeader><CardTitle>Results ({testRun.results.length})</CardTitle></CardHeader><CardContent>
167
+ <DataTable data={testRun.results} columns={resultColumns as any} />
168
+ </CardContent></Card>
169
+ )}
170
+ </div>
171
+ )
172
+ }