spine-framework 0.4.4 → 0.5.0-rc.4

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 (283) hide show
  1. package/.env.example +13 -3
  2. package/.framework/cli/commands/bootstrap.ts +392 -0
  3. package/.framework/cli/commands/dev.ts +91 -218
  4. package/.framework/cli/commands/doctor.ts +132 -26
  5. package/.framework/cli/commands/generate.ts +38 -298
  6. package/.framework/cli/commands/init.ts +20 -1
  7. package/.framework/cli/commands/migrate.ts +36 -30
  8. package/.framework/cli/commands/migrations.ts +16 -56
  9. package/.framework/cli/commands/upgrade.ts +35 -0
  10. package/.framework/cli/commands/validate-schema.ts +147 -0
  11. package/.framework/cli/context.ts +223 -110
  12. package/.framework/cli/index.ts +6 -0
  13. package/.framework/cli/lib/project-files.ts +241 -1
  14. package/.framework/functions/_shared/hash-api-key.ts +183 -79
  15. package/.framework/functions/_shared/logging.ts +562 -224
  16. package/.framework/functions/_shared/middleware.ts +47 -44
  17. package/.framework/functions/admin-data.ts +39 -28
  18. package/.framework/functions/ai-agents.ts +10 -6
  19. package/.framework/functions/api-keys.ts +301 -122
  20. package/.framework/functions/apps.ts +43 -26
  21. package/.framework/functions/cil-ingest.ts +48 -15
  22. package/.framework/functions/debug-auth.ts +14 -8
  23. package/.framework/functions/deliveries.ts +39 -12
  24. package/.framework/functions/embeddings.ts +145 -76
  25. package/.framework/functions/integration-outbound.ts +67 -27
  26. package/.framework/functions/integrations.ts +254 -127
  27. package/.framework/functions/logs.ts +273 -133
  28. package/.framework/functions/observability.ts +277 -147
  29. package/.framework/functions/pipeline-executions.ts +1 -1
  30. package/.framework/functions/pipelines.ts +14 -9
  31. package/.framework/functions/prompt-configs.ts +7 -4
  32. package/.framework/functions/roles.ts +8 -5
  33. package/.framework/functions/security.ts +30 -17
  34. package/.framework/functions/system-cron.ts +240 -127
  35. package/.framework/functions/tests.ts +7 -6
  36. package/.framework/functions/timers.ts +310 -107
  37. package/.framework/functions/triggers.ts +28 -13
  38. package/.framework/functions/types.ts +13 -10
  39. package/.framework/migrations/069_log_stats_window.sql +54 -0
  40. package/.framework/migrations/070_app_type_schema_rpcs.sql +166 -0
  41. package/.framework/migrations/071_timer_interval_keys.sql +96 -0
  42. package/.framework/migrations/072_slug_autofill.sql +77 -0
  43. package/.framework/migrations/073_seed_member_roles.sql +26 -0
  44. package/.framework/src/apps/admin/index.tsx +1141 -775
  45. package/.framework/src/components/ErrorBoundary.tsx +136 -0
  46. package/.framework/src/components/admin/AdminListPage.tsx +81 -73
  47. package/.framework/src/components/admin/AdminSidebar.tsx +88 -79
  48. package/.framework/src/components/admin/EntitySelect.tsx +181 -0
  49. package/.framework/src/components/admin/PageInstructions.tsx +86 -127
  50. package/.framework/src/components/app-shell/GenericDetailPage.tsx +37 -13
  51. package/.framework/src/components/app-shell/GenericListPage.tsx +28 -32
  52. package/.framework/src/components/layout/Sidebar.tsx +300 -177
  53. package/.framework/src/components/runtime/DataDetailPage.tsx +67 -35
  54. package/.framework/src/components/runtime/DataHeader.tsx +96 -48
  55. package/.framework/src/components/runtime/DataListPage.tsx +3 -26
  56. package/.framework/src/components/runtime/DataStats.tsx +10 -10
  57. package/.framework/src/components/runtime/DataTable.tsx +12 -10
  58. package/.framework/src/components/ui/sheet.tsx +24 -26
  59. package/.framework/src/components/ui/textarea.tsx +74 -48
  60. package/.framework/src/hooks/useEntityList.ts +12 -9
  61. package/.framework/src/hooks/useListSchema.ts +108 -58
  62. package/.framework/src/instructions/README.md +57 -0
  63. package/.framework/src/instructions/ai-agents.md +69 -0
  64. package/.framework/src/instructions/alerts.md +80 -0
  65. package/.framework/src/instructions/api-keys.md +87 -0
  66. package/.framework/src/instructions/apps.md +77 -0
  67. package/.framework/src/instructions/concepts/ai-and-prompts.md +150 -0
  68. package/.framework/src/instructions/concepts/apps-and-renderers.md +162 -0
  69. package/.framework/src/instructions/concepts/auth-and-api-keys.md +133 -0
  70. package/.framework/src/instructions/concepts/automation.md +186 -0
  71. package/.framework/src/instructions/concepts/concurrency-and-idempotency.md +125 -0
  72. package/.framework/src/instructions/concepts/core-vs-custom.md +124 -0
  73. package/.framework/src/instructions/concepts/design-schema.md +152 -0
  74. package/.framework/src/instructions/concepts/integrations-and-webhooks.md +127 -0
  75. package/.framework/src/instructions/concepts/observability.md +116 -0
  76. package/.framework/src/instructions/concepts/permissions.md +150 -0
  77. package/.framework/src/instructions/concepts/runtime-records.md +111 -0
  78. package/.framework/src/instructions/concepts/scope-and-accounts.md +112 -0
  79. package/.framework/src/instructions/concepts/spine-way.md +172 -0
  80. package/.framework/src/instructions/deliveries.md +59 -0
  81. package/.framework/src/instructions/guide/00-orientation.md +106 -0
  82. package/.framework/src/instructions/guide/01-install-and-first-run.md +253 -0
  83. package/.framework/src/instructions/guide/02-project-map.md +147 -0
  84. package/.framework/src/instructions/guide/03-domain-model.md +223 -0
  85. package/.framework/src/instructions/guide/04-first-app.md +227 -0
  86. package/.framework/src/instructions/guide/05-glossary.md +183 -0
  87. package/.framework/src/instructions/integrations.md +96 -0
  88. package/.framework/src/instructions/internal/cil-markers.md +83 -0
  89. package/.framework/src/instructions/invites.md +60 -0
  90. package/.framework/src/instructions/kb.md +80 -0
  91. package/.framework/src/instructions/logs.md +77 -0
  92. package/.framework/src/instructions/observability.md +61 -0
  93. package/.framework/src/instructions/operations/deployment.md +115 -0
  94. package/.framework/src/instructions/operations/migrations.md +125 -0
  95. package/.framework/src/instructions/operations/security-checklist.md +148 -0
  96. package/.framework/src/instructions/operations/troubleshooting.md +170 -0
  97. package/.framework/src/instructions/operations/upgrade.md +116 -0
  98. package/.framework/src/instructions/pipeline-executions.md +62 -0
  99. package/.framework/src/instructions/pipelines.md +78 -0
  100. package/.framework/src/instructions/prompts.md +95 -0
  101. package/.framework/src/instructions/reference/api/admin-data.md +162 -0
  102. package/.framework/src/instructions/reference/api/auth.md +113 -0
  103. package/.framework/src/instructions/reference/api/errors-and-envelopes.md +113 -0
  104. package/.framework/src/instructions/reference/app-manifest.md +150 -0
  105. package/.framework/src/instructions/reference/cli.md +124 -0
  106. package/.framework/src/instructions/reference/database.md +132 -0
  107. package/.framework/src/instructions/reference/design-schema.md +280 -0
  108. package/.framework/src/instructions/reference/env-vars.md +133 -0
  109. package/.framework/src/instructions/reference/functions/account-nodes.md +75 -0
  110. package/.framework/src/instructions/reference/functions/admin-data.md +195 -0
  111. package/.framework/src/instructions/reference/functions/admin-funnel.md +90 -0
  112. package/.framework/src/instructions/reference/functions/admin-install-funnel.md +107 -0
  113. package/.framework/src/instructions/reference/functions/admin-signals.md +102 -0
  114. package/.framework/src/instructions/reference/functions/ai-agents.md +148 -0
  115. package/.framework/src/instructions/reference/functions/ai-interactions.md +156 -0
  116. package/.framework/src/instructions/reference/functions/api-keys.md +130 -0
  117. package/.framework/src/instructions/reference/functions/apps.md +140 -0
  118. package/.framework/src/instructions/reference/functions/auth.md +99 -0
  119. package/.framework/src/instructions/reference/functions/debug-auth.md +91 -0
  120. package/.framework/src/instructions/reference/functions/deliveries.md +110 -0
  121. package/.framework/src/instructions/reference/functions/embeddings.md +166 -0
  122. package/.framework/src/instructions/reference/functions/eval-harness.md +149 -0
  123. package/.framework/src/instructions/reference/functions/index.md +103 -0
  124. package/.framework/src/instructions/reference/functions/integration-outbound.md +200 -0
  125. package/.framework/src/instructions/reference/functions/integration-routes.md +151 -0
  126. package/.framework/src/instructions/reference/functions/integrations.md +130 -0
  127. package/.framework/src/instructions/reference/functions/invites.md +182 -0
  128. package/.framework/src/instructions/reference/functions/item-progress.md +107 -0
  129. package/.framework/src/instructions/reference/functions/kb.md +166 -0
  130. package/.framework/src/instructions/reference/functions/logs.md +141 -0
  131. package/.framework/src/instructions/reference/functions/observability.md +105 -0
  132. package/.framework/src/instructions/reference/functions/pipeline-executions.md +132 -0
  133. package/.framework/src/instructions/reference/functions/pipeline-runner-background.md +121 -0
  134. package/.framework/src/instructions/reference/functions/pipelines.md +136 -0
  135. package/.framework/src/instructions/reference/functions/prompt-configs.md +121 -0
  136. package/.framework/src/instructions/reference/functions/roles.md +121 -0
  137. package/.framework/src/instructions/reference/functions/security.md +140 -0
  138. package/.framework/src/instructions/reference/functions/system-cron.md +136 -0
  139. package/.framework/src/instructions/reference/functions/system.md +106 -0
  140. package/.framework/src/instructions/reference/functions/tests.md +97 -0
  141. package/.framework/src/instructions/reference/functions/timers.md +117 -0
  142. package/.framework/src/instructions/reference/functions/trigger-scheduler.md +102 -0
  143. package/.framework/src/instructions/reference/functions/triggers.md +140 -0
  144. package/.framework/src/instructions/reference/functions/types.md +146 -0
  145. package/.framework/src/instructions/reference/seeds.md +126 -0
  146. package/.framework/src/instructions/reference/shared-modules.md +127 -0
  147. package/.framework/src/instructions/reference/spine-config.md +114 -0
  148. package/.framework/src/instructions/roles.md +80 -0
  149. package/.framework/src/instructions/runtime-detail.md +70 -0
  150. package/.framework/src/instructions/runtime-list.md +77 -0
  151. package/.framework/src/instructions/security.md +67 -0
  152. package/.framework/src/instructions/tasks/add-a-pipeline.md +110 -0
  153. package/.framework/src/instructions/tasks/add-a-role.md +96 -0
  154. package/.framework/src/instructions/tasks/add-a-timer.md +114 -0
  155. package/.framework/src/instructions/tasks/add-a-trigger.md +106 -0
  156. package/.framework/src/instructions/tasks/add-a-type.md +151 -0
  157. package/.framework/src/instructions/tasks/add-a-webhook.md +108 -0
  158. package/.framework/src/instructions/tasks/add-an-ai-agent.md +108 -0
  159. package/.framework/src/instructions/tasks/add-an-integration.md +124 -0
  160. package/.framework/src/instructions/tasks/build-a-custom-page.md +118 -0
  161. package/.framework/src/instructions/tasks/package-and-install-an-app.md +127 -0
  162. package/.framework/src/instructions/tasks/test-your-code.md +108 -0
  163. package/.framework/src/instructions/tasks/write-a-function.md +132 -0
  164. package/.framework/src/instructions/tasks/write-a-migration.md +110 -0
  165. package/.framework/src/instructions/testing.md +59 -0
  166. package/.framework/src/instructions/timers.md +82 -0
  167. package/.framework/src/instructions/triggers.md +69 -0
  168. package/.framework/src/instructions/types.md +93 -0
  169. package/.framework/src/pages/NotFoundPage.tsx +62 -31
  170. package/.framework/src/pages/admin/AIAgentDetailPage.tsx +117 -106
  171. package/.framework/src/pages/admin/AIAgentsPage.tsx +86 -48
  172. package/.framework/src/pages/admin/APIKeyDetailPage.tsx +153 -152
  173. package/.framework/src/pages/admin/APIKeysPage.tsx +91 -90
  174. package/.framework/src/pages/admin/AlertsConfigPage.tsx +29 -18
  175. package/.framework/src/pages/admin/AppDetailPage.tsx +6 -60
  176. package/.framework/src/pages/admin/AppsPage.tsx +104 -66
  177. package/.framework/src/pages/admin/DeliveriesPage.tsx +5 -5
  178. package/.framework/src/pages/admin/EmbeddingDetailPage.tsx +5 -23
  179. package/.framework/src/pages/admin/EmbeddingsPage.tsx +5 -26
  180. package/.framework/src/pages/admin/IntegrationDetailPage.tsx +7 -7
  181. package/.framework/src/pages/admin/IntegrationsPage.tsx +85 -43
  182. package/.framework/src/pages/admin/LogsPage.tsx +144 -76
  183. package/.framework/src/pages/admin/ObservabilityDashboard.tsx +223 -140
  184. package/.framework/src/pages/admin/PipelineDetailPage.tsx +134 -113
  185. package/.framework/src/pages/admin/PipelineExecutionsPage.tsx +108 -45
  186. package/.framework/src/pages/admin/PipelinesPage.tsx +160 -115
  187. package/.framework/src/pages/admin/PromptConfigDetailPage.tsx +96 -98
  188. package/.framework/src/pages/admin/PromptConfigsPage.tsx +101 -59
  189. package/.framework/src/pages/admin/RoleDetailPage.tsx +90 -79
  190. package/.framework/src/pages/admin/RolesPage.tsx +86 -43
  191. package/.framework/src/pages/admin/SecurityPage.tsx +1 -1
  192. package/.framework/src/pages/admin/TestingDashboard.tsx +16 -28
  193. package/.framework/src/pages/admin/TimerDetailPage.tsx +117 -100
  194. package/.framework/src/pages/admin/TimersPage.tsx +90 -62
  195. package/.framework/src/pages/admin/TriggerDetailPage.tsx +90 -83
  196. package/.framework/src/pages/admin/TriggersPage.tsx +124 -99
  197. package/.framework/src/pages/admin/TypeDetailPage.tsx +152 -138
  198. package/.framework/src/pages/admin/TypesPage.tsx +90 -48
  199. package/.framework/src/pages/admin/cil/CILAgentPage.tsx +17 -25
  200. package/.framework/src/pages/admin/cil/CILChunkDetailPage.tsx +17 -27
  201. package/.framework/src/pages/admin/cil/CILDashboardPage.tsx +72 -40
  202. package/.framework/src/pages/admin/cil/CILFileListPage.tsx +321 -129
  203. package/.framework/src/pages/admin/cil/CILFileSelectPage.tsx +18 -29
  204. package/.framework/src/pages/admin/cil/CILGraphPage.tsx +26 -38
  205. package/.framework/src/pages/admin/cil/CILIngestionPage.tsx +34 -46
  206. package/.framework/src/pages/admin/cil/CILProjectsPage.tsx +189 -103
  207. package/.framework/src/pages/admin/cil/CILSearchPage.tsx +246 -136
  208. package/.framework/src/pages/admin/cil/CILSuggestionsPage.tsx +11 -22
  209. package/.framework/src/pages/admin/cil/CILVersionsPage.tsx +9 -20
  210. package/.framework/src/pages/admin/cil/FlexiblePipelinePage.tsx +26 -38
  211. package/.framework/src/pages/admin/kb/KBAdminPage.tsx +7 -26
  212. package/.framework/templates/agent/AGENTS.md +150 -0
  213. package/.framework/templates/agent/skills/spine-add-ai-agent/SKILL.md +58 -0
  214. package/.framework/templates/agent/skills/spine-add-automation/SKILL.md +62 -0
  215. package/.framework/templates/agent/skills/spine-add-integration/SKILL.md +63 -0
  216. package/.framework/templates/agent/skills/spine-architect/SKILL.md +86 -0
  217. package/.framework/templates/agent/skills/spine-install-app/SKILL.md +72 -0
  218. package/.framework/templates/agent/skills/spine-migration/SKILL.md +75 -0
  219. package/.framework/templates/agent/skills/spine-new-app/SKILL.md +67 -0
  220. package/.framework/templates/agent/skills/spine-new-function/SKILL.md +65 -0
  221. package/.framework/templates/agent/skills/spine-new-type/SKILL.md +65 -0
  222. package/.framework/templates/agent/skills/spine-schema/SKILL.md +77 -0
  223. package/.framework/templates/agent/skills/spine-test/SKILL.md +67 -0
  224. package/.framework/templates/agent/skills/spine-troubleshoot/SKILL.md +74 -0
  225. package/.framework/templates/agent/skills/spine-upgrade/SKILL.md +69 -0
  226. package/.framework/templates/project.json +4 -1
  227. package/.framework/tests/unit/account-scoping-gates.test.ts +392 -0
  228. package/.framework/tests/unit/agent-files.test.ts +355 -0
  229. package/.framework/tests/unit/agent-runner.test.ts +479 -44
  230. package/.framework/tests/unit/api-keys-create-scope-gate.test.ts +160 -0
  231. package/.framework/tests/unit/api-keys-omit-secret-fields.test.ts +38 -0
  232. package/.framework/tests/unit/bootstrap.test.ts +242 -0
  233. package/.framework/tests/unit/cli-context-api-key.test.ts +114 -0
  234. package/.framework/tests/unit/debug-auth.test.ts +38 -0
  235. package/.framework/tests/unit/deliveries-account-scoping.test.ts +185 -0
  236. package/.framework/tests/unit/integration-outbound-credentials.test.ts +167 -0
  237. package/.framework/tests/unit/integrations-audit-redaction.test.ts +130 -0
  238. package/.framework/tests/unit/logging-app-id.test.ts +75 -0
  239. package/.framework/tests/unit/system-context-denial.test.ts +145 -0
  240. package/.framework/tests/unit/system-cron.test.ts +240 -0
  241. package/.framework/tests/unit/timers.test.ts +159 -0
  242. package/README.md +125 -166
  243. package/config/tsconfig.cli.json +2 -2
  244. package/package.json +15 -4
  245. package/templates/project/package-lock.json +2 -2
  246. package/.framework/docs/admin-routes.md +0 -76
  247. package/.framework/docs/api-docs-progress.md +0 -38
  248. package/.framework/docs/api-governance.md +0 -146
  249. package/.framework/docs/api-testing-results.md +0 -212
  250. package/.framework/docs/assembly-launch-guide.md +0 -138
  251. package/.framework/docs/audit-results.md +0 -590
  252. package/.framework/docs/db-api-inventory.md +0 -95
  253. package/.framework/docs/gap-remediation-backlog.md +0 -103
  254. package/.framework/docs/ui-adoption-verification.md +0 -111
  255. package/.framework/docs/ui-api-coverage.md +0 -84
  256. package/.framework/docs/v2-compatibility-audit.md +0 -228
  257. package/.framework/mcp/index.ts +0 -133
  258. package/.framework/mcp/load-env.ts +0 -60
  259. package/.framework/mcp/shared/app-manifest.ts +0 -275
  260. package/.framework/mcp/shared/db.ts +0 -477
  261. package/.framework/mcp/shared/kb.ts +0 -118
  262. package/.framework/mcp/tools/architect.ts +0 -431
  263. package/.framework/mcp/tools/cil/context.ts +0 -345
  264. package/.framework/mcp/tools/cil/graph.ts +0 -242
  265. package/.framework/mcp/tools/cil/ingest.ts +0 -1217
  266. package/.framework/mcp/tools/cil/pipeline-orchestrator.ts +0 -693
  267. package/.framework/mcp/tools/cil/pipeline.ts +0 -767
  268. package/.framework/mcp/tools/cil/project.ts +0 -791
  269. package/.framework/mcp/tools/cil/retrieval.ts +0 -336
  270. package/.framework/mcp/tools/cil/search-core.ts +0 -454
  271. package/.framework/mcp/tools/cil/search.ts +0 -97
  272. package/.framework/mcp/tools/cil/suggest.ts +0 -186
  273. package/.framework/mcp/tools/cil/validate.ts +0 -1369
  274. package/.framework/mcp/tools/kb/delete.ts +0 -139
  275. package/.framework/mcp/tools/kb/index.ts +0 -52
  276. package/.framework/mcp/tools/kb/ingest.ts +0 -84
  277. package/.framework/mcp/tools/kb/list-types.ts +0 -102
  278. package/.framework/mcp/tools/kb/publish.ts +0 -100
  279. package/.framework/mcp/tools/kb/reindex.ts +0 -86
  280. package/.framework/mcp/tools/kb/revoke.ts +0 -85
  281. package/.framework/mcp/tools/kb/search.ts +0 -101
  282. package/.framework/mcp/tools/kb/upsert.ts +0 -125
  283. package/.framework/mcp/tools/observability.ts +0 -510
