spine-framework 0.3.124 → 0.3.126

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 (319) hide show
  1. package/.framework/cli/commands/agents.ts +35 -37
  2. package/.framework/cli/commands/auth.ts +35 -34
  3. package/.framework/cli/commands/create-app.ts +104 -40
  4. package/.framework/cli/commands/dev.ts +104 -69
  5. package/.framework/cli/commands/doctor.ts +179 -69
  6. package/.framework/cli/commands/generate.ts +83 -143
  7. package/.framework/cli/commands/init.ts +72 -34
  8. package/.framework/cli/commands/install-app.ts +260 -125
  9. package/.framework/cli/commands/items.ts +33 -44
  10. package/.framework/cli/commands/migrate.ts +122 -40
  11. package/.framework/cli/commands/migrations.ts +33 -40
  12. package/.framework/cli/commands/pipelines.ts +31 -39
  13. package/.framework/cli/commands/status.ts +47 -23
  14. package/.framework/cli/commands/system.ts +47 -37
  15. package/.framework/cli/commands/test.ts +112 -68
  16. package/.framework/cli/commands/validate-app.ts +215 -121
  17. package/.framework/cli/context.ts +112 -130
  18. package/.framework/cli/env-loader.ts +47 -18
  19. package/.framework/cli/index.ts +81 -42
  20. package/.framework/docs/runtime-types.md +1024 -0
  21. package/.framework/functions/_shared/agent-runner.ts +1296 -961
  22. package/.framework/functions/_shared/app-manifest.ts +82 -68
  23. package/.framework/functions/_shared/audit.ts +135 -83
  24. package/.framework/functions/_shared/{cil-state.ts → cil.ts} +158 -56
  25. package/.framework/functions/_shared/db.ts +80 -126
  26. package/.framework/functions/_shared/hash-api-key.ts +63 -0
  27. package/.framework/functions/_shared/index.ts +224 -335
  28. package/.framework/functions/_shared/kb.ts +319 -0
  29. package/.framework/functions/_shared/llm.ts +92 -0
  30. package/.framework/functions/_shared/logging.ts +288 -0
  31. package/.framework/functions/_shared/middleware.ts +329 -365
  32. package/.framework/functions/_shared/outcomes.ts +36 -0
  33. package/.framework/functions/_shared/permissions.ts +359 -643
  34. package/.framework/functions/_shared/pipeline-runner.ts +243 -316
  35. package/.framework/functions/_shared/principal.ts +376 -468
  36. package/.framework/functions/_shared/resolve-credentials.ts +102 -0
  37. package/.framework/functions/_shared/resolve-ids.ts +188 -16
  38. package/.framework/functions/_shared/retry-deliveries.ts +104 -0
  39. package/.framework/functions/_shared/schema-utils.ts +611 -373
  40. package/.framework/functions/_shared/testing.ts +207 -137
  41. package/.framework/functions/_shared/tracing.ts +276 -0
  42. package/.framework/functions/_shared/trigger-engine.ts +159 -211
  43. package/.framework/functions/_shared/webhook-registration.ts +95 -81
  44. package/.framework/functions/_shared/webhook-registry.ts +153 -75
  45. package/.framework/functions/account-nodes.ts +31 -53
  46. package/.framework/functions/adapters/generic-webhook-inbound.ts +56 -0
  47. package/.framework/functions/adapters/generic-webhook-outbound.ts +43 -0
  48. package/.framework/functions/adapters/openai-outbound.ts +40 -0
  49. package/.framework/functions/admin-data.ts +685 -537
  50. package/.framework/functions/admin-funnel.ts +31 -20
  51. package/.framework/functions/admin-install-funnel.ts +47 -28
  52. package/.framework/functions/admin-signals.ts +47 -29
  53. package/.framework/functions/ai-agents.ts +122 -147
  54. package/.framework/functions/ai-interactions.ts +180 -90
  55. package/.framework/functions/api-keys.ts +250 -192
  56. package/.framework/functions/apps.ts +203 -197
  57. package/.framework/functions/auth.ts +98 -91
  58. package/.framework/functions/cil-agent-ingest.ts +773 -0
  59. package/.framework/functions/cil-agent.ts +592 -0
  60. package/.framework/functions/cil-callmap.ts +1227 -0
  61. package/.framework/functions/cil-config.ts +583 -0
  62. package/.framework/functions/cil-context.ts +445 -0
  63. package/.framework/functions/cil-doc.ts +1752 -0
  64. package/.framework/functions/cil-embeddings.ts +1202 -0
  65. package/.framework/functions/cil-graph.ts +585 -0
  66. package/.framework/functions/cil-ingest.ts +2416 -0
  67. package/.framework/functions/cil-pipeline.ts +318 -0
  68. package/.framework/functions/cil-project.ts +499 -0
  69. package/.framework/functions/cil-validate.ts +469 -0
  70. package/.framework/functions/debug-auth.ts +73 -53
  71. package/.framework/functions/deliveries.ts +117 -0
  72. package/.framework/functions/embeddings.ts +528 -516
  73. package/.framework/functions/eval-harness.ts +158 -106
  74. package/.framework/functions/integration-outbound.ts +311 -0
  75. package/.framework/functions/integration-routes.ts +240 -466
  76. package/.framework/functions/integrations.ts +132 -140
  77. package/.framework/functions/invites.ts +401 -201
  78. package/.framework/functions/item-progress.ts +113 -53
  79. package/.framework/functions/kb.ts +28 -0
  80. package/.framework/functions/logs.ts +239 -222
  81. package/.framework/functions/observability.ts +308 -259
  82. package/.framework/functions/pipeline-executions.ts +179 -235
  83. package/.framework/functions/pipelines.ts +163 -205
  84. package/.framework/functions/prompt-configs.ts +109 -156
  85. package/.framework/functions/roles.ts +97 -147
  86. package/.framework/functions/system-cron.ts +132 -218
  87. package/.framework/functions/system.ts +112 -52
  88. package/.framework/functions/tests.ts +32 -28
  89. package/.framework/functions/timers.ts +162 -210
  90. package/.framework/functions/triggers.ts +282 -346
  91. package/.framework/functions/types.ts +283 -400
  92. package/.framework/migrations/001_core_schema.sql +630 -0
  93. package/.framework/migrations/002_core_rls_and_functions.sql +532 -0
  94. package/.framework/migrations/{003_system_data.sql → 003_core_system_data.sql} +26 -153
  95. package/.framework/migrations/004_core_rpc_and_broker.sql +421 -0
  96. package/.framework/migrations/005_core_observability.sql +598 -0
  97. package/.framework/migrations/006_security_hardening_rls.sql +97 -0
  98. package/.framework/migrations/007_kb_article_list.sql +237 -0
  99. package/.framework/migrations/008_items_target.sql +8 -0
  100. package/.framework/migrations/009_roles_slug_unique.sql +11 -0
  101. package/.framework/public/spine.config.json +91 -0
  102. package/.framework/scripts/app-install-cli.ts +112 -98
  103. package/.framework/src/App.tsx +67 -20
  104. package/.framework/src/apps/admin/index.tsx +97 -27
  105. package/.framework/src/components/AppWrapper.tsx +50 -11
  106. package/.framework/src/components/CustomAppLoader.tsx +131 -22
  107. package/.framework/src/components/admin/AdminListPage.tsx +75 -8
  108. package/.framework/src/components/admin/AdminSidebar.tsx +148 -36
  109. package/.framework/src/components/admin/AdminStatsCard.tsx +48 -29
  110. package/.framework/src/components/admin/PageInstructions.tsx +49 -0
  111. package/.framework/src/components/admin/SortableTableHeader.tsx +49 -2
  112. package/.framework/src/components/app-shell/GenericAppShell.tsx +69 -11
  113. package/.framework/src/components/app-shell/GenericDetailPage.tsx +55 -10
  114. package/.framework/src/components/app-shell/GenericListPage.tsx +76 -9
  115. package/.framework/src/components/app-sidebar.tsx +50 -3
  116. package/.framework/src/components/auth/ProtectedRoute.tsx +53 -45
  117. package/.framework/src/components/kb/KBArticleEditor.tsx +409 -0
  118. package/.framework/src/components/kb/KBArticleList.tsx +557 -0
  119. package/.framework/src/components/layout/AppShell.tsx +54 -16
  120. package/.framework/src/components/layout/Header.tsx +50 -38
  121. package/.framework/src/components/layout/Layout.tsx +48 -32
  122. package/.framework/src/components/layout/Sidebar.tsx +167 -16
  123. package/.framework/src/components/runtime/DataDetailHeader.tsx +33 -1
  124. package/.framework/src/components/runtime/DataDetailPage.tsx +289 -4
  125. package/.framework/src/components/runtime/DataFilters.tsx +78 -1
  126. package/.framework/src/components/runtime/DataHeader.tsx +32 -29
  127. package/.framework/src/components/runtime/DataListPage.tsx +161 -2
  128. package/.framework/src/components/runtime/DataStats.tsx +48 -1
  129. package/.framework/src/components/runtime/DataTable.tsx +153 -1
  130. package/.framework/src/components/runtime/SchemaDetailForm.tsx +77 -46
  131. package/.framework/src/components/runtime/index.ts +16 -9
  132. package/.framework/src/components/search-form.tsx +33 -1
  133. package/.framework/src/components/shared/AgentView.tsx +48 -51
  134. package/.framework/src/components/shared/FieldRenderer.tsx +84 -67
  135. package/.framework/src/components/shared/InviteManager.tsx +113 -52
  136. package/.framework/src/components/shared/MemberList.tsx +182 -0
  137. package/.framework/src/components/shared/SchemaFields.tsx +96 -78
  138. package/.framework/src/components/ui/DataTable.tsx +86 -56
  139. package/.framework/src/components/ui/Form.tsx +188 -109
  140. package/.framework/src/components/ui/ItemCard.tsx +86 -58
  141. package/.framework/src/components/ui/ItemListView.tsx +88 -61
  142. package/.framework/src/components/ui/LoadingSpinner.tsx +52 -27
  143. package/.framework/src/components/ui/Modal.tsx +81 -4
  144. package/.framework/src/components/ui/RichTextEditor.tsx +101 -9
  145. package/.framework/src/components/ui/accordion.tsx +97 -5
  146. package/.framework/src/components/ui/alert-dialog.tsx +225 -13
  147. package/.framework/src/components/ui/alert.tsx +113 -6
  148. package/.framework/src/components/ui/aspect-ratio.tsx +49 -2
  149. package/.framework/src/components/ui/avatar.tsx +129 -7
  150. package/.framework/src/components/ui/badge.tsx +65 -3
  151. package/.framework/src/components/ui/breadcrumb.tsx +145 -8
  152. package/.framework/src/components/ui/button-group.tsx +81 -4
  153. package/.framework/src/components/ui/button.tsx +49 -2
  154. package/.framework/src/components/ui/calendar.tsx +65 -3
  155. package/.framework/src/components/ui/card.tsx +145 -8
  156. package/.framework/src/components/ui/carousel.tsx +129 -7
  157. package/.framework/src/components/ui/chart.tsx +161 -10
  158. package/.framework/src/components/ui/checkbox.tsx +49 -2
  159. package/.framework/src/components/ui/collapsible.tsx +81 -5
  160. package/.framework/src/components/ui/combobox.tsx +305 -20
  161. package/.framework/src/components/ui/command.tsx +177 -11
  162. package/.framework/src/components/ui/context-menu.tsx +273 -17
  163. package/.framework/src/components/ui/dialog.tsx +209 -27
  164. package/.framework/src/components/ui/direction.tsx +64 -4
  165. package/.framework/src/components/ui/drawer.tsx +193 -12
  166. package/.framework/src/components/ui/dropdown-menu.tsx +273 -18
  167. package/.framework/src/components/ui/empty.tsx +145 -9
  168. package/.framework/src/components/ui/field.tsx +209 -14
  169. package/.framework/src/components/ui/hover-card.tsx +81 -4
  170. package/.framework/src/components/ui/input-group.tsx +162 -10
  171. package/.framework/src/components/ui/input-otp.tsx +98 -5
  172. package/.framework/src/components/ui/input.tsx +49 -2
  173. package/.framework/src/components/ui/item.tsx +225 -13
  174. package/.framework/src/components/ui/kbd.tsx +65 -3
  175. package/.framework/src/components/ui/label.tsx +49 -2
  176. package/.framework/src/components/ui/menubar.tsx +289 -17
  177. package/.framework/src/components/ui/native-select.tsx +97 -5
  178. package/.framework/src/components/ui/navigation-menu.tsx +177 -10
  179. package/.framework/src/components/ui/pagination.tsx +161 -9
  180. package/.framework/src/components/ui/popover.tsx +145 -8
  181. package/.framework/src/components/ui/progress.tsx +49 -2
  182. package/.framework/src/components/ui/radio-group.tsx +65 -3
  183. package/.framework/src/components/ui/resizable.tsx +82 -4
  184. package/.framework/src/components/ui/scroll-area.tsx +65 -3
  185. package/.framework/src/components/ui/select.tsx +193 -11
  186. package/.framework/src/components/ui/separator.tsx +49 -2
  187. package/.framework/src/components/ui/sheet.tsx +193 -11
  188. package/.framework/src/components/ui/sidebar.tsx +481 -38
  189. package/.framework/src/components/ui/skeleton.tsx +49 -2
  190. package/.framework/src/components/ui/slider.tsx +49 -2
  191. package/.framework/src/components/ui/sonner.tsx +49 -2
  192. package/.framework/src/components/ui/spinner.tsx +49 -2
  193. package/.framework/src/components/ui/switch.tsx +49 -2
  194. package/.framework/src/components/ui/table-primitives.tsx +160 -33
  195. package/.framework/src/components/ui/table.tsx +161 -9
  196. package/.framework/src/components/ui/tabs.tsx +113 -6
  197. package/.framework/src/components/ui/textarea.tsx +49 -2
  198. package/.framework/src/components/ui/toggle-group.tsx +81 -4
  199. package/.framework/src/components/ui/toggle.tsx +65 -3
  200. package/.framework/src/components/ui/tooltip.tsx +97 -5
  201. package/.framework/src/contexts/AppContext.tsx +129 -45
  202. package/.framework/src/contexts/AuthContext.tsx +187 -144
  203. package/.framework/src/hooks/use-mobile.ts +48 -2
  204. package/.framework/src/hooks/useApi.ts +208 -159
  205. package/.framework/src/hooks/useAppPath.ts +32 -23
  206. package/.framework/src/hooks/useApps.ts +51 -20
  207. package/.framework/src/hooks/useEntityList.ts +32 -78
  208. package/.framework/src/hooks/useEntityRecord.ts +35 -96
  209. package/.framework/src/hooks/useForm.ts +32 -92
  210. package/.framework/src/hooks/useListSchema.ts +49 -78
  211. package/.framework/src/hooks/useSchemaRecord.ts +114 -105
  212. package/.framework/src/lib/api.ts +195 -116
  213. package/.framework/src/lib/supabase.ts +98 -64
  214. package/.framework/src/lib/utils.ts +287 -151
  215. package/.framework/src/main.tsx +49 -3
  216. package/.framework/src/pages/DashboardPage.tsx +52 -29
  217. package/.framework/src/pages/NotFoundPage.tsx +32 -10
  218. package/.framework/src/pages/SetupPage.tsx +32 -12
  219. package/.framework/src/pages/admin/AIAgentDetailPage.tsx +119 -10
  220. package/.framework/src/pages/admin/AIAgentsPage.tsx +48 -19
  221. package/.framework/src/pages/admin/APIKeyDetailPage.tsx +187 -17
  222. package/.framework/src/pages/admin/APIKeysPage.tsx +98 -22
  223. package/.framework/src/pages/admin/AlertsConfigPage.tsx +113 -26
  224. package/.framework/src/pages/admin/AppDetailPage.tsx +125 -8
  225. package/.framework/src/pages/admin/AppsPage.tsx +49 -2
  226. package/.framework/src/pages/admin/DeliveriesPage.tsx +196 -0
  227. package/.framework/src/pages/admin/DesignedPage.tsx +32 -18
  228. package/.framework/src/pages/admin/EmbeddingDetailPage.tsx +215 -484
  229. package/.framework/src/pages/admin/EmbeddingsPage.tsx +116 -319
  230. package/.framework/src/pages/admin/ExtendedShadcnTestPage.tsx +34 -9
  231. package/.framework/src/pages/admin/IncrementalShadcnTestPage.tsx +34 -9
  232. package/.framework/src/pages/admin/IntegratedDashboard.tsx +32 -16
  233. package/.framework/src/pages/admin/IntegrationDetailPage.tsx +183 -26
  234. package/.framework/src/pages/admin/IntegrationsPage.tsx +48 -19
  235. package/.framework/src/pages/admin/InvitesPage.tsx +48 -14
  236. package/.framework/src/pages/admin/LogsPage.tsx +422 -75
  237. package/.framework/src/pages/admin/MinimalShadcnTestPage.tsx +34 -9
  238. package/.framework/src/pages/admin/ObservabilityDashboard.tsx +113 -24
  239. package/.framework/src/pages/admin/PipelineDetailPage.tsx +206 -34
  240. package/.framework/src/pages/admin/PipelineExecutionsPage.tsx +50 -17
  241. package/.framework/src/pages/admin/PipelinesPage.tsx +160 -21
  242. package/.framework/src/pages/admin/PromptConfigDetailPage.tsx +378 -88
  243. package/.framework/src/pages/admin/PromptConfigsPage.tsx +125 -16
  244. package/.framework/src/pages/admin/ProperlyDesignedPage.tsx +49 -10
  245. package/.framework/src/pages/admin/RoleDetailPage.tsx +130 -10
  246. package/.framework/src/pages/admin/RolesPage.tsx +171 -18
  247. package/.framework/src/pages/admin/SelectTestPage.tsx +34 -9
  248. package/.framework/src/pages/admin/ShadcnTestPage.tsx +49 -11
  249. package/.framework/src/pages/admin/SimpleDashboard.tsx +49 -10
  250. package/.framework/src/pages/admin/TestRunDetailPage.tsx +49 -4
  251. package/.framework/src/pages/admin/TestingDashboard.tsx +98 -28
  252. package/.framework/src/pages/admin/TimerDetailPage.tsx +143 -33
  253. package/.framework/src/pages/admin/TimersPage.tsx +48 -20
  254. package/.framework/src/pages/admin/TriggerDetailPage.tsx +118 -30
  255. package/.framework/src/pages/admin/TriggersPage.tsx +64 -19
  256. package/.framework/src/pages/admin/TypeDetailPage.tsx +138 -15
  257. package/.framework/src/pages/admin/TypesPage.tsx +48 -20
  258. package/.framework/src/pages/admin/cil/CILAgentPage.tsx +465 -0
  259. package/.framework/src/pages/admin/cil/CILChunkDetailPage.tsx +787 -0
  260. package/.framework/src/pages/admin/cil/CILDashboardPage.tsx +699 -0
  261. package/.framework/src/pages/admin/cil/CILFileListPage.tsx +647 -0
  262. package/.framework/src/pages/admin/cil/CILGraphPage.tsx +616 -0
  263. package/.framework/src/pages/admin/cil/CILIngestionPage.tsx +1402 -0
  264. package/.framework/src/pages/admin/cil/CILProjectsPage.tsx +614 -0
  265. package/.framework/src/pages/admin/cil/CILSearchPage.tsx +571 -0
  266. package/.framework/src/pages/admin/cil/FlexiblePipelinePage.tsx +731 -0
  267. package/.framework/src/pages/admin/kb/KBAdminPage.tsx +64 -0
  268. package/.framework/src/pages/auth/AuthConfirmPage.tsx +52 -51
  269. package/.framework/src/pages/auth/ForgotPasswordPage.tsx +31 -22
  270. package/.framework/src/pages/auth/LoginPage.tsx +50 -23
  271. package/.framework/src/pages/auth/PendingApprovalPage.tsx +31 -15
  272. package/.framework/src/pages/auth/RegisterPage.tsx +281 -317
  273. package/.framework/src/pages/spine-framework/APIPage.tsx +33 -0
  274. package/.framework/src/pages/spine-framework/CLIPage.tsx +33 -0
  275. package/.framework/src/types/auth.ts +128 -71
  276. package/.framework/src/types/types.ts +373 -157
  277. package/custom/.devin/skills/spine-workbench-discovery/SKILL.md +39 -0
  278. package/custom/.devin/skills/spine-workbench-idea/SKILL.md +36 -0
  279. package/custom/.devin/skills/spine-workbench-implement/SKILL.md +46 -0
  280. package/custom/.devin/skills/spine-workbench-initiative/SKILL.md +28 -0
  281. package/custom/.devin/skills/spine-workbench-plan/SKILL.md +38 -0
  282. package/docs/README.md +9 -130
  283. package/netlify.toml +5 -2
  284. package/package.json +13 -25
  285. package/scripts/kb-ingest-docs.ts +203 -0
  286. package/spine.config.json +65 -4
  287. package/.framework/migrations/001_schema.sql +0 -425
  288. package/.framework/migrations/002_rls_and_functions.sql +0 -763
  289. package/.framework/migrations/004_enhancements.sql +0 -43
  290. package/.framework/migrations/005_auth_user_trigger.sql +0 -105
  291. package/.framework/migrations/006_fix_current_actor_id.sql +0 -21
  292. package/.framework/migrations/016_invites.sql +0 -27
  293. package/.framework/migrations/017_fix_get_account_apps.sql +0 -78
  294. package/.framework/migrations/018_apps_required_roles.sql +0 -17
  295. package/.framework/migrations/019_triggers_unique_constraint.sql +0 -13
  296. package/.framework/migrations/020_get_account_apps_role_filter.sql +0 -117
  297. package/.framework/migrations/021_app_domains.sql +0 -112
  298. package/.framework/migrations/022_route_prefix_domain_unique.sql +0 -21
  299. package/.framework/migrations/023_match_embeddings_rpc.sql +0 -78
  300. package/.framework/migrations/024_messages_account_id.sql +0 -9
  301. package/.framework/migrations/025_retype_threads_messages.sql +0 -240
  302. package/.framework/migrations/026_fix_rls_policies.sql +0 -47
  303. package/.framework/migrations/027_embedding_lifecycle.sql +0 -176
  304. package/.framework/migrations/028_fix_message_data_permissions.sql +0 -49
  305. package/.framework/migrations/029_tighten_support_triage_prompt.sql +0 -41
  306. package/.framework/migrations/030_messages_updated_by.sql +0 -6
  307. package/.framework/migrations/031_seed_upsert_constraints.sql +0 -35
  308. package/docs/APPS.md +0 -232
  309. package/docs/ARCHITECTURE.md +0 -246
  310. package/docs/INSTALL.md +0 -155
  311. package/docs/design-schema-spec.md +0 -1837
  312. package/docs/dev-guides/01-create-an-app.md +0 -183
  313. package/docs/dev-guides/02-create-a-function.md +0 -178
  314. package/docs/dev-guides/03-create-a-component.md +0 -178
  315. package/docs/dev-guides/04-webhook-handlers.md +0 -129
  316. package/docs/dev-guides/05-testing.md +0 -168
  317. package/docs/dev-guides/README.md +0 -40
  318. package/docs/npm-packages-plan.md +0 -288
  319. package/docs/spine-core--api-reference.md +0 -822
