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,60 +0,0 @@
1
- // CIL[BEGIN stable_id="~/.framework/mcp/load-env.ts:module_header:module_header" type="module_header" identity="module_header" parent="~/.framework/mcp/load-env.ts"]
2
- // CIL[DOC-MACRO purpose="Imports Node.js utilities for resolving and loading an environment file."]
3
- // CIL[DOC-CONTEXT module="mcp" layer="framework" related_files=".framework/mcp/load-env.ts"]
4
- // CIL[DOC-CONTRACT inputs="none" outputs="runtime dependencies available to the module" errors="none" side_effects="none"]
5
- // CIL[DOC-MICRO logic_summary="Imports fs, path, and fileURLToPath for use by loadEnv." notable_decisions="[]"]
6
- // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
7
- // CIL[DOC-STABILITY stability="stable"]
8
- // CIL[DOC-AUDIENCE audience="developers"]
9
- import fs from 'node:fs'
10
- import path from 'node:path'
11
- import { fileURLToPath } from 'node:url'
12
- // CIL[DOC-VECTOR type="context" content="purpose='Imports Node.js utilities for resolving and loading an environment file.'; No verified external callers; imports: none"]
13
- // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
14
- // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
15
- // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
16
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
17
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
18
- // CIL[END stable_id="~/.framework/mcp/load-env.ts:module_header:module_header"]
19
-
20
- // CIL[BEGIN stable_id="~/.framework/mcp/load-env.ts:loadEnv:function" type="function" identity="loadEnv" parent="~/.framework/mcp/load-env.ts"]
21
- // CIL[DOC-MACRO purpose="Reads a .env file and populates process.env for any keys that are not already set."]
22
- // CIL[DOC-RESPONSIBILITY responsibility="Bootstrap environment variables for the MCP server process."]
23
- // CIL[DOC-CONTEXT module="mcp" layer="framework" related_files=".framework/mcp/load-env.ts"]
24
- // CIL[DOC-CONTRACT inputs="none" outputs="process.env updated from .env file" errors="read/parse failures are silently ignored" side_effects="mutates process.env"]
25
- // CIL[DOC-MICRO logic_summary="Resolves the .env path relative to this file, reads it line by line, skips empty and comment lines, parses KEY=VALUE pairs, trims and strips surrounding quotes from values, and writes to process.env only when the key is absent." notable_decisions="Returns early if .env is missing; ignores all exceptions so server startup is not blocked; preserves already-set environment variables."]
26
- // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
27
- // CIL[DOC-STABILITY stability="stable"]
28
- function loadEnv(): void {
29
- try {
30
- const __filename = fileURLToPath(import.meta.url)
31
- const envPath = path.resolve(path.dirname(__filename), '../../.env')
32
- if (!fs.existsSync(envPath)) return
33
- const text = fs.readFileSync(envPath, 'utf-8')
34
- for (const raw of text.split(/\r?\n/)) {
35
- const line = raw.trim()
36
- if (!line || line.startsWith('#')) continue
37
- const eq = line.indexOf('=')
38
- if (eq === -1) continue
39
- const key = line.slice(0, eq).trim()
40
- let value = line.slice(eq + 1).trim()
41
- if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) {
42
- value = value.slice(1, -1)
43
- }
44
- if (key && process.env[key] === undefined) {
45
- process.env[key] = value
46
- }
47
- }
48
- } catch {
49
- // Ignore read/parse errors so the server still starts if .env is missing.
50
- }
51
- }
52
-
53
- loadEnv()
54
- // CIL[DOC-VECTOR type="context" content="purpose='Reads a .env file and populates process.env for any keys that are not already set.'; No verified external callers; imports: none"]
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
- // CIL[END stable_id="~/.framework/mcp/load-env.ts:loadEnv:function"]
@@ -1,275 +0,0 @@
1
- // CIL[BEGIN stable_id="~/.framework/mcp/shared/app-manifest.ts:module_header:module_header" type="module_header" identity="module_header" parent="~/.framework/mcp/shared/app-manifest.ts"]
2
- // CIL[DOC-MACRO purpose="Shared TypeScript module for loading and merging app manifests from JSON files"]
3
- // CIL[DOC-RESPONSIBILITY responsibility="Declares AppManifest and NavItem interfaces and exposes loadManifest, clearManifestCache, and mergeWithManifest helpers"]
4
- // CIL[DOC-CONTEXT module="mcp/shared" layer="shared" related_files=".framework/mcp/shared/app-manifest.ts"]
5
- // CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
6
- // CIL[DOC-MICRO logic_summary="Provides shared manifest data types and loader/merger functions" notable_decisions="[]"]
7
- // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
8
- // CIL[DOC-STABILITY stability="stable"]
9
- // CIL[DOC-AUDIENCE audience="mcp"]
10
-
11
- import { readFileSync, realpathSync } from 'node:fs'
12
- import { resolve, sep } from 'node:path'
13
- // CIL[DOC-VECTOR type="context" content="purpose='Shared TypeScript module for loading and merging app manifests from JSON files'; No verified external callers; imports: none"]
14
- // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
15
- // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
16
- // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
17
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
18
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
19
- // CIL[END stable_id="~/.framework/mcp/shared/app-manifest.ts:module_header:module_header"]
20
-
21
-
22
- // CIL[BEGIN stable_id="~/.framework/mcp/shared/app-manifest.ts:AppManifest:interface" type="interface" identity="AppManifest" parent="~/.framework/mcp/shared/app-manifest.ts"]
23
- // CIL[DOC-MACRO purpose="Defines the typed contract for an app manifest JSON file"]
24
- // CIL[DOC-RESPONSIBILITY responsibility="Describe all configurable fields exposed by a Spine app manifest"]
25
- // CIL[DOC-CONTEXT module="mcp/shared" layer="shared" related_files=".framework/mcp/shared/app-manifest.ts"]
26
- // CIL[DOC-CONTRACT inputs="none" outputs="AppManifest interface" errors="none" side_effects="none"]
27
- // CIL[DOC-MICRO logic_summary="Property list for an app manifest including metadata, roles, routes, navigation, dependencies, and feature toggles" notable_decisions="[]"]
28
- // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
29
- // CIL[DOC-STABILITY stability="stable"]
30
- export interface AppManifest {
31
- name: string
32
- slug: string
33
- description?: string
34
- version?: string
35
- required_roles: string[]
36
- route_prefix?: string
37
- renderer?: 'generic' | 'custom' | 'none'
38
- routes: string[]
39
- nav_items: NavItem[]
40
- features?: string[]
41
- dependencies?: string[]
42
- entry_point: string
43
- is_public?: boolean
44
- auth_required?: boolean
45
- preview_domain?: string
46
- prod_domain?: string
47
- }
48
- // CIL[DOC-VECTOR type="context" content="purpose='Defines the typed contract for an app manifest JSON file'; No verified external callers; imports: none"]
49
- // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
50
- // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
51
- // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
52
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
53
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
54
- // CIL[END stable_id="~/.framework/mcp/shared/app-manifest.ts:AppManifest:interface"]
55
-
56
-
57
- // CIL[BEGIN stable_id="~/.framework/mcp/shared/app-manifest.ts:NavItem:interface" type="interface" identity="NavItem" parent="~/.framework/mcp/shared/app-manifest.ts"]
58
- // CIL[DOC-MACRO purpose="Defines the recursive navigation item contract for app manifests"]
59
- // CIL[DOC-RESPONSIBILITY responsibility="Describe a single navigation entry with optional children"]
60
- // CIL[DOC-CONTEXT module="mcp/shared" layer="shared" related_files=".framework/mcp/shared/app-manifest.ts"]
61
- // CIL[DOC-CONTRACT inputs="none" outputs="NavItem interface" errors="none" side_effects="none"]
62
- // CIL[DOC-MICRO logic_summary="Navigation item structure with title, path, icon, order, and nested children" notable_decisions="[]"]
63
- // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
64
- // CIL[DOC-STABILITY stability="stable"]
65
- export interface NavItem {
66
- title: string
67
- path: string
68
- icon?: string
69
- order?: number
70
- children?: NavItem[]
71
- }
72
- // CIL[DOC-VECTOR type="context" content="purpose='Defines the recursive navigation item contract for app manifests'; No verified external callers; imports: none"]
73
- // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
74
- // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
75
- // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
76
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
77
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
78
- // CIL[END stable_id="~/.framework/mcp/shared/app-manifest.ts:NavItem:interface"]
79
-
80
-
81
-
82
- // CIL[BEGIN stable_id="~/.framework/mcp/shared/app-manifest.ts:manifestCache:constant" type="constant" identity="manifestCache" parent="~/.framework/mcp/shared/app-manifest.ts"]
83
- // CIL[DOC-MACRO purpose="In-memory cache for loaded app manifests keyed by file path"]
84
- // CIL[DOC-RESPONSIBILITY responsibility="Store and reuse parsed manifest objects across loadManifest calls"]
85
- // CIL[DOC-CONTEXT module="mcp/shared" layer="shared" related_files=".framework/mcp/shared/app-manifest.ts"]
86
- // CIL[DOC-CONTRACT inputs="canonical manifest path key and AppManifest value" outputs="cached manifest or undefined" errors="none" side_effects="reads and writes a module-level Map"]
87
- // CIL[DOC-MICRO logic_summary="Uses a module-scoped Map keyed by canonical path to avoid repeated JSON parsing of the same manifest file" notable_decisions="[]"]
88
- // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
89
- // CIL[DOC-STABILITY stability="stable"]
90
- const manifestCache = new Map<string, AppManifest>()
91
- // CIL[DOC-VECTOR type="context" content="purpose='In-memory cache for loaded app manifests keyed by file path'; No verified external callers; imports: none"]
92
- // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
93
- // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
94
- // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
95
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
96
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
97
- // CIL[END stable_id="~/.framework/mcp/shared/app-manifest.ts:manifestCache:constant"]
98
-
99
-
100
-
101
- // CIL[BEGIN stable_id="~/.framework/mcp/shared/app-manifest.ts:repoRoot:function" type="function" identity="repoRoot" parent="~/.framework/mcp/shared/app-manifest.ts"]
102
- // CIL[DOC-MACRO purpose="Resolve the repository root directory used to locate manifest files"]
103
- // CIL[DOC-RESPONSIBILITY responsibility="Return the absolute repository root for manifest path resolution"]
104
- // CIL[DOC-CONTEXT module="mcp/shared" layer="shared" related_files=".framework/mcp/shared/app-manifest.ts"]
105
- // CIL[DOC-CONTRACT inputs="none" outputs="string absolute path" errors="none" side_effects="reads process.env.REPO_PATH or process.cwd"]
106
- // CIL[DOC-MICRO logic_summary="Prefers the REPO_PATH environment variable, falling back to the current working directory" notable_decisions="[]"]
107
- // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
108
- // CIL[DOC-STABILITY stability="stable"]
109
- function repoRoot(): string {
110
- return process.env.REPO_PATH || process.cwd()
111
- }
112
- // CIL[DOC-VECTOR type="context" content="purpose='Resolve the repository root directory used to locate manifest files'; No verified external callers; imports: none"]
113
- // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
114
- // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
115
- // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
116
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
117
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
118
- // CIL[END stable_id="~/.framework/mcp/shared/app-manifest.ts:repoRoot:function"]
119
-
120
-
121
-
122
- // CIL[BEGIN stable_id="~/.framework/mcp/shared/app-manifest.ts:loadManifest:function" type="function" identity="loadManifest" parent="~/.framework/mcp/shared/app-manifest.ts"]
123
- // CIL[DOC-MACRO purpose="Load and parse an app manifest JSON file from a path relative to the repo root"]
124
- // CIL[DOC-RESPONSIBILITY responsibility="Read, validate, and cache app manifests for downstream use"]
125
- // CIL[DOC-CONTEXT module="mcp/shared" layer="shared" related_files=".framework/mcp/shared/app-manifest.ts"]
126
- // CIL[DOC-CONTRACT inputs="manifestPath: string relative path, projectRoot: optional root (defaults to REPO_PATH or cwd)" outputs="AppManifest | null" errors="returns null on path escapes, missing or invalid fields, or file read and parse failures" side_effects="reads the manifest file from disk and updates the in-memory cache keyed by canonical path; may log errors to console"]
127
- // CIL[DOC-MICRO logic_summary="Canonicalizes project root and manifest path with realpathSync, rejects lexical or symlink escapes, checks the cache, parses the JSON, validates object shape, nonempty name, slug charset, and required_roles array, then caches by canonical path" notable_decisions="[]"]
128
- // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
129
- // CIL[DOC-STABILITY stability="stable"]
130
- export function loadManifest(
131
- manifestPath: string,
132
- projectRoot: string = resolve(repoRoot())
133
- ): AppManifest | null {
134
- try {
135
- const root = realpathSync(resolve(projectRoot))
136
- const lexical = resolve(root, manifestPath)
137
- if (lexical !== root && !lexical.startsWith(root + sep)) {
138
- console.error(`[app-manifest] Manifest path escapes project root: ${manifestPath}`)
139
- return null
140
- }
141
- const canonical = realpathSync(lexical)
142
- if (canonical !== root && !canonical.startsWith(root + sep)) {
143
- console.error(`[app-manifest] Manifest resolves outside project root: ${manifestPath}`)
144
- return null
145
- }
146
-
147
- if (manifestCache.has(canonical)) {
148
- return manifestCache.get(canonical)!
149
- }
150
-
151
- const content = readFileSync(canonical, 'utf-8')
152
- const manifest: AppManifest = JSON.parse(content)
153
-
154
- if (!manifest || typeof manifest !== 'object' || Array.isArray(manifest)) {
155
- console.error(`[app-manifest] Invalid manifest at ${manifestPath}: root must be an object`)
156
- return null
157
- }
158
-
159
- if (typeof manifest.name !== 'string' || !manifest.name.trim()) {
160
- console.error(`[app-manifest] Invalid manifest at ${manifestPath}: missing name`)
161
- return null
162
- }
163
-
164
- if (typeof manifest.slug !== 'string' || !/^[a-z][a-z0-9-]*$/.test(manifest.slug)) {
165
- console.error(`[app-manifest] Invalid manifest at ${manifestPath}: missing or invalid slug`)
166
- return null
167
- }
168
-
169
- if (manifest.required_roles === undefined || manifest.required_roles === null) {
170
- manifest.required_roles = []
171
- } else if (!Array.isArray(manifest.required_roles) || manifest.required_roles.some((r) => typeof r !== 'string' || !r.trim())) {
172
- console.error(`[app-manifest] Invalid manifest at ${manifestPath}: required_roles must be an array of nonempty strings`)
173
- return null
174
- }
175
-
176
- manifestCache.set(canonical, manifest)
177
- return manifest
178
- } catch (err) {
179
- console.error(`[app-manifest] Failed to load ${manifestPath}:`, err)
180
- return null
181
- }
182
- }
183
- // CIL[DOC-VECTOR type="context" content="purpose='Load and parse an app manifest JSON file from a path relative to the repo root'; No verified external callers; imports: none"]
184
- // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
185
- // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
186
- // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
187
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
188
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
189
- // CIL[END stable_id="~/.framework/mcp/shared/app-manifest.ts:loadManifest:function"]
190
-
191
-
192
- // CIL[BEGIN stable_id="~/.framework/mcp/shared/app-manifest.ts:clearManifestCache:function" type="function" identity="clearManifestCache" parent="~/.framework/mcp/shared/app-manifest.ts"]
193
- // CIL[DOC-MACRO purpose="Clear the in-memory manifest cache"]
194
- // CIL[DOC-RESPONSIBILITY responsibility="Allow callers to invalidate cached manifests so fresh files are loaded on the next call"]
195
- // CIL[DOC-CONTEXT module="mcp/shared" layer="shared" related_files=".framework/mcp/shared/app-manifest.ts"]
196
- // CIL[DOC-CONTRACT inputs="none" outputs="void" errors="none" side_effects="clears the manifestCache Map"]
197
- // CIL[DOC-MICRO logic_summary="Calls manifestCache.clear() to remove all entries" notable_decisions="[]"]
198
- // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
199
- // CIL[DOC-STABILITY stability="stable"]
200
- export function clearManifestCache(): void {
201
- manifestCache.clear()
202
- }
203
- // CIL[DOC-VECTOR type="context" content="purpose='Clear the in-memory manifest cache'; No verified external callers; imports: none"]
204
- // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
205
- // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
206
- // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
207
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
208
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
209
- // CIL[END stable_id="~/.framework/mcp/shared/app-manifest.ts:clearManifestCache:function"]
210
-
211
-
212
- // CIL[BEGIN stable_id="~/.framework/mcp/shared/app-manifest.ts:mergeWithManifest:function" type="function" identity="mergeWithManifest" parent="~/.framework/mcp/shared/app-manifest.ts"]
213
- // CIL[DOC-MACRO purpose="Merge a database app record with its corresponding manifest, preferring manifest values when present"]
214
- // CIL[DOC-RESPONSIBILITY responsibility="Build a runtime app object from a database record and manifest file, with fallback to database values when the manifest is absent"]
215
- // CIL[DOC-CONTEXT module="mcp/shared" layer="shared" related_files=".framework/mcp/shared/app-manifest.ts"]
216
- // CIL[DOC-CONTRACT inputs="dbRecord: any" outputs="merged record object | null" errors="returns null for missing dbRecord; warns on missing manifest" side_effects="loads a manifest via loadManifest; may log a warning to console"]
217
- // CIL[DOC-MICRO logic_summary="Returns null for a falsy record. If config_source is not manifest or manifest_path is missing, returns a database-only record tagged _source=database preserving an existing required_roles array and deriving from min_role only when absent. Otherwise loads the manifest and composes a record using manifest values for slug, name, description, roles, routes, nav items, features, dependencies, version, is_public, auth_required, while preserving the full database record including id, is_active, is_system, route_prefix, renderer, config, account_id, pack_id, and ownership" notable_decisions="[]"]
218
- // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
219
- // CIL[DOC-STABILITY stability="stable"]
220
- export function mergeWithManifest(dbRecord: any): any {
221
- if (!dbRecord) return null
222
-
223
- const fallbackRoles = Array.isArray(dbRecord.required_roles)
224
- ? dbRecord.required_roles
225
- : dbRecord.min_role ? [dbRecord.min_role] : []
226
-
227
- if (!dbRecord.manifest_path || dbRecord.config_source !== 'manifest') {
228
- return {
229
- ...dbRecord,
230
- required_roles: fallbackRoles,
231
- _source: 'database',
232
- }
233
- }
234
-
235
- const manifest = loadManifest(dbRecord.manifest_path)
236
- if (!manifest) {
237
- console.warn(`[app-manifest] Could not load manifest for ${dbRecord.slug}, falling back to DB`)
238
- return {
239
- ...dbRecord,
240
- required_roles: fallbackRoles,
241
- _source: 'database (manifest missing)',
242
- }
243
- }
244
-
245
- return {
246
- ...dbRecord,
247
- id: dbRecord.id,
248
- slug: manifest.slug,
249
- name: manifest.name,
250
- description: manifest.description || dbRecord.description,
251
- required_roles: manifest.required_roles,
252
- min_role: manifest.required_roles[0] || null,
253
- routes: manifest.routes,
254
- nav_items: manifest.nav_items,
255
- features: manifest.features || [],
256
- dependencies: manifest.dependencies || [],
257
- version: manifest.version,
258
- is_active: dbRecord.is_active,
259
- is_system: dbRecord.is_system,
260
- is_public: manifest.is_public ?? false,
261
- auth_required: manifest.auth_required ?? true,
262
- account_id: dbRecord.account_id,
263
- pack_id: dbRecord.pack_id,
264
- ownership: dbRecord.ownership,
265
- _source: 'manifest',
266
- _manifest_path: dbRecord.manifest_path,
267
- }
268
- }
269
- // CIL[DOC-VECTOR type="context" content="purpose='Merge a database app record with its corresponding manifest, preferring manifest values when present'; No verified external callers; imports: none"]
270
- // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
271
- // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
272
- // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
273
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
274
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
275
- // CIL[END stable_id="~/.framework/mcp/shared/app-manifest.ts:mergeWithManifest:function"]