@@ -1,12 +1,28 @@
1
1
  // CIL[BEGIN stable_id="~/.framework/src/pages/admin/RoleDetailPage.tsx:module_header:module_header" type="module_header" identity="module_header" parent="~/.framework/src/pages/admin/RoleDetailPage.tsx"]
2
- // CIL[DOC-MACRO purpose="Provides module-level imports and context for the admin role detail page."]
3
- // CIL[DOC-RESPONSIBILITY responsibility="Load React, routing, UI primitives, hooks, and utilities used by RoleDetailPage."]
4
- // CIL[DOC-CONTEXT module="admin" layer="page" related_files=".framework/src/components/admin/PageInstructions.tsx,.framework/src/components/ui/alert.tsx,.framework/src/components/ui/button.tsx,.framework/src/components/ui/card.tsx,.framework/src/components/ui/checkbox.tsx,.framework/src/components/ui/input.tsx,.framework/src/components/ui/label.tsx,.framework/src/components/ui/skeleton.tsx,.framework/src/components/ui/textarea.tsx,.framework/src/hooks/useApi.ts,.framework/src/lib/api.ts,.framework/src/lib/utils.ts"]
5
- // CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
6
- // CIL[DOC-MICRO logic_summary="Imports dependencies for the role detail page." notable_decisions="[]"]
7
- // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
8
- // CIL[DOC-STABILITY stability="stable"]
9
- // CIL[DOC-AUDIENCE audience="admin-frontend"]
2
+ /**
3
+ * @module RoleDetailPage
4
+ * @audience internal
5
+ * @layer app-specific
6
+ * @stability stable
7
+ *
8
+ * RoleDetailPage is a React component that manages the display and editing of role details within the admin interface. It interacts with the API to fetch and update role information based on the role ID obtained from the URL parameters. INVARIANT: The role ID must always be present in the URL for the component to function correctly.
9
+ *
10
+ * @seeAlso useApi (provides API interaction hooks).
11
+ * @seeAlso apiFetch (handles API requests).
12
+ * @seeAlso formatDateTime (formats date and time for display).
13
+ * @seeAlso PageInstructions (provides instructional content for the admin page).
14
+ *
15
+ * @cil-generated
16
+ */
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+
25
+
10
26
 