@@ -1,52 +1,68 @@
1
- /**
2
- * @module src/hooks/useApi
3
- * @audience installer
4
- * @layer frontend-hook
5
- * @stability stable
6
- *
7
- * Low-level React hooks for async API calls with loading/error state,
8
- * AbortController-based cancellation, and optional pagination/mutation
9
- * variants. These are the primitives all higher-level data hooks
10
- * (`useEntityList`, `useEntityRecord`) build on top of.
11
- *
12
- * **Exports:**
13
- * | Hook | Purpose |
14
- * |-------------------|-----------------------------------------------------|
15
- * | `useApi` | Single async call with abort + route-change re-fetch|
16
- * | `usePaginatedApi` | Paginated async call with page/size controls |
17
- * | `useMutation` | Write operation (create/update/delete) with state |
18
- *
19
- * **Abort contract:** `useApi` creates a new `AbortController` per
20
- * invocation. On route navigation (`location.pathname` change) or on
21
- * unmount, the in-flight request is aborted and state is reset. This
22
- * prevents stale responses from a previous route populating the next
23
- * route's data.
24
- *
25
- * @seeAlso src/lib/api.ts (apiFetch — passes AbortSignal through)
26
- * @seeAlso src/hooks/useEntityList.ts (uses useApi)
27
- * @seeAlso src/hooks/useEntityRecord.ts (uses useApi + useMutation)
28
- */
29
1
 