11
27
  import { useState, useEffect } from 'react'
12
28
  import { useParams, useNavigate } from 'react-router-dom'
@@ -22,23 +38,31 @@ import { ArrowLeft, ShieldCheck, AlertCircle } from 'lucide-react'
22
38
  import { useApi } from '../../hooks/useApi'
23
39
  import { apiFetch } from '../../lib/api'
24
40
  import { formatDateTime } from '../../lib/utils'
25
- import { PageInstructions } from '../../components/admin/PageInstructions'
26
-
27
- // CIL[DOC-VECTOR type="context" content="purpose='Provides module-level imports and context for the admin role detail page.'; No verified external callers; imports: .framework/src/components/ui/button.tsx,.framework/src/components/ui/input.tsx,.framework/src/components/ui/textarea.tsx"]
28
- // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
29
- // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
30
- // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
31
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
32
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
33
41
  // CIL[END stable_id="~/.framework/src/pages/admin/RoleDetailPage.tsx:module_header:module_header"]
42
+
43
+
44
+
45
+
46
+
47
+
48
+
49
+
50
+
51
+
52
+
53
+
54
+
55
+
56
+
57
+
34
58
  // CIL[BEGIN stable_id="~/.framework/src/pages/admin/RoleDetailPage.tsx:Role:interface" type="interface" identity="Role" parent="~/.framework/src/pages/admin/RoleDetailPage.tsx"]
35
- // CIL[DOC-MACRO purpose="Defines the TypeScript shape of a Role record used in the admin UI."]
36
- // CIL[DOC-RESPONSIBILITY responsibility="Provide a typed contract for role data, permissions, and metadata."]
37
- // CIL[DOC-CONTEXT module="admin" layer="domain" related_files=".framework/src/components/admin/PageInstructions.tsx,.framework/src/components/ui/alert.tsx,.framework/src/components/ui/button.tsx,.framework/src/components/ui/card.tsx,.framework/src/components/ui/checkbox.tsx,.framework/src/components/ui/input.tsx,.framework/src/components/ui/label.tsx,.framework/src/components/ui/skeleton.tsx,.framework/src/components/ui/textarea.tsx,.framework/src/hooks/useApi.ts,.framework/src/lib/api.ts,.framework/src/lib/utils.ts,.framework/src/pages/admin/RoleDetailPage.tsx"]
38
- // CIL[DOC-CONTRACT inputs="none" outputs="Role type definition" errors="none" side_effects="none"]
39
- // CIL[DOC-MICRO logic_summary="Declares the Role interface fields consumed by the detail page and API." notable_decisions="[]"]
40
- // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
41
- // CIL[DOC-STABILITY stability="stable"]
59
+ /**
60
+ * The Role interface defines the structure of a role object used in the admin panel, encapsulating essential attributes and permissions associated with a role. It exists to standardize role management within the application.
61
+ *
62
+ * @sideEffects none
63
+ * @stability stable
64
+ * @cil-generated
65
+ */
42
66
  interface Role {
43
67
  id: string
44
68
  name: string
@@ -51,22 +75,37 @@ interface Role {
51
75
  created_at: string
52
76
  updated_at: string
53
77
  }
54
- // CIL[DOC-VECTOR type="context" content="purpose='Defines the TypeScript shape of a Role record used in the admin UI.'; No verified external callers; imports: .framework/src/components/ui/button.tsx,.framework/src/components/ui/input.tsx,.framework/src/components/ui/textarea.tsx"]
55
- // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
56
- // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
57
- // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
58
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
59
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
60
78
  // CIL[END stable_id="~/.framework/src/pages/admin/RoleDetailPage.tsx:Role:interface"]
61
79
 
80
+
81
+
82
+
83
+
84
+
85
+
86
+
87
+
88
+
89
+
90
+
91
+
92
+
93
+
94
+
62
95
  // CIL[BEGIN stable_id="~/.framework/src/pages/admin/RoleDetailPage.tsx:RoleDetailPage:component" type="component" identity="RoleDetailPage" parent="~/.framework/src/pages/admin/RoleDetailPage.tsx"]
63
- // CIL[DOC-MACRO purpose="Renders a create/edit form for admin roles and their permissions."]
64
- // CIL[DOC-RESPONSIBILITY responsibility="Fetch role data, manage form state, validate permissions JSON, submit to the API, and render the admin UI."]
65
- // CIL[DOC-CONTEXT module="admin" layer="page" related_files=".framework/src/components/admin/PageInstructions.tsx,.framework/src/components/ui/alert.tsx,.framework/src/components/ui/button.tsx,.framework/src/components/ui/card.tsx,.framework/src/components/ui/checkbox.tsx,.framework/src/components/ui/input.tsx,.framework/src/components/ui/label.tsx,.framework/src/components/ui/skeleton.tsx,.framework/src/components/ui/textarea.tsx,.framework/src/hooks/useApi.ts,.framework/src/lib/api.ts,.framework/src/lib/utils.ts,.framework/src/pages/admin/RoleDetailPage.tsx"]
66
- // CIL[DOC-CONTRACT inputs="URL id parameter ('new' or existing role), role data from /api/roles, user input" outputs="Rendered role form, navigation after save" errors="fetchError, save error, invalid permissions JSON" side_effects="Calls /api/roles (POST or PATCH) and navigates on success"]
67
- // CIL[DOC-MICRO logic_summary="Initializes form from fetched role, parses permissions JSON, handles create/update submission, and renders instructions, alerts, and fields." notable_decisions="[]"]
68
- // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
69
- // CIL[DOC-STABILITY stability="stable"]
96
+ /**
97
+ * The RoleDetailPage component manages the creation and editing of role details in an admin interface. It fetches role data if editing an existing role and handles form submission for creating or updating roles.
98
+ *
99
+ * @macro Component responsible for role management in an admin interface.
100
+ * @micro Utilizes React hooks for state management and API calls to handle role data.
101
+ * @outputSpec JSX.Element
102
+ * @throws Error — Invalid JSON in permissions field, Error — Failed to fetch role, Error — Failed to save role
103
+ * @sideEffects API calls to fetch and save role data.
104
+ * @stability stable
105
+ * @calls useParams, useNavigate, useApi, apiFetch
106
+ * @errorHandling Catches and sets error messages for invalid JSON and API response failures.
107
+ * @cil-generated
108
+ */
70
109
  export function RoleDetailPage() {
71
110
  const { id } = useParams<{ id: string }>()
72
111
  const navigate = useNavigate()
@@ -186,43 +225,6 @@ export function RoleDetailPage() {
186
225
  {isCreateMode ? 'Create Role' : role?.name || 'Role Detail'}
187
226
  </h1>
188
227
  </div>
189
-
190
- <PageInstructions
191
- description="Define a role and set its permissions and metadata."
192
- sections={[
193
- { title: 'What this role controls', content: 'A role is a named permission set assigned to people. It controls which record types a person can create, read, update, delete, or admin, and whether the role can be assigned in the first place.' },
194
- { title: 'Fields explained', content: <ul className="list-disc pl-4 space-y-1">
195
- <li><strong>Name</strong> — string, required. The display label such as Sales Manager. Empty name blocks save.</li>
196
- <li><strong>Slug</strong> — string, required. A unique URL-friendly identifier. Disabled after creation because permissions and references depend on it.</li>
197
- <li><strong>Description</strong> — string. Optional context for other admins.</li>
198
- <li><strong>System Role</strong> — checkbox, create-only. Marks a reserved role that cannot be deleted and is protected for core functions.</li>
199
- <li><strong>Active</strong> — checkbox. Inactive roles cannot be assigned to people.</li>
200
- <li><strong>Permissions (JSON)</strong> — JSON. Maps type slugs to arrays of allowed actions. Invalid JSON or wrong shape will cause save to fail.</li>
201
- </ul> },
202
- { title: 'Options and values', content: <ul className="list-disc pl-4 space-y-1">
203
- <li><strong>Actions per type</strong>: typical values are create, read, update, delete, and admin. Use the array format with a type slug mapped to an array: type_slug: ["read", "write"].</li>
204
- <li><strong>System Role</strong>: can only be set during creation and prevents deletion later.</li>
205
- </ul> },
206
- { title: 'Downstream impact', content: <ul className="list-disc pl-4 space-y-1">
207
- <li>People assigned to this role receive the effective permissions immediately after the role is saved.</li>
208
- <li>The admin-data API and runtime record UIs evaluate the role permissions for every create, read, update, and delete request.</li>
209
- <li>Missing or malformed permissions can lock people out of records or grant unintended access.</li>
210
- </ul> },
211
- { title: 'How to create, save, and validate', content: <ol className="list-decimal pl-4 space-y-1">
212
- <li>In create mode, enter Name and Slug, then set Active and optionally System. Existing roles cannot change the slug.</li>
213
-
214
-
215
- <li>Enter valid Permissions JSON mapping type slugs to action arrays.</li>
216
- <li>Click Create Role or Update Role. Save fails if the name/slug are empty, the slug is changed, or the permissions JSON cannot be parsed.</li>
217
- </ol> },
218
- { title: 'Common mistakes', content: <ul className="list-disc pl-4 space-y-1">
219
- <li>Writing permissions as a flat list instead of an object of arrays.</li>
220
- <li>Trying to change the slug after creation, which is disabled and will be ignored.</li>
221
- <li>Forgetting to mark a role Active, which prevents assignment.</li>
222
- </ul> },
223
- ]}
224
- />
225
-
226
228
  {error && (
227
229
  <Alert variant="destructive">
228
230
  <AlertCircle className="h-4 w-4" />
@@ -323,6 +325,14 @@ export function RoleDetailPage() {
323
325
  placeholder={`{\n "item": ["read", "write"],\n "account": ["read"]\n}`}
324
326
  rows={10}
325
327
  />
328
+ {(() => {
329
+ try {
330
+ JSON.parse(permissionsJson)
331
+ return null
332
+ } catch (err) {
333
+ return <p className="text-xs text-red-600 mt-2">Invalid JSON: {(err as Error).message}</p>
334
+ }
335
+ })()}
326
336
  <p className="text-xs text-muted-foreground mt-2">
327
337
  Example: <code className="bg-muted px-1 py-0.5 rounded">{`{"ticket": ["read", "write", "admin"]}`}</code>
328
338
  </p>
@@ -341,10 +351,11 @@ export function RoleDetailPage() {
341
351
  </div>
342
352
  )
343
353
  }
344
- // CIL[DOC-VECTOR type="context" content="purpose='Renders a create/edit form for admin roles and their permissions.'; No verified external callers; imports: .framework/src/components/ui/button.tsx,.framework/src/components/ui/input.tsx,.framework/src/components/ui/textarea.tsx"]
345
- // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
346
- // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
347
- // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
348
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
349
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
350
354
  // CIL[END stable_id="~/.framework/src/pages/admin/RoleDetailPage.tsx:RoleDetailPage:component"]
355
+
356
+
357
+
358
+
359
+
360
+
361
+
@@ -1,18 +1,36 @@
1
1
  // CIL[BEGIN stable_id="~/.framework/src/pages/admin/RolesPage.tsx:module_header:module_header" type="module_header" identity="module_header" parent="~/.framework/src/pages/admin/RolesPage.tsx"]
2
- // CIL[DOC-MACRO purpose="Admin roles management page module: defines the Role interface and the RolesPage React component for listing, searching, filtering, and sorting roles."]
3
- // CIL[DOC-RESPONSIBILITY responsibility="Provide the top-level TypeScript module exports and role model shape consumed by the admin roles UI."]
4
- // CIL[DOC-CONTEXT module="admin" layer="pages" related_files=".framework/src/components/admin/AdminListPage.tsx,.framework/src/components/admin/SortableTableHeader.tsx,.framework/src/components/ui/LoadingSpinner.tsx,.framework/src/components/ui/button.tsx,.framework/src/hooks/useApi.ts,.framework/src/lib/api.ts,.framework/src/lib/utils.ts"]
5
- // CIL[DOC-CONTRACT inputs="module imports and role API response data" outputs="Role interface and RolesPage React component" errors="Network or API errors are surfaced by useApi hook" side_effects="none at module scope"]
6
- // CIL[DOC-MICRO logic_summary="Imports React, hooks, shared components, and utilities; exports Role type and RolesPage component for rendering the admin roles list." notable_decisions="[]"]
7
- // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
8
- // CIL[DOC-STABILITY stability="stable"]
9
- // CIL[DOC-AUDIENCE audience="admin-frontend"]
2
+ /**
3
+ * @module RolesPage
4
+ * @audience both
5
+ * @layer shared-core
6
+ * @stability stable
7
+ *
8
+ * The RolesPage module provides an interface for managing user roles within the admin panel of the application. It allows administrators to view, add, and modify roles, leveraging various UI components for a seamless experience.
9
+ * INVARIANT: The user must have admin privileges to access this page.
10
+ *
11
+ * @seeAlso AdminListPage (provides the list view for admin roles).
12
+ * @seeAlso LoadingSpinner (indicates loading states during API calls).
13
+ * @seeAlso useApi (custom hook for API interactions).
14
+ * @seeAlso SortableTableHeader (enables sorting functionality in tables).
15
+ *
16
+ * @cil-generated
17
+ */
18
+
19
+
20
+
21
+
22
+
23
+
24
+
25
+
26
+
10
27
 
11
28
 
12
29
 
13
30
 
14
31
 
15
32
  import React, { useState } from 'react'
33
+ import { useNavigate } from 'react-router-dom'
16
34
  import { Plus, ShieldCheck, CheckCircle, XCircle, Settings, FileText, Cog } from 'lucide-react';
17
35
  import { LoadingSpinner } from '../../components/ui/LoadingSpinner'
18
36
  import { Button } from '../../components/ui/button'
@@ -21,23 +39,32 @@ import { SortableTableHeader } from '../../components/admin/SortableTableHeader'
21
39
  import { formatDateTime } from '../../lib/utils'
22
40
  import { useApi } from '../../hooks/useApi'
23
41
  import { apiFetch } from '../../lib/api'
42
+ // CIL[END stable_id="~/.framework/src/pages/admin/RolesPage.tsx:module_header:module_header"]
43
+
44
+
45
+
46
+
47
+
48
+
49
+
50
+
51
+
52
+
53
+
54
+
55
+
56
+
57
+
24
58
 
25
59
 
26
- // CIL[DOC-VECTOR type="context" content="purpose='Admin roles management page module: defines the Role interface and the RolesPage React component for listing, searching, filtering, and sorting roles.'; No verified external callers; imports: .framework/src/components/ui/LoadingSpinner.tsx,.framework/src/components/ui/button.tsx,.framework/src/components/admin/AdminListPage.tsx"]
27
- // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
28
- // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
29
- // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
30
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
31
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
32
- // CIL[END stable_id="~/.framework/src/pages/admin/RolesPage.tsx:module_header:module_header"]
33
60
  // CIL[BEGIN stable_id="~/.framework/src/pages/admin/RolesPage.tsx:Role:interface" type="interface" identity="Role" parent="~/.framework/src/pages/admin/RolesPage.tsx"]
34
- // CIL[DOC-MACRO purpose="Define the shape of a role record for use in the admin roles list and related operations."]
35
- // CIL[DOC-RESPONSIBILITY responsibility="Declare the TypeScript interface for role objects returned by the roles API."]
36
- // CIL[DOC-CONTEXT module="admin" layer="types" related_files=".framework/src/components/admin/AdminListPage.tsx,.framework/src/components/admin/SortableTableHeader.tsx,.framework/src/components/ui/LoadingSpinner.tsx,.framework/src/components/ui/button.tsx,.framework/src/hooks/useApi.ts,.framework/src/lib/api.ts,.framework/src/lib/utils.ts,.framework/src/pages/admin/RolesPage.tsx"]
37
- // CIL[DOC-CONTRACT inputs="none" outputs="Role interface type definition" errors="none" side_effects="none"]
38
- // CIL[DOC-MICRO logic_summary="Typed interface with required and optional fields representing a role, its permissions, app association, and audit timestamps." notable_decisions="[]"]
39
- // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
40
- // CIL[DOC-STABILITY stability="stable"]
61
+ /**
62
+ * The Role interface defines the structure of a role object used in the admin panel for managing user roles and permissions. It encapsulates essential attributes such as identification, status, and metadata related to roles within the application.
63
+ *
64
+ * @sideEffects none
65
+ * @stability internal
66
+ * @cil-generated
67
+ */
41
68
  interface Role {
42
69
  id: string
43
70
  name: string
@@ -51,23 +78,39 @@ interface Role {
51
78
  created_at: string
52
79
  updated_at: string
53
80
  }
54
- // CIL[DOC-VECTOR type="context" content="purpose='Define the shape of a role record for use in the admin roles list and related operations.'; No verified external callers; imports: .framework/src/components/ui/LoadingSpinner.tsx,.framework/src/components/ui/button.tsx,.framework/src/components/admin/AdminListPage.tsx"]
55
- // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
56
- // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
57
- // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
58
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
59
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
60
81
  // CIL[END stable_id="~/.framework/src/pages/admin/RolesPage.tsx:Role:interface"]
61
82
 
83
+
84
+
85
+
86
+
87
+
88
+
89
+
90
+
91
+
92
+
93
+
94
+
95
+
96
+
97
+
62
98
  // CIL[BEGIN stable_id="~/.framework/src/pages/admin/RolesPage.tsx:RolesPage:component" type="component" identity="RolesPage" parent="~/.framework/src/pages/admin/RolesPage.tsx"]
63
- // CIL[DOC-MACRO purpose="Render the admin roles list page with search, filters, sorting, stats, and navigation to role detail."]
64
- // CIL[DOC-RESPONSIBILITY responsibility="Fetch and display roles; handle search, status/type filters, column sorting, row navigation, and summary statistics."]
65
- // CIL[DOC-CONTEXT module="admin" layer="pages" related_files=".framework/src/components/admin/AdminListPage.tsx,.framework/src/components/admin/SortableTableHeader.tsx,.framework/src/components/ui/LoadingSpinner.tsx,.framework/src/components/ui/button.tsx,.framework/src/hooks/useApi.ts,.framework/src/lib/api.ts,.framework/src/lib/utils.ts,.framework/src/pages/admin/RolesPage.tsx"]
66
- // CIL[DOC-CONTRACT inputs="none (internal state and useApi fetch)" outputs="JSX admin list page for roles" errors="API fetch error passed to AdminListPage; boolean sort fallback for permissions" side_effects="Navigates to /spine-framework/admin/configs/roles/:id on row click; uses window.location.href"]
67
- // CIL[DOC-MICRO logic_summary="Uses useApi to load roles, applies search/status/type filters, sorts by selected column, computes stats cards, and renders an AdminListPage with a sortable table and clickable rows." notable_decisions="[]"]
68
- // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
69
- // CIL[DOC-STABILITY stability="stable"]
99
+ /**
100
+ * The RolesPage component manages the display and filtering of user roles in the admin interface. It provides functionality for searching, sorting, and navigating to role details.
101
+ *
102
+ * @macro Component responsible for rendering and managing roles in an admin dashboard.
103
+ * @micro Utilizes state management and API calls to filter and sort roles based on user input.
104
+ * @outputSpec JSX.Element — renders a UI for managing roles.
105
+ * @throws Error — if the API call fails
106
+ * @sideEffects API call to '/api/roles?action=list' to fetch roles.
107
+ * @stability internal
108
+ * @calls useApi, apiFetch, useNavigate
109
+ * @errorHandling throws an error if the API call fails.
110
+ * @cil-generated
111
+ */
70
112
  export function RolesPage() {
113
+ const navigate = useNavigate()
71
114
  const [searchTerm, setSearchTerm] = useState('')
72
115
  const [selectedStatus, setSelectedStatus] = useState('all')
73
116
  const [selectedType, setSelectedType] = useState('all')
@@ -119,7 +162,7 @@ export function RolesPage() {
119
162
  }
120
163
 
121
164
  const handleRowClick = (role: Role) => {
122
- window.location.href = `/spine-framework/admin/configs/roles/${role.id}`
165
+ navigate(`/spine-framework/admin/configs/roles/${role.id}`)
123
166
  }
124
167
 
125
168
  const sortedRoles = [...(filteredRoles || [])].sort((a, b) => {
@@ -319,10 +362,10 @@ export function RolesPage() {
319
362
  </AdminListPage>
320
363
  )
321
364
  }
322
- // CIL[DOC-VECTOR type="context" content="purpose='Render the admin roles list page with search, filters, sorting, stats, and navigation to role detail.'; No verified external callers; imports: .framework/src/components/ui/LoadingSpinner.tsx,.framework/src/components/ui/button.tsx,.framework/src/components/admin/AdminListPage.tsx"]
323
- // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
324
- // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
325
- // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
326
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
327
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
328
- // CIL[END stable_id="~/.framework/src/pages/admin/RolesPage.tsx:RolesPage:component"]
365
+ // CIL[END stable_id="~/.framework/src/pages/admin/RolesPage.tsx:RolesPage:component"]
366
+
367
+
368
+
369
+
370
+
371
+
@@ -55,7 +55,7 @@ async function callSecurity(action: string, body?: any) {
55
55
  })
56
56
  const data = await res.json().catch(() => ({}))
57
57
  if (!res.ok) throw new Error(data?.error || data?.message || `${action} failed (${res.status})`)
58
- return data
58
+ return data?.data ?? data
59
59
  }
60
60
 
61
61
  export function SecurityPage() {
@@ -28,7 +28,7 @@ import { AgentView } from '../../components/shared/AgentView'
28
28
  import { FlaskConical, CheckCircle, XCircle, Clock, RefreshCw } from 'lucide-react';
29
29
  import { LoadingSpinner } from '../../components/ui/LoadingSpinner'
30
30
  import { formatDateTime } from '../../lib/utils'
31
- import { PageInstructions } from '../../components/admin/PageInstructions'
31
+ // CIL[END stable_id="~/.framework/src/pages/admin/TestingDashboard.tsx:module_header:module_header"]
32
32
 
33
33
  // CIL[DOC-VECTOR type="context" content="purpose='Admin test suite dashboard page module header'; No verified external callers; imports: .framework/src/hooks/useApi.ts,.framework/src/lib/api.ts,.framework/src/components/shared/AgentView.tsx"]
34
34
  // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
@@ -36,8 +36,6 @@ import { PageInstructions } from '../../components/admin/PageInstructions'
36
36
  // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
37
37
  // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
38
38
  // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
39
- // CIL[END stable_id="~/.framework/src/pages/admin/TestingDashboard.tsx:module_header:module_header"]
40
- // CIL[BEGIN stable_id="~/.framework/src/pages/admin/TestingDashboard.tsx:SuiteStat:interface" type="interface" identity="SuiteStat" parent="~/.framework/src/pages/admin/TestingDashboard.tsx"]
41
39
  // CIL[DOC-MACRO purpose="Type definition for suite statistics"]
42
40
  // CIL[DOC-RESPONSIBILITY responsibility="Describe the shape of aggregated test suite stats"]
43
41
  // CIL[DOC-CONTEXT module="TestingDashboard" layer="types" related_files=".framework/src/components/admin/PageInstructions.tsx,.framework/src/components/shared/AgentView.tsx,.framework/src/components/ui/LoadingSpinner.tsx,.framework/src/hooks/useApi.ts,.framework/src/lib/api.ts,.framework/src/lib/utils.ts,.framework/src/pages/admin/TestingDashboard.tsx"]
@@ -45,6 +43,7 @@ import { PageInstructions } from '../../components/admin/PageInstructions'
45
43
  // CIL[DOC-MICRO logic_summary="Record of suite, total_runs, last status, counts, and timestamps" notable_decisions="[]"]
46
44
  // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
47
45
  // CIL[DOC-STABILITY stability="stable"]
46
+ // CIL[BEGIN stable_id="~/.framework/src/pages/admin/TestingDashboard.tsx:SuiteStat:interface" type="interface" identity="SuiteStat" parent="~/.framework/src/pages/admin/TestingDashboard.tsx"]
48
47
  interface SuiteStat {
49
48
  suite: string
50
49
  total_runs: number
@@ -54,16 +53,15 @@ interface SuiteStat {
54
53
  last_failed: number | null
55
54
  last_total: number | null
56
55
  }
56
+ // CIL[END stable_id="~/.framework/src/pages/admin/TestingDashboard.tsx:SuiteStat:interface"]
57
57
  // CIL[DOC-VECTOR type="context" content="purpose='Type definition for suite statistics'; No verified external callers; imports: .framework/src/hooks/useApi.ts,.framework/src/lib/api.ts,.framework/src/components/shared/AgentView.tsx"]
58
58
  // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
59
59
  // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
60
60
  // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
61
61
  // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
62
62
  // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
63
- // CIL[END stable_id="~/.framework/src/pages/admin/TestingDashboard.tsx:SuiteStat:interface"]
64
63
 
65
64
 
66
- // CIL[BEGIN stable_id="~/.framework/src/pages/admin/TestingDashboard.tsx:TestRun:interface" type="interface" identity="TestRun" parent="~/.framework/src/pages/admin/TestingDashboard.tsx"]
67
65
  // CIL[DOC-MACRO purpose="Type definition for a test run record"]
68
66
  // CIL[DOC-RESPONSIBILITY responsibility="Describe the shape of an individual test run"]
69
67
  // CIL[DOC-CONTEXT module="TestingDashboard" layer="types" related_files=".framework/src/components/admin/PageInstructions.tsx,.framework/src/components/shared/AgentView.tsx,.framework/src/components/ui/LoadingSpinner.tsx,.framework/src/hooks/useApi.ts,.framework/src/lib/api.ts,.framework/src/lib/utils.ts,.framework/src/pages/admin/TestingDashboard.tsx"]
@@ -71,6 +69,7 @@ interface SuiteStat {
71
69
  // CIL[DOC-MICRO logic_summary="Record of id, suite, status, timing, counts, and trigger" notable_decisions="[]"]
72
70
  // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
73
71
  // CIL[DOC-STABILITY stability="stable"]
72
+ // CIL[BEGIN stable_id="~/.framework/src/pages/admin/TestingDashboard.tsx:TestRun:interface" type="interface" identity="TestRun" parent="~/.framework/src/pages/admin/TestingDashboard.tsx"]
74
73
  interface TestRun {
75
74
  id: string
76
75
  suite: string
@@ -84,14 +83,13 @@ interface TestRun {
84
83
  skipped: number | null
85
84
  triggered_by: string | null
86
85
  }
86
+ // CIL[END stable_id="~/.framework/src/pages/admin/TestingDashboard.tsx:TestRun:interface"]
87
87
  // CIL[DOC-VECTOR type="context" content="purpose='Type definition for a test run record'; No verified external callers; imports: .framework/src/hooks/useApi.ts,.framework/src/lib/api.ts,.framework/src/components/shared/AgentView.tsx"]
88
88
  // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
89
89
  // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
90
90
  // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
91
91
  // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
92
92
  // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
93
- // CIL[END stable_id="~/.framework/src/pages/admin/TestingDashboard.tsx:TestRun:interface"]
94
- // CIL[BEGIN stable_id="~/.framework/src/pages/admin/TestingDashboard.tsx:suite_labels:constant" type="constant" identity="SUITE_LABELS" parent="~/.framework/src/pages/admin/TestingDashboard.tsx"]
95
93
  // CIL[DOC-MACRO purpose="Human readable labels for test suite names"]
96
94
  // CIL[DOC-RESPONSIBILITY responsibility="Map suite slugs to display labels"]
97
95
  // CIL[DOC-CONTEXT module="TestingDashboard" layer="constants" related_files=".framework/src/components/admin/PageInstructions.tsx,.framework/src/components/shared/AgentView.tsx,.framework/src/components/ui/LoadingSpinner.tsx,.framework/src/hooks/useApi.ts,.framework/src/lib/api.ts,.framework/src/lib/utils.ts,.framework/src/pages/admin/TestingDashboard.tsx"]
@@ -99,26 +97,26 @@ interface TestRun {
99
97
  // CIL[DOC-MICRO logic_summary="Mapping of unit, integration, api, ui to display names" notable_decisions="[]"]
100
98
  // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
101
99
  // CIL[DOC-STABILITY stability="stable"]
100
+ // CIL[BEGIN stable_id="~/.framework/src/pages/admin/TestingDashboard.tsx:SUITE_LABELS:constant" type="constant" identity="SUITE_LABELS" parent="~/.framework/src/pages/admin/TestingDashboard.tsx"]
102
101
  const SUITE_LABELS: Record<string, string> = {
103
102
  unit: 'Unit',
104
103
  integration: 'Integration',
105
104
  api: 'API',
106
105
  ui: 'UI',
107
106
  }
107
+ // CIL[END stable_id="~/.framework/src/pages/admin/TestingDashboard.tsx:SUITE_LABELS:constant"]
108
108
  // CIL[DOC-VECTOR type="context" content="purpose='Human readable labels for test suite names'; No verified external callers; imports: .framework/src/hooks/useApi.ts,.framework/src/lib/api.ts,.framework/src/components/shared/AgentView.tsx"]
109
109
  // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
110
110
  // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
111
111
  // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
112
112
  // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
113
113
  // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
114
- // CIL[END stable_id="~/.framework/src/pages/admin/TestingDashboard.tsx:suite_labels:constant"]
115
114
 
116
115
 
117
116
 
118
117
 
119
118
 
120
119
 
121
- // CIL[BEGIN stable_id="~/.framework/src/pages/admin/TestingDashboard.tsx:StatusBadge:component" type="component" identity="StatusBadge" parent="~/.framework/src/pages/admin/TestingDashboard.tsx"]
122
120
  // CIL[DOC-MACRO purpose="Render a colored status badge"]
123
121
  // CIL[DOC-RESPONSIBILITY responsibility="Display a status string as a styled badge"]
124
122
  // CIL[DOC-CONTEXT module="TestingDashboard" layer="presentation" related_files=".framework/src/components/admin/PageInstructions.tsx,.framework/src/components/shared/AgentView.tsx,.framework/src/components/ui/LoadingSpinner.tsx,.framework/src/hooks/useApi.ts,.framework/src/lib/api.ts,.framework/src/lib/utils.ts,.framework/src/pages/admin/TestingDashboard.tsx"]
@@ -126,6 +124,7 @@ const SUITE_LABELS: Record<string, string> = {
126
124
  // CIL[DOC-MICRO logic_summary="Selects Tailwind color classes based on status and renders text" notable_decisions="[]"]
127
125
  // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
128
126
  // CIL[DOC-STABILITY stability="stable"]
127
+ // CIL[BEGIN stable_id="~/.framework/src/pages/admin/TestingDashboard.tsx:StatusBadge:component" type="component" identity="StatusBadge" parent="~/.framework/src/pages/admin/TestingDashboard.tsx"]
129
128
  function StatusBadge({ status }: { status: string | null }) {
130
129
  if (!status) return <span className="text-gray-400 text-xs">—</span>
131
130
  const color =
@@ -139,16 +138,15 @@ function StatusBadge({ status }: { status: string | null }) {
139
138
  </span>
140
139
  )
141
140
  }
141
+ // CIL[END stable_id="~/.framework/src/pages/admin/TestingDashboard.tsx:StatusBadge:component"]
142
142
  // CIL[DOC-VECTOR type="context" content="purpose='Render a colored status badge'; No verified external callers; imports: .framework/src/hooks/useApi.ts,.framework/src/lib/api.ts,.framework/src/components/shared/AgentView.tsx"]
143
143
  // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
144
144
  // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
145
145
  // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
146
146
  // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
147
147
  // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
148
- // CIL[END stable_id="~/.framework/src/pages/admin/TestingDashboard.tsx:StatusBadge:component"]
149
148
 
150
149
 
151
- // CIL[BEGIN stable_id="~/.framework/src/pages/admin/TestingDashboard.tsx:durationLabel:function" type="function" identity="durationLabel" parent="~/.framework/src/pages/admin/TestingDashboard.tsx"]
152
150
  // CIL[DOC-MACRO purpose="Format a duration in milliseconds as a readable string"]
153
151
  // CIL[DOC-RESPONSIBILITY responsibility="Convert millisecond duration to ms or seconds display"]
154
152
  // CIL[DOC-CONTEXT module="TestingDashboard" layer="presentation" related_files=".framework/src/components/admin/PageInstructions.tsx,.framework/src/components/shared/AgentView.tsx,.framework/src/components/ui/LoadingSpinner.tsx,.framework/src/hooks/useApi.ts,.framework/src/lib/api.ts,.framework/src/lib/utils.ts,.framework/src/pages/admin/TestingDashboard.tsx"]
@@ -156,20 +154,20 @@ function StatusBadge({ status }: { status: string | null }) {
156
154
  // CIL[DOC-MICRO logic_summary="Returns '—' for null, 'ms' for sub-second, or formatted seconds" notable_decisions="[]"]
157
155
  // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
158
156
  // CIL[DOC-STABILITY stability="stable"]
157
+ // CIL[BEGIN stable_id="~/.framework/src/pages/admin/TestingDashboard.tsx:durationLabel:function" type="function" identity="durationLabel" parent="~/.framework/src/pages/admin/TestingDashboard.tsx"]
159
158
  function durationLabel(ms: number | null): string {
160
159
  if (ms == null) return '—'
161
160
  if (ms < 1000) return `${ms}ms`
162
161
  return `${(ms / 1000).toFixed(1)}s`
163
162
  }
163
+ // CIL[END stable_id="~/.framework/src/pages/admin/TestingDashboard.tsx:durationLabel:function"]
164
164
  // CIL[DOC-VECTOR type="context" content="purpose='Format a duration in milliseconds as a readable string'; No verified external callers; imports: .framework/src/hooks/useApi.ts,.framework/src/lib/api.ts,.framework/src/components/shared/AgentView.tsx"]
165
165
  // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
166
166
  // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
167
167
  // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
168
168
  // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
169
169
  // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
170
- // CIL[END stable_id="~/.framework/src/pages/admin/TestingDashboard.tsx:durationLabel:function"]
171
170
 
172
- // CIL[BEGIN stable_id="~/.framework/src/pages/admin/TestingDashboard.tsx:SuiteCard:component" type="component" identity="SuiteCard" parent="~/.framework/src/pages/admin/TestingDashboard.tsx"]
173
171
  // CIL[DOC-MACRO purpose="Render a test suite summary card"]
174
172
  // CIL[DOC-RESPONSIBILITY responsibility="Show label, status, last run, pass/fail counts, and pass rate"]
175
173
  // CIL[DOC-CONTEXT module="TestingDashboard" layer="presentation" related_files=".framework/src/components/admin/PageInstructions.tsx,.framework/src/components/shared/AgentView.tsx,.framework/src/components/ui/LoadingSpinner.tsx,.framework/src/hooks/useApi.ts,.framework/src/lib/api.ts,.framework/src/lib/utils.ts,.framework/src/pages/admin/TestingDashboard.tsx"]
@@ -177,6 +175,7 @@ function durationLabel(ms: number | null): string {
177
175
  // CIL[DOC-MICRO logic_summary="Computes pass rate and displays suite health in a card" notable_decisions="[]"]
178
176
  // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
179
177
  // CIL[DOC-STABILITY stability="stable"]
178
+ // CIL[BEGIN stable_id="~/.framework/src/pages/admin/TestingDashboard.tsx:SuiteCard:component" type="component" identity="SuiteCard" parent="~/.framework/src/pages/admin/TestingDashboard.tsx"]
180
179
  function SuiteCard({ stat }: { stat: SuiteStat }) {
181
180
  const label = SUITE_LABELS[stat.suite] ?? stat.suite
182
181
  const passRate = stat.last_total
@@ -209,15 +208,14 @@ function SuiteCard({ stat }: { stat: SuiteStat }) {
209
208
  </div>
210
209
  )
211
210
  }
211
+ // CIL[END stable_id="~/.framework/src/pages/admin/TestingDashboard.tsx:SuiteCard:component"]
212
212
  // CIL[DOC-VECTOR type="context" content="purpose='Render a test suite summary card'; No verified external callers; imports: .framework/src/hooks/useApi.ts,.framework/src/lib/api.ts,.framework/src/components/shared/AgentView.tsx"]
213
213
  // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
214
214
  // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
215
215
  // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
216
216
  // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
217
217
  // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
218
- // CIL[END stable_id="~/.framework/src/pages/admin/TestingDashboard.tsx:SuiteCard:component"]
219
218
 
220
- // CIL[BEGIN stable_id="~/.framework/src/pages/admin/TestingDashboard.tsx:TestingDashboard:component" type="component" identity="TestingDashboard" parent="~/.framework/src/pages/admin/TestingDashboard.tsx"]
221
219
  // CIL[DOC-MACRO purpose="Admin page for viewing test suite health and run history"]
222
220
  // CIL[DOC-RESPONSIBILITY responsibility="Fetch stats and recent runs, render suite cards and run table"]
223
221
  // CIL[DOC-CONTEXT module="TestingDashboard" layer="page" related_files=".framework/src/components/admin/PageInstructions.tsx,.framework/src/components/shared/AgentView.tsx,.framework/src/components/ui/LoadingSpinner.tsx,.framework/src/hooks/useApi.ts,.framework/src/lib/api.ts,.framework/src/lib/utils.ts,.framework/src/pages/admin/TestingDashboard.tsx"]
@@ -225,6 +223,7 @@ function SuiteCard({ stat }: { stat: SuiteStat }) {
225
223
  // CIL[DOC-MICRO logic_summary="Loads suite stats and recent runs, renders cards, table, and agent view" notable_decisions="[]"]
226
224
  // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
227
225
  // CIL[DOC-STABILITY stability="stable"]
226
+ // CIL[BEGIN stable_id="~/.framework/src/pages/admin/TestingDashboard.tsx:TestingDashboard:component" type="component" identity="TestingDashboard" parent="~/.framework/src/pages/admin/TestingDashboard.tsx"]
228
227
  export default function TestingDashboard() {
229
228
  const navigate = useNavigate()
230
229
 
@@ -264,17 +263,6 @@ export default function TestingDashboard() {
264
263
  Refresh
265
264
  </button>
266
265
  </div>
267
-
268
- <PageInstructions
269
- description="Run and review Spine test suites."
270
- sections={[
271
- { title: 'What this page is for', content: 'This page displays the health and history of the unit, integration, API, and UI test suites.' },
272
- { title: 'How to read the cards', content: 'The suite health cards show the most recent run status, pass rate, total runs, and last run time. Colors indicate passed, failed, running, or unknown states.' },
273
- { title: 'How to use this page', content: 'Click the Refresh button to reload stats and runs. Click a row in the Recent Runs table to view individual test case results. Suites are triggered from the IDE or CI pipeline.' },
274
- { title: 'Important notes', content: 'A pass rate below 100% is shown in red. Empty states mean no runs have been recorded yet for that suite.' },
275
- ]}
276
- />
277
-
278
266
  {/* Suite health cards */}
279
267
  {statsLoading ? (
280
268
  <div className="flex justify-center py-8"><LoadingSpinner /></div>
@@ -373,10 +361,10 @@ export default function TestingDashboard() {
373
361
  </div>
374
362
  )
375
363
  }
364
+ // CIL[END stable_id="~/.framework/src/pages/admin/TestingDashboard.tsx:TestingDashboard:component"]
376
365
  // CIL[DOC-VECTOR type="context" content="purpose='Admin page for viewing test suite health and run history'; No verified external callers; imports: .framework/src/hooks/useApi.ts,.framework/src/lib/api.ts,.framework/src/components/shared/AgentView.tsx"]
377
366
  // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
378
367
  // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
379
368
  // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
380
369
  // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
381
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
382
- // CIL[END stable_id="~/.framework/src/pages/admin/TestingDashboard.tsx:TestingDashboard:component"]
370
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]