30
- import { useState, useEffect, useCallback, useRef } from 'react'
31
- import { useLocation } from 'react-router-dom'
32
2
 
33
- // ─── TYPES ───────────────────────────────────────────────────────────────────
34
3
 
4
+
5
+
6
+
7
+
8
+
9
+
10
+
11
+
12
+
13
+ // CIL[BEGIN chunk_id="useapi_module_header_1783740744" type="module_header" identity="imports" parent="none"]
14
+ // CIL[DOC-MACRO purpose="Import React hooks and router for API functionality"]
15
+ // CIL[DOC-RESPONSIBILITY responsibility="Provide core React dependencies for API state management"]
16
+ // CIL[DOC-CONTEXT module="useApi" layer="frontend-hook" related_files="[\"custom/apps/portal/pages/ContentPage.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\".framework/functions/_shared/principal.ts\",\".framework/functions/_shared/schema-utils.ts\",\"\\\"]"]
17
+ // CIL[DOC-CONTRACT inputs="none" outputs="React hooks" errors="none" side_effects="Module imports"]
18
+ // CIL[DOC-MICRO logic_summary="Imports useState, useEffect, useCallback, useRef from React and useLocation from react-router-dom" notable_decisions="[]"]
19
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
20
+ // CIL[DOC-STABILITY stability="stable"]
21
+ // CIL[DOC-AUDIENCE audience="developer"]
22
+ // CIL[DOC-VECTOR type="context" content="Layer: frontend-hook. Direct callers: 0. Direct calls: 0. Related files: custom/apps/portal/pages/ContentPage.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/src/pages/admin/TypeDetailPage.tsx, .framework/functions/_shared/principal.ts, .framework/functions/_shared/schema-utils.ts, \."]
23
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
24
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
25
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
26
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
27
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
28
+ import { useState, useEffect, useCallback, useRef } from 'react'
29
+ import { useLocation } from 'react-router-dom'
30
+ // CIL[END chunk_id="useapi_module_header_1783740744"]
31
+ // CIL[BEGIN chunk_id="useapi_apistate_1783740744" type="interface" identity="ApiState" parent="none"]
32
+ // CIL[DOC-MACRO purpose="Define API state structure for loading, data, and error tracking"]
33
+ // CIL[DOC-RESPONSIBILITY responsibility="Own the core state shape for API operations"]
34
+ // CIL[DOC-CONTEXT module="useApi" layer="frontend-hook" related_files="[\"custom/apps/portal/pages/ContentPage.tsx\",\".framework/src/pages/admin/IntegrationsPage.tsx\",\".framework/functions/_shared/principal.ts\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/functions/_shared/schema-utils.ts\",\"\\\"]"]
35
+ // CIL[DOC-CONTRACT inputs="none" outputs="state interface" errors="none" side_effects="Type definition"]
36
+ // CIL[DOC-MICRO logic_summary="Generic interface with data, loading, error, and lastFetched fields" notable_decisions="[]"]
37
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
38
+ // CIL[DOC-STABILITY stability="stable"]
39
+ // CIL[DOC-VECTOR type="context" content="Layer: frontend-hook. Direct callers: 0. Direct calls: 0. Related files: custom/apps/portal/pages/ContentPage.tsx, .framework/src/pages/admin/IntegrationsPage.tsx, .framework/functions/_shared/principal.ts, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/functions/_shared/schema-utils.ts, \."]
40
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
41
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
42
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
43
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
44
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
35
45
  interface ApiState<T> {
36
46
  data: T | null
37
47
  loading: boolean
38
48
  error: string | null
39
49
  lastFetched: Date | null
40
50
  }
41
-
42
- /**
43
- * Options for `useApi`.
44
- *
45
- * @prop immediate - If true, executes the function on mount and on route change
46
- * @prop onSuccess - Callback fired on successful response
47
- * @prop onError - Callback fired on error (with message string)
48
- * @prop initialData - Seed value for `data` before first fetch
49
- */
51
+ // CIL[END chunk_id="useapi_apistate_1783740744"]
52
+ // CIL[BEGIN chunk_id="useapi_useapioptions_1783740744" type="interface" identity="UseApiOptions" parent="none"]
53
+ // CIL[DOC-MACRO purpose="Configure API hook behavior with callbacks and initial data"]
54
+ // CIL[DOC-RESPONSIBILITY responsibility="Define configuration options for API hook usage"]
55
+ // CIL[DOC-CONTEXT module="useApi" layer="frontend-hook" related_files="[\"custom/apps/portal/pages/ContentPage.tsx\",\".framework/src/pages/admin/IntegrationsPage.tsx\",\".framework/functions/_shared/schema-utils.ts\",\".framework/src/pages/admin/RolesPage.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\"\\\"]"]
56
+ // CIL[DOC-CONTRACT inputs="none" outputs="options interface" errors="none" side_effects="Type definition"]
57
+ // CIL[DOC-MICRO logic_summary="Options for immediate execution, success/error callbacks, initial data, and dependencies" notable_decisions="[]"]
58
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
59
+ // CIL[DOC-STABILITY stability="stable"]
60
+ // CIL[DOC-VECTOR type="context" content="Layer: frontend-hook. Direct callers: 0. Direct calls: 0. Related files: custom/apps/portal/pages/ContentPage.tsx, .framework/src/pages/admin/IntegrationsPage.tsx, .framework/functions/_shared/schema-utils.ts, .framework/src/pages/admin/RolesPage.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, \."]
61
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
62
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
63
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
64
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
65
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
50
66
  interface UseApiOptions<T> {
51
67
  immediate?: boolean
52
68
  onSuccess?: (data: T) => void
@@ -54,17 +70,21 @@ interface UseApiOptions<T> {
54
70
  initialData?: T
55
71
  deps?: any[]
56
72
  }
57
-
58
- /**
59
- * Return value of `useApi`.
60
- *
61
- * @prop data - Response data or null
62
- * @prop loading - True while the request is in flight
63
- * @prop error - Error message string or null
64
- * @prop execute - Imperatively trigger the API call (with optional params)
65
- * @prop reset - Cancel in-flight request and restore to initial state
66
- * @prop refetch - Alias for `execute()` with no params
67
- */
73
+ // CIL[END chunk_id="useapi_useapioptions_1783740744"]
74
+ // CIL[BEGIN chunk_id="useapi_useapireturn_1783740744" type="interface" identity="UseApiReturn" parent="none"]
75
+ // CIL[DOC-MACRO purpose="Define the return value structure for useApi hook"]
76
+ // CIL[DOC-RESPONSIBILITY responsibility="Shape the public API surface for consumers"]
77
+ // CIL[DOC-CONTEXT module="useApi" layer="frontend-hook" related_files="[\".framework/functions/_shared/principal.ts\",\".framework/src/pages/admin/IntegrationsPage.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/functions/_shared/schema-utils.ts\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\"\\\"]"]
78
+ // CIL[DOC-CONTRACT inputs="none" outputs="return interface" errors="none" side_effects="Type definition"]
79
+ // CIL[DOC-MICRO logic_summary="Returns state data, loading status, error, and control functions" notable_decisions="[]"]
80
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
81
+ // CIL[DOC-STABILITY stability="stable"]
82
+ // CIL[DOC-VECTOR type="context" content="Layer: frontend-hook. Direct callers: 0. Direct calls: 0. Related files: .framework/functions/_shared/principal.ts, .framework/src/pages/admin/IntegrationsPage.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/functions/_shared/schema-utils.ts, .framework/src/pages/admin/TypeDetailPage.tsx, \."]
83
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
84
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
85
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
86
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
87
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
68
88
  interface UseApiReturn<T> {
69
89
  data: T | null
70
90
  loading: boolean
@@ -73,34 +93,21 @@ interface UseApiReturn<T> {
73
93
  reset: () => void
74
94
  refetch: () => Promise<T>
75
95
  }
76
-
77
- // ─── useApi ──────────────────────────────────────────────────────────────────
78
-
79
- /**
80
- * Generic async API hook with loading/error state and automatic
81
- * request cancellation.
82
- *
83
- * Each call to `execute` cancels any previous in-flight request via
84
- * `AbortController`. When `immediate: true`, the hook re-executes
85
- * (and aborts the prior request) whenever `location.pathname` changes.
86
- *
87
- * @param apiFunction - Async function to call; receives `{ ...params, signal }`
88
- * @param options - `UseApiOptions<T>` — see type for details
89
- * @returns `UseApiReturn<T>` — data, loading, error, execute, reset, refetch
90
- *
91
- * @inputSpec apiFunction must forward `signal` to any underlying `apiFetch`
92
- * call, otherwise cancellation is a no-op.
93
- * @sideEffects React state mutations; aborts in-flight fetch on cleanup
94
- * @calledBy useEntityList.ts, useEntityRecord.ts
95
- *
96
- * @example
97
- * ```tsx
98
- * const { data, loading, execute } = useApi(
99
- * async () => apiFetch('/api/items?action=list').then(r => r.json()),
100
- * { immediate: true }
101
- * )
102
- * ```
103
- */
96
+ // CIL[END chunk_id="useapi_useapireturn_1783740744"]
97
+ // CIL[BEGIN chunk_id="useapi_useapi_1783740744" type="function" identity="useApi" parent="none"]
98
+ // CIL[DOC-MACRO purpose="Core async API hook with loading state and request cancellation"]
99
+ // CIL[DOC-RESPONSIBILITY responsibility="Manage API calls, state, and automatic cleanup on navigation"]
100
+ // CIL[DOC-CONTEXT module="useApi" layer="frontend-hook" related_files="[]"]
101
+ // CIL[DOC-CONTRACT inputs="none" outputs="UseApiReturn" errors="throws API errors" side_effects="React state, AbortController"]
102
+ // CIL[DOC-MICRO logic_summary="Wraps async functions with loading state, error handling, and AbortController for cancellation" notable_decisions="[]"]
103
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
104
+ // CIL[DOC-STABILITY stability="stable"]
105
+ // CIL[DOC-VECTOR type="context" content="Layer: frontend-hook. Direct callers: 0. Direct calls: 0. Related files: none."]
106
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
107
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
108
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
109
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
110
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
104
111
  export function useApi<T>(
105
112
  apiFunction: (params?: any) => Promise<T>,
106
113
  options: UseApiOptions<T> = {}
@@ -127,15 +134,12 @@ export function useApi<T>(
127
134
  lastFetched: null
128
135
  })
129
136
 
130
- // Stable AbortController ref — replaced on each new fetch cycle
131
137
  const abortControllerRef = useRef<AbortController | null>(null)
132
138
 
133
139
  const execute = useCallback(async (params?: any) => {
134
- // Create a new AbortController for this specific request
135
140
  const abortController = new AbortController()
136
141
  const { signal } = abortController
137
142
 
138
- // Cancel previous request if still running
139
143
  abortControllerRef.current?.abort()
140
144
  abortControllerRef.current = abortController
141
145
 
@@ -147,7 +151,6 @@ export function useApi<T>(
147
151
  const result = await apiFunctionRef.current({ ...params, signal })
148
152
  const duration = Date.now() - startTime
149
153
 
150
- // Structured API call log for agentic IDE consumption
151
154
  console.log(JSON.stringify({
152
155
  type: 'spine_api_call',
153
156
  timestamp: new Date().toISOString(),
@@ -198,8 +201,6 @@ export function useApi<T>(
198
201
  return execute()
199
202
  }, [execute])
200
203
 
201
- // Re-fetch when pathname changes (navigation) — AbortController cancels
202
- // any previous in-flight request so auth state re-renders don't corrupt data
203
204
  useEffect(() => {
204
205
  if (!immediateRef.current) return
205
206
  setState({
@@ -224,9 +225,21 @@ export function useApi<T>(
224
225
  refetch
225
226
  }
226
227
  }
227
-
228
- // ─── usePaginatedApi ─────────────────────────────────────────────────────────
229
-
228
+ // CIL[END chunk_id="useapi_useapi_1783740744"]
229
+ // CIL[BEGIN chunk_id="useapi_paginatedapistate_1783740744" type="interface" identity="PaginatedApiState" parent="none"]
230
+ // CIL[DOC-MACRO purpose="Extend ApiState with pagination metadata for paginated responses"]
231
+ // CIL[DOC-RESPONSIBILITY responsibility="Define state structure for paginated API data"]
232
+ // CIL[DOC-CONTEXT module="useApi" layer="frontend-hook" related_files="[]"]
233
+ // CIL[DOC-CONTRACT inputs="none" outputs="paginated state interface" errors="none" side_effects="Type definition"]
234
+ // CIL[DOC-MICRO logic_summary="Extends ApiState with pagination fields for page, totalPages, totalItems, itemsPerPage" notable_decisions="[]"]
235
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
236
+ // CIL[DOC-STABILITY stability="stable"]
237
+ // CIL[DOC-VECTOR type="context" content="Layer: frontend-hook. Direct callers: 0. Direct calls: 0. Related files: none."]
238
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
239
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
240
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
241
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
242
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
230
243
  interface PaginatedApiState<T> extends ApiState<T[]> {
231
244
  pagination: {
232
245
  page: number
@@ -235,24 +248,39 @@ interface PaginatedApiState<T> extends ApiState<T[]> {
235
248
  itemsPerPage: number
236
249
  }
237
250
  }
238
-
239
- /**
240
- * Options for `usePaginatedApi`. Extends `UseApiOptions` with `itemsPerPage`.
241
- */
251
+ // CIL[END chunk_id="useapi_paginatedapistate_1783740744"]
252
+ // CIL[BEGIN chunk_id="useapi_usepaginatedapioptions_1783740744" type="interface" identity="UsePaginatedApiOptions" parent="none"]
253
+ // CIL[DOC-MACRO purpose="Extend UseApiOptions with pagination-specific configuration"]
254
+ // CIL[DOC-RESPONSIBILITY responsibility="Define configuration options for paginated API hook"]
255
+ // CIL[DOC-CONTEXT module="useApi" layer="frontend-hook" related_files="[]"]
256
+ // CIL[DOC-CONTRACT inputs="none" outputs="paginated options interface" errors="none" side_effects="Type definition"]
257
+ // CIL[DOC-MICRO logic_summary="Extends UseApiOptions with itemsPerPage configuration" notable_decisions="[]"]
258
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
259
+ // CIL[DOC-STABILITY stability="stable"]
260
+ // CIL[DOC-VECTOR type="context" content="Layer: frontend-hook. Direct callers: 0. Direct calls: 0. Related files: none."]
261
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
262
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
263
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
264
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
265
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
242
266
  interface UsePaginatedApiOptions<T> extends UseApiOptions<T[]> {
243
267
  itemsPerPage?: number
244
268
  }
245
-
246
- /**
247
- * Return value of `usePaginatedApi`. Extends `UseApiReturn` with pagination
248
- * controls.
249
- *
250
- * @prop pagination - Current page, totalPages, totalItems, itemsPerPage
251
- * @prop setPage - Navigate to a specific page (triggers re-fetch if immediate)
252
- * @prop setItemsPerPage - Change page size, resets to page 1
253
- * @prop nextPage / prevPage - Convenience page navigation
254
- * @prop hasNextPage / hasPrevPage - Boundary guards
255
- */
269
+ // CIL[END chunk_id="useapi_usepaginatedapioptions_1783740744"]
270
+ // CIL[BEGIN chunk_id="useapi_usepaginatedapireturn_1783740744" type="interface" identity="UsePaginatedApiReturn" parent="none"]
271
+ // CIL[DOC-MACRO purpose="Extend UseApiReturn with pagination navigation controls"]
272
+ // CIL[DOC-RESPONSIBILITY responsibility="Define return structure for paginated API hook with navigation"]
273
+ // CIL[DOC-CONTEXT module="useApi" layer="frontend-hook" related_files="[]"]
274
+ // CIL[DOC-CONTRACT inputs="none" outputs="paginated return interface" errors="none" side_effects="Type definition"]
275
+ // CIL[DOC-MICRO logic_summary="Extends UseApiReturn with pagination state and navigation functions" notable_decisions="[]"]
276
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
277
+ // CIL[DOC-STABILITY stability="stable"]
278
+ // CIL[DOC-VECTOR type="context" content="Layer: frontend-hook. Direct callers: 0. Direct calls: 0. Related files: none."]
279
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
280
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
281
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
282
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
283
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
256
284
  interface UsePaginatedApiReturn<T> extends UseApiReturn<T[]> {
257
285
  pagination: PaginatedApiState<T>['pagination']
258
286
  setPage: (page: number) => void
@@ -262,19 +290,21 @@ interface UsePaginatedApiReturn<T> extends UseApiReturn<T[]> {
262
290
  hasNextPage: boolean
263
291
  hasPrevPage: boolean
264
292
  }
265
-
266
- /**
267
- * Paginated variant of `useApi`. Manages page and itemsPerPage state and
268
- * automatically re-fetches when either changes (if `immediate: true`).
269
- *
270
- * @param apiFunction - Must accept `{ page, itemsPerPage, ...params }` and
271
- * return `{ data: T[], pagination: { page, totalPages, totalItems, itemsPerPage } }`
272
- * @param options - `UsePaginatedApiOptions<T>`
273
- * @returns `UsePaginatedApiReturn<T>`
274
- *
275
- * @sideEffects React state mutations
276
- * @calledBy admin list pages with server-side pagination
277
- */
293
+ // CIL[END chunk_id="useapi_usepaginatedapireturn_1783740744"]
294
+ // CIL[BEGIN chunk_id="useapi_usepaginatedapi_1783740744" type="function" identity="usePaginatedApi" parent="none"]
295
+ // CIL[DOC-MACRO purpose="Paginated API hook with page navigation and items-per-page controls"]
296
+ // CIL[DOC-RESPONSIBILITY responsibility="Manage paginated API state and navigation controls"]
297
+ // CIL[DOC-CONTEXT module="useApi" layer="frontend-hook" related_files="[]"]
298
+ // CIL[DOC-CONTRACT inputs="none" outputs="UsePaginatedApiReturn" errors="throws API errors" side_effects="React state, pagination"]
299
+ // CIL[DOC-MICRO logic_summary="Wraps paginated API calls with state management and navigation functions" notable_decisions="[]"]
300
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
301
+ // CIL[DOC-STABILITY stability="stable"]
302
+ // CIL[DOC-VECTOR type="context" content="Layer: frontend-hook. Direct callers: 0. Direct calls: 0. Related files: none."]
303
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
304
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
305
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
306
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
307
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
278
308
  export function usePaginatedApi<T>(
279
309
  apiFunction: (params: { page: number; itemsPerPage: number; [key: string]: any }) => Promise<{
280
310
  data: T[]
@@ -350,7 +380,7 @@ export function usePaginatedApi<T>(
350
380
  pagination: {
351
381
  ...prev.pagination,
352
382
  itemsPerPage,
353
- page: 1 // Reset to first page when changing items per page
383
+ page: 1
354
384
  }
355
385
  }))
356
386
  }, [])
@@ -389,7 +419,6 @@ export function usePaginatedApi<T>(
389
419
  const hasNextPage = state.pagination.page < state.pagination.totalPages
390
420
  const hasPrevPage = state.pagination.page > 1
391
421
 
392
- // Auto-execute when page or itemsPerPage changes
393
422
  useEffect(() => {
394
423
  if (apiOptions.immediate) {
395
424
  execute()
@@ -412,37 +441,61 @@ export function usePaginatedApi<T>(
412
441
  hasPrevPage
413
442
  }
414
443
  }
415
-
416
- // ─── useMutation ─────────────────────────────────────────────────────────────
417
-
444
+ // CIL[END chunk_id="useapi_usepaginatedapi_1783740744"]
445
+ // CIL[BEGIN chunk_id="useapi_mutationstate_1783740744" type="interface" identity="MutationState" parent="none"]
446
+ // CIL[DOC-MACRO purpose="Define state structure for mutation operations"]
447
+ // CIL[DOC-RESPONSIBILITY responsibility="Own the state shape for write operations"]
448
+ // CIL[DOC-CONTEXT module="useApi" layer="frontend-hook" related_files="[]"]
449
+ // CIL[DOC-CONTRACT inputs="none" outputs="mutation state interface" errors="none" side_effects="Type definition"]
450
+ // CIL[DOC-MICRO logic_summary="Simple state interface with data, loading, and error fields for mutations" notable_decisions="[]"]
451
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
452
+ // CIL[DOC-STABILITY stability="stable"]
453
+ // CIL[DOC-VECTOR type="context" content="Layer: frontend-hook. Direct callers: 0. Direct calls: 0. Related files: none."]
454
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
455
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
456
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
457
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
458
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
418
459
  interface MutationState<T> {
419
460
  data: T | null
420
461
  loading: boolean
421
462
  error: string | null
422
463
  }
423
-
424
- /**
425
- * Options for `useMutation`.
426
- *
427
- * @prop onSuccess - Called with the result after a successful mutation
428
- * @prop onError - Called with the error message on failure
429
- * @prop onSettled - Called after success or failure (always fires)
430
- */
464
+ // CIL[END chunk_id="useapi_mutationstate_1783740744"]
465
+ // CIL[BEGIN chunk_id="useapi_usemutationoptions_1783740744" type="interface" identity="UseMutationOptions" parent="none"]
466
+ // CIL[DOC-MACRO purpose="Define callback options for mutation lifecycle events"]
467
+ // CIL[DOC-RESPONSIBILITY responsibility="Configure mutation hook behavior with lifecycle callbacks"]
468
+ // CIL[DOC-CONTEXT module="useApi" layer="frontend-hook" related_files="[]"]
469
+ // CIL[DOC-CONTRACT inputs="none" outputs="mutation options interface" errors="none" side_effects="Type definition"]
470
+ // CIL[DOC-MICRO logic_summary="Options for success, error, and settled callbacks with typed parameters" notable_decisions="[]"]
471
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
472
+ // CIL[DOC-STABILITY stability="stable"]
473
+ // CIL[DOC-VECTOR type="context" content="Layer: frontend-hook. Direct callers: 0. Direct calls: 0. Related files: none."]
474
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
475
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
476
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
477
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
478
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
431
479
  interface UseMutationOptions<T, P> {
432
480
  onSuccess?: (data: T) => void
433
481
  onError?: (error: string) => void
434
482
  onSettled?: () => void
435
483
  }
436
-
437
- /**
438
- * Return value of `useMutation`.
439
- *
440
- * @prop data - Result of the last successful mutation, or null
441
- * @prop loading - True while the mutation is in flight
442
- * @prop error - Error message string or null
443
- * @prop mutate - Trigger the mutation with typed params
444
- * @prop reset - Reset state to null/false/null
445
- */
484
+ // CIL[END chunk_id="useapi_usemutationoptions_1783740744"]
485
+ // CIL[BEGIN chunk_id="useapi_usemutationreturn_1783740744" type="interface" identity="UseMutationReturn" parent="none"]
486
+ // CIL[DOC-MACRO purpose="Define return structure for mutation hook"]
487
+ // CIL[DOC-RESPONSIBILITY responsibility="Shape the public API surface for mutation operations"]
488
+ // CIL[DOC-CONTEXT module="useApi" layer="frontend-hook" related_files="[]"]
489
+ // CIL[DOC-CONTRACT inputs="none" outputs="mutation return interface" errors="none" side_effects="Type definition"]
490
+ // CIL[DOC-MICRO logic_summary="Returns mutation state, mutate function, and reset function" notable_decisions="[]"]
491
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
492
+ // CIL[DOC-STABILITY stability="stable"]
493
+ // CIL[DOC-VECTOR type="context" content="Layer: frontend-hook. Direct callers: 0. Direct calls: 0. Related files: none."]
494
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
495
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
496
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
497
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
498
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
446
499
  interface UseMutationReturn<T, P> {
447
500
  data: T | null
448
501
  loading: boolean
@@ -450,26 +503,21 @@ interface UseMutationReturn<T, P> {
450
503
  mutate: (params: P) => Promise<T>
451
504
  reset: () => void
452
505
  }
453
-
454
- /**
455
- * Write-operation hook for create, update, and delete calls. Does not
456
- * auto-execute — call `mutate(params)` explicitly.
457
- *
458
- * @param mutationFunction - Async write function taking typed params
459
- * @param options - `UseMutationOptions<T, P>`
460
- * @returns `UseMutationReturn<T, P>` — data, loading, error, mutate, reset
461
- *
462
- * @sideEffects React state mutations; triggers `onSuccess/onError/onSettled` callbacks
463
- * @calledBy useEntityRecord.ts (save and delete mutations)
464
- *
465
- * @example
466
- * ```tsx
467
- * const { mutate, loading } = useMutation(
468
- * async (id: string) => apiFetch(`/api/items?action=delete&id=${id}`, { method: 'DELETE' }),
469
- * { onSuccess: () => navigate('/items') }
470
- * )
471
- * ```
472
- */
506
+ // CIL[END chunk_id="useapi_usemutationreturn_1783740744"]
507
+ // CIL[BEGIN chunk_id="useapi_usemutation_1783740744" type="function" identity="useMutation" parent="none"]
508
+ // CIL[DOC-MACRO purpose="Write-operation hook for create, update, and delete operations"]
509
+ // CIL[DOC-RESPONSIBILITY responsibility="Manage mutation state and lifecycle callbacks"]
510
+ // CIL[DOC-CONTEXT module="useApi" layer="frontend-hook" related_files="[]"]
511
+ // CIL[DOC-CONTRACT inputs="none" outputs="UseMutationReturn" errors="throws mutation errors" side_effects="React state, callbacks"]
512
+ // CIL[DOC-MICRO logic_summary="Wraps async write operations with loading state and lifecycle callbacks" notable_decisions="[]"]
513
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
514
+ // CIL[DOC-STABILITY stability="stable"]
515
+ // CIL[DOC-VECTOR type="context" content="Layer: frontend-hook. Direct callers: 0. Direct calls: 0. Related files: none."]
516
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
517
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
518
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
519
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
520
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
473
521
  export function useMutation<T, P = void>(
474
522
  mutationFunction: (params: P) => Promise<T>,
475
523
  options: UseMutationOptions<T, P> = {}
@@ -524,3 +572,4 @@ export function useMutation<T, P = void>(
524
572
  reset
525
573
  }
526
574
  }
575
+ // CIL[END chunk_id="useapi_usemutation_1783740744"]
@@ -1,38 +1,47 @@
1
- import { useCurrentApp } from '../contexts/AppContext'
2
1
 
3
- /**
4
- * Returns a helper function that prepends the current app's route_prefix
5
- * to a root-relative path.
6
- *
7
- * Use this instead of hardcoding absolute paths in app components so that
8
- * changing `route_prefix` in manifest.json (and running update-db-app) is
9
- * the only change needed to move an app to a new URL location.
10
- *
11
- * @example
12
- * const appPath = useAppPath()
13
- * appPath('/dashboard') // → '/cortex/dashboard' (if prefix is /cortex)
14
- * appPath('/crm/accounts') // → '/cortex/crm/accounts'
15
- * appPath('/') // → '/cortex'
16
- *
17
- * // With route_prefix = '/'
18
- * appPath('/dashboard') // → '/dashboard'
19
- * appPath('/crm/accounts') // → '/crm/accounts'
20
- */
2
+ // CIL[BEGIN chunk_id="useapppath_module_header_1783740744" type="module_header" identity="imports" parent="none"]
3
+ // CIL[DOC-MACRO purpose="Import app context hook for route prefix access"]
4
+ // CIL[DOC-RESPONSIBILITY responsibility="Provide access to current app configuration"]
5
+ // CIL[DOC-CONTEXT module="useAppPath" layer="frontend-hook" related_files="[\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/migrations/015_simplify_apps_table.sql\",\"custom/apps/portal/pages/ContentPage.tsx\",\".framework/functions/_shared/principal.ts\",\"\\\"]"]
6
+ // CIL[DOC-CONTRACT inputs="none" outputs="useCurrentApp hook" errors="none" side_effects="Module imports"]
7
+ // CIL[DOC-MICRO logic_summary="Imports useCurrentApp hook from AppContext for app-specific routing" notable_decisions="[]"]
8
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
9
+ // CIL[DOC-STABILITY stability="stable"]
10
+ // CIL[DOC-AUDIENCE audience="developer"]
11
+ // CIL[DOC-VECTOR type="context" content="Layer: frontend-hook. Direct callers: 0. Direct calls: 0. Related files: custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/migrations/015_simplify_apps_table.sql, custom/apps/portal/pages/ContentPage.tsx, .framework/functions/_shared/principal.ts, \."]
12
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
13
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
14
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
15
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
16
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
17
+ import { useCurrentApp } from '../contexts/AppContext'
18
+ // CIL[END chunk_id="useapppath_module_header_1783740744"]
19
+ // CIL[BEGIN chunk_id="useapppath_useapppath_1783740744" type="function" identity="useAppPath" parent="none"]
20
+ // CIL[DOC-MACRO purpose="Generate app-specific path helper with route prefix handling"]
21
+ // CIL[DOC-RESPONSIBILITY responsibility="Manage route prefix logic for app-relative paths"]
22
+ // CIL[DOC-CONTEXT module="useAppPath" layer="frontend-hook" related_files="[\".framework/src/pages/admin/RolesPage.tsx\",\".framework/functions/_shared/schema-utils.ts\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\"custom/apps/cortex/functions/custom_cil-embeddings.ts\",\".framework/src/components/ui/dialog.tsx\",\"\\\"]"]
23
+ // CIL[DOC-CONTRACT inputs="none" outputs="path helper function" errors="none" side_effects="React hook dependency"]
24
+ // CIL[DOC-MICRO logic_summary="Creates path function that prepends app route_prefix to root-relative paths" notable_decisions="[]"]
25
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
26
+ // CIL[DOC-STABILITY stability="stable"]
27
+ // CIL[DOC-VECTOR type="context" content="Layer: frontend-hook. Direct callers: 7. Direct calls: 0. Related files: .framework/src/pages/admin/RolesPage.tsx, .framework/functions/_shared/schema-utils.ts, .framework/src/pages/admin/TypeDetailPage.tsx, custom/apps/cortex/functions/custom_cil-embeddings.ts, .framework/src/components/ui/dialog.tsx, \."]
28
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 7. Total affected: 7."]
29
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
30
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
31
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
32
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
21
33
  export function useAppPath(): (path: string) => string {
22
34
  const app = useCurrentApp()
23
35
 
24
- // Normalize: '/' prefix means the app owns root — no prefix to prepend.
25
- // Any other prefix is prepended as-is (trailing slash stripped).
26
36
  const prefix =
27
37
  !app.route_prefix || app.route_prefix === '/'
28
38
  ? ''
29
39
  : app.route_prefix.replace(/\/$/, '')
30
40
 
31
41
  return (path: string): string => {
32
- // path should be root-relative (start with /)
33
- // If the caller passes '/' return just the prefix (or '/' if no prefix)
34
42
  if (path === '/') return prefix || '/'
35
43
  const normalized = path.startsWith('/') ? path : `/${path}`
36
44
  return `${prefix}${normalized}`
37
45
  }
38
46
  }
47
+ // CIL[END chunk_id="useapppath_useapppath_1783740744"]