spine-framework 0.3.17 → 0.3.18

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 (269) hide show
  1. package/.framework/cli/commands/create-app.ts +1 -1
  2. package/.framework/cli/commands/dev.ts +215 -33
  3. package/.framework/cli/index.ts +37 -75
  4. package/.framework/functions/_shared/app-manifest.ts +8 -15
  5. package/.framework/functions/_shared/db.ts +11 -15
  6. package/.framework/functions/_shared/index.ts +7 -16
  7. package/.framework/functions/_shared/principal.ts +4 -62
  8. package/.framework/functions/_shared/resolve-ids.ts +6 -6
  9. package/.framework/functions/_shared/webhook-registry.ts +43 -1
  10. package/.framework/functions/admin-funnel.ts +104 -0
  11. package/.framework/functions/admin-install-funnel.ts +225 -0
  12. package/.framework/functions/admin-signals.ts +241 -0
  13. package/.framework/functions/integration-routes.ts +4 -8
  14. package/.framework/migrations/001_schema.sql +406 -0
  15. package/.framework/migrations/002_rls_and_functions.sql +710 -0
  16. package/.framework/migrations/003_system_data.sql +520 -0
  17. package/.framework/migrations/004_enhancements.sql +43 -0
  18. package/.framework/public/_redirects +3 -0
  19. package/.framework/public/spine-logo.jpg +0 -0
  20. package/.framework/public/spine-logo.svg +3 -0
  21. package/{scripts → .framework/scripts}/assemble-frontend.sh +8 -5
  22. package/{scripts → .framework/scripts}/assemble-functions.sh +4 -47
  23. package/{scripts → .framework/scripts}/assemble.sh +2 -8
  24. package/{scripts → .framework/scripts}/boundary-check.sh +5 -9
  25. package/{scripts → .framework/scripts}/check-core-integrity.sh +0 -0
  26. package/.framework/seeds/link_types/account_cli_instances.json +9 -0
  27. package/.framework/seeds/types/funnel_signal_use.json +98 -0
  28. package/.framework/seeds/types/spine_instance.json +109 -0
  29. package/.framework/src/App.tsx +11 -21
  30. package/.framework/src/components/CustomAppLoader.tsx +2 -19
  31. package/.framework/src/components/ui/accordion.tsx +1 -1
  32. package/.framework/src/components/ui/alert-dialog.tsx +1 -1
  33. package/.framework/src/components/ui/aspect-ratio.tsx +1 -1
  34. package/.framework/src/components/ui/avatar.tsx +1 -1
  35. package/.framework/src/components/ui/badge.tsx +2 -2
  36. package/.framework/src/components/ui/breadcrumb.tsx +2 -2
  37. package/.framework/src/components/ui/button-group.tsx +2 -2
  38. package/.framework/src/components/ui/button.tsx +2 -2
  39. package/.framework/src/components/ui/chart.tsx +6 -1
  40. package/.framework/src/components/ui/checkbox.tsx +1 -1
  41. package/.framework/src/components/ui/collapsible.tsx +1 -1
  42. package/.framework/src/components/ui/context-menu.tsx +1 -1
  43. package/.framework/src/components/ui/dialog.tsx +1 -1
  44. package/.framework/src/components/ui/direction.tsx +17 -1
  45. package/.framework/src/components/ui/dropdown-menu.tsx +1 -1
  46. package/.framework/src/components/ui/hover-card.tsx +1 -1
  47. package/.framework/src/components/ui/item.tsx +2 -2
  48. package/.framework/src/components/ui/label.tsx +1 -1
  49. package/.framework/src/components/ui/menubar.tsx +1 -1
  50. package/.framework/src/components/ui/navigation-menu.tsx +1 -1
  51. package/.framework/src/components/ui/popover.tsx +1 -1
  52. package/.framework/src/components/ui/progress.tsx +1 -1
  53. package/.framework/src/components/ui/radio-group.tsx +1 -1
  54. package/.framework/src/components/ui/scroll-area.tsx +1 -1
  55. package/.framework/src/components/ui/select.tsx +1 -1
  56. package/.framework/src/components/ui/separator.tsx +1 -1
  57. package/.framework/src/components/ui/sheet.tsx +1 -1
  58. package/.framework/src/components/ui/sidebar.tsx +6 -6
  59. package/.framework/src/components/ui/slider.tsx +1 -1
  60. package/.framework/src/components/ui/switch.tsx +1 -1
  61. package/.framework/src/components/ui/tabs.tsx +1 -1
  62. package/.framework/src/components/ui/toggle-group.tsx +1 -1
  63. package/.framework/src/components/ui/toggle.tsx +1 -1
  64. package/.framework/src/components/ui/tooltip.tsx +1 -1
  65. package/.framework/src/pages/auth/LoginPage.tsx +10 -9
  66. package/LICENSE.md +63 -93
  67. package/README.md +254 -129
  68. package/custom/.devin/skills/install-app/SKILL.md +39 -0
  69. package/custom/.devin/workflows/app-install.yaml +83 -0
  70. package/custom/README.md +79 -0
  71. package/docs/APPS.md +232 -0
  72. package/docs/ARCHITECTURE.md +246 -0
  73. package/docs/INSTALL.md +155 -0
  74. package/docs/README.md +170 -0
  75. package/docs/design-schema-spec.md +1837 -0
  76. package/docs/dev-guides/01-create-an-app.md +183 -0
  77. package/docs/dev-guides/02-create-a-function.md +178 -0
  78. package/docs/dev-guides/03-create-a-component.md +178 -0
  79. package/docs/dev-guides/04-webhook-handlers.md +129 -0
  80. package/docs/dev-guides/05-testing.md +168 -0
  81. package/docs/dev-guides/README.md +40 -0
  82. package/docs/npm-packages-plan.md +288 -0
  83. package/docs/spine-core--api-reference.md +822 -0
  84. package/package.json +78 -150
  85. package/.framework/cli/bin.cjs +0 -14
  86. package/.framework/cli/commands/claim.ts +0 -430
  87. package/.framework/cli/commands/init.ts +0 -219
  88. package/.framework/cli/commands/install-app.ts +0 -685
  89. package/.framework/cli/commands/migrate.ts +0 -178
  90. package/.framework/cli/commands/publish.ts +0 -191
  91. package/.framework/cli/commands/status.ts +0 -268
  92. package/.framework/cli/commands/uninstall-app.ts +0 -166
  93. package/.framework/cli/commands/update-app.ts +0 -397
  94. package/.framework/cli/welcome.cjs +0 -45
  95. package/.framework/config/signal-client.ts +0 -147
  96. package/.framework/config/signals.ts +0 -70
  97. package/.framework/docs/STABILITY.md +0 -52
  98. package/.framework/docs/examples/custom-app/README.md +0 -77
  99. package/.framework/docs/examples/custom-function/README.md +0 -27
  100. package/.framework/docs/examples/custom-function/handler.ts +0 -48
  101. package/.framework/docs/examples/custom-webhook/README.md +0 -68
  102. package/.framework/functions/handler-registry.ts +0 -22
  103. package/.framework/functions/signal.ts +0 -168
  104. package/.framework/migrations/000_foundation.sql +0 -1302
  105. package/.framework/migrations/001_seed.sql +0 -163
  106. package/.framework/migrations/002_seed_constraints.sql +0 -19
  107. package/.framework/migrations/003_auth_user_trigger.sql +0 -67
  108. package/.framework/migrations/004_app_version_tracking.sql +0 -8
  109. package/.framework/migrations/005_pipelines_slug_stages.sql +0 -21
  110. package/.framework/src/pages/auth/RegisterPage.tsx +0 -163
  111. package/CHANGELOG.md +0 -71
  112. package/STRUCTURE.md +0 -150
  113. package/bin/spine-framework.cjs +0 -62
  114. package/bin/welcome.cjs +0 -58
  115. package/bin/ws-shim.ts +0 -10
  116. package/config/components.json +0 -25
  117. package/config/deno.lock +0 -108
  118. package/config/package-lock.json +0 -17183
  119. package/config/postcss.config.cjs +0 -10
  120. package/config/tailwind.config.cjs +0 -78
  121. package/config/tsconfig.build.json +0 -32
  122. package/config/tsconfig.cli.json +0 -18
  123. package/config/tsconfig.json +0 -41
  124. package/config/tsconfig.node.json +0 -17
  125. package/config/tsconfig.node.tsbuildinfo +0 -1
  126. package/config/tsconfig.tsbuildinfo +0 -1
  127. package/config/typedoc.json +0 -16
  128. package/config/vite.config.d.ts +0 -2
  129. package/config/vite.config.ts +0 -71
  130. package/dist/cli/commands/agents.d.ts +0 -39
  131. package/dist/cli/commands/agents.d.ts.map +0 -1
  132. package/dist/cli/commands/auth.d.ts +0 -36
  133. package/dist/cli/commands/auth.d.ts.map +0 -1
  134. package/dist/cli/commands/claim.d.ts +0 -38
  135. package/dist/cli/commands/claim.d.ts.map +0 -1
  136. package/dist/cli/commands/create-app.d.ts +0 -23
  137. package/dist/cli/commands/create-app.d.ts.map +0 -1
  138. package/dist/cli/commands/dev.d.ts +0 -24
  139. package/dist/cli/commands/dev.d.ts.map +0 -1
  140. package/dist/cli/commands/doctor.d.ts +0 -42
  141. package/dist/cli/commands/doctor.d.ts.map +0 -1
  142. package/dist/cli/commands/generate.d.ts +0 -36
  143. package/dist/cli/commands/generate.d.ts.map +0 -1
  144. package/dist/cli/commands/init.d.ts +0 -20
  145. package/dist/cli/commands/init.d.ts.map +0 -1
  146. package/dist/cli/commands/install-app.d.ts +0 -30
  147. package/dist/cli/commands/install-app.d.ts.map +0 -1
  148. package/dist/cli/commands/items.d.ts +0 -45
  149. package/dist/cli/commands/items.d.ts.map +0 -1
  150. package/dist/cli/commands/migrate.d.ts +0 -21
  151. package/dist/cli/commands/migrate.d.ts.map +0 -1
  152. package/dist/cli/commands/migrations.d.ts +0 -41
  153. package/dist/cli/commands/migrations.d.ts.map +0 -1
  154. package/dist/cli/commands/pipelines.d.ts +0 -40
  155. package/dist/cli/commands/pipelines.d.ts.map +0 -1
  156. package/dist/cli/commands/publish.d.ts +0 -23
  157. package/dist/cli/commands/publish.d.ts.map +0 -1
  158. package/dist/cli/commands/status.d.ts +0 -23
  159. package/dist/cli/commands/status.d.ts.map +0 -1
  160. package/dist/cli/commands/system.d.ts +0 -29
  161. package/dist/cli/commands/system.d.ts.map +0 -1
  162. package/dist/cli/commands/test.d.ts +0 -46
  163. package/dist/cli/commands/test.d.ts.map +0 -1
  164. package/dist/cli/commands/uninstall-app.d.ts +0 -23
  165. package/dist/cli/commands/uninstall-app.d.ts.map +0 -1
  166. package/dist/cli/commands/update-app.d.ts +0 -24
  167. package/dist/cli/commands/update-app.d.ts.map +0 -1
  168. package/dist/cli/context.d.ts +0 -88
  169. package/dist/cli/context.d.ts.map +0 -1
  170. package/dist/cli/env-loader.d.ts +0 -14
  171. package/dist/cli/env-loader.d.ts.map +0 -1
  172. package/dist/cli/index.d.ts +0 -44
  173. package/dist/cli/index.d.ts.map +0 -1
  174. package/dist/config/signals.d.ts +0 -82
  175. package/dist/config/signals.d.ts.map +0 -1
  176. package/dist/functions/_shared/agent-runner.d.ts +0 -156
  177. package/dist/functions/_shared/agent-runner.d.ts.map +0 -1
  178. package/dist/functions/_shared/app-manifest.d.ts +0 -68
  179. package/dist/functions/_shared/app-manifest.d.ts.map +0 -1
  180. package/dist/functions/_shared/audit.d.ts +0 -91
  181. package/dist/functions/_shared/audit.d.ts.map +0 -1
  182. package/dist/functions/_shared/db.d.ts +0 -125
  183. package/dist/functions/_shared/db.d.ts.map +0 -1
  184. package/dist/functions/_shared/index.d.ts +0 -299
  185. package/dist/functions/_shared/index.d.ts.map +0 -1
  186. package/dist/functions/_shared/middleware.d.ts +0 -315
  187. package/dist/functions/_shared/middleware.d.ts.map +0 -1
  188. package/dist/functions/_shared/permissions.d.ts +0 -626
  189. package/dist/functions/_shared/permissions.d.ts.map +0 -1
  190. package/dist/functions/_shared/pipeline-runner.d.ts +0 -124
  191. package/dist/functions/_shared/pipeline-runner.d.ts.map +0 -1
  192. package/dist/functions/_shared/principal.d.ts +0 -284
  193. package/dist/functions/_shared/principal.d.ts.map +0 -1
  194. package/dist/functions/_shared/resolve-ids.d.ts +0 -10
  195. package/dist/functions/_shared/resolve-ids.d.ts.map +0 -1
  196. package/dist/functions/_shared/schema-utils.d.ts +0 -181
  197. package/dist/functions/_shared/schema-utils.d.ts.map +0 -1
  198. package/dist/functions/_shared/testing.d.ts +0 -172
  199. package/dist/functions/_shared/testing.d.ts.map +0 -1
  200. package/dist/functions/_shared/trigger-engine.d.ts +0 -140
  201. package/dist/functions/_shared/trigger-engine.d.ts.map +0 -1
  202. package/dist/functions/_shared/webhook-registration.d.ts +0 -81
  203. package/dist/functions/_shared/webhook-registration.d.ts.map +0 -1
  204. package/dist/functions/_shared/webhook-registry.d.ts +0 -41
  205. package/dist/functions/_shared/webhook-registry.d.ts.map +0 -1
  206. package/dist/functions/account-nodes.d.ts +0 -48
  207. package/dist/functions/account-nodes.d.ts.map +0 -1
  208. package/dist/functions/admin-data.d.ts +0 -178
  209. package/dist/functions/admin-data.d.ts.map +0 -1
  210. package/dist/functions/ai-agents.d.ts +0 -125
  211. package/dist/functions/ai-agents.d.ts.map +0 -1
  212. package/dist/functions/api-keys.d.ts +0 -140
  213. package/dist/functions/api-keys.d.ts.map +0 -1
  214. package/dist/functions/apps.d.ts +0 -163
  215. package/dist/functions/apps.d.ts.map +0 -1
  216. package/dist/functions/auth.d.ts +0 -74
  217. package/dist/functions/auth.d.ts.map +0 -1
  218. package/dist/functions/debug-auth.d.ts +0 -33
  219. package/dist/functions/debug-auth.d.ts.map +0 -1
  220. package/dist/functions/embeddings.d.ts +0 -205
  221. package/dist/functions/embeddings.d.ts.map +0 -1
  222. package/dist/functions/handler-registry.d.ts +0 -22
  223. package/dist/functions/handler-registry.d.ts.map +0 -1
  224. package/dist/functions/integration-routes.d.ts +0 -45
  225. package/dist/functions/integration-routes.d.ts.map +0 -1
  226. package/dist/functions/integrations.d.ts +0 -124
  227. package/dist/functions/integrations.d.ts.map +0 -1
  228. package/dist/functions/item-progress.d.ts +0 -41
  229. package/dist/functions/item-progress.d.ts.map +0 -1
  230. package/dist/functions/logs.d.ts +0 -162
  231. package/dist/functions/logs.d.ts.map +0 -1
  232. package/dist/functions/observability.d.ts +0 -123
  233. package/dist/functions/observability.d.ts.map +0 -1
  234. package/dist/functions/pipeline-executions.d.ts +0 -190
  235. package/dist/functions/pipeline-executions.d.ts.map +0 -1
  236. package/dist/functions/pipelines.d.ts +0 -171
  237. package/dist/functions/pipelines.d.ts.map +0 -1
  238. package/dist/functions/prompt-configs.d.ts +0 -125
  239. package/dist/functions/prompt-configs.d.ts.map +0 -1
  240. package/dist/functions/roles.d.ts +0 -118
  241. package/dist/functions/roles.d.ts.map +0 -1
  242. package/dist/functions/signal.d.ts +0 -73
  243. package/dist/functions/signal.d.ts.map +0 -1
  244. package/dist/functions/system-cron.d.ts +0 -65
  245. package/dist/functions/system-cron.d.ts.map +0 -1
  246. package/dist/functions/system.d.ts +0 -29
  247. package/dist/functions/system.d.ts.map +0 -1
  248. package/dist/functions/tests.d.ts +0 -28
  249. package/dist/functions/tests.d.ts.map +0 -1
  250. package/dist/functions/timers.d.ts +0 -139
  251. package/dist/functions/timers.d.ts.map +0 -1
  252. package/dist/functions/triggers.d.ts +0 -203
  253. package/dist/functions/triggers.d.ts.map +0 -1
  254. package/dist/functions/types.d.ts +0 -151
  255. package/dist/functions/types.d.ts.map +0 -1
  256. package/dist/src/types/types.d.ts +0 -364
  257. package/dist/src/types/types.d.ts.map +0 -1
  258. package/index.html +0 -13
  259. package/netlify.toml +0 -36
  260. package/package-project.json +0 -71
  261. package/scripts/ingest-chunks.cjs +0 -202
  262. package/scripts/kb-chunk-parser.cjs +0 -312
  263. package/scripts/kb-chunk-parser.ts +0 -330
  264. package/scripts/load-test-app-install.ts +0 -484
  265. package/scripts/netlify-dev-wrapper.sh +0 -22
  266. package/vitest.config.ts +0 -45
  267. /package/{scripts → .framework/scripts}/app-install-cli.ts +0 -0
  268. /package/{scripts → .framework/scripts}/build-manifest.sh +0 -0
  269. /package/{scripts → .framework/scripts}/verify-integrity.sh +0 -0
@@ -1,484 +0,0 @@
1
- #!/usr/bin/env tsx
2
-
3
- /**
4
- * Load Testing for App Installation System
5
- * Tests performance with large installations and concurrent operations
6
- */
7
-
8
- import { readFileSync, existsSync } from 'fs'
9
- import { resolve, dirname } from 'path'
10
- import { program } from 'commander'
11
- import yaml from 'js-yaml'
12
- import { performance } from 'perf_hooks'
13
-
14
- // Fix __dirname for ES modules
15
- import { fileURLToPath } from 'url'
16
- const __filename = fileURLToPath(import.meta.url)
17
- const __dirname = dirname(__filename)
18
-
19
- interface LoadTestConfig {
20
- concurrentInstalls: number
21
- totalApps: number
22
- appComplexity: 'simple' | 'medium' | 'complex'
23
- testDuration: number // seconds
24
- reportInterval: number // seconds
25
- }
26
-
27
- interface TestResult {
28
- appId: string
29
- startTime: number
30
- endTime: number
31
- duration: number
32
- success: boolean
33
- error?: string
34
- steps: {
35
- validation: number
36
- packInstallation: number
37
- appCreation: number
38
- migrations: number
39
- verification: number
40
- }
41
- }
42
-
43
- interface LoadTestReport {
44
- config: LoadTestConfig
45
- results: TestResult[]
46
- summary: {
47
- totalTests: number
48
- successfulTests: number
49
- failedTests: number
50
- averageDuration: number
51
- minDuration: number
52
- maxDuration: number
53
- throughput: number // tests per second
54
- errors: Array<{ error: string; count: number }>
55
- }
56
- performance: {
57
- validation: { avg: number; min: number; max: number }
58
- packInstallation: { avg: number; min: number; max: number }
59
- appCreation: { avg: number; min: number; max: number }
60
- migrations: { avg: number; min: number; max: number }
61
- verification: { avg: number; min: number; max: number }
62
- }
63
- }
64
-
65
- class LoadTestRunner {
66
- private config: LoadTestConfig
67
- private results: TestResult[] = []
68
- private running = false
69
- private startTime = 0
70
-
71
- constructor(config: LoadTestConfig) {
72
- this.config = config
73
- }
74
-
75
- /**
76
- * Generate test app installation YAML
77
- */
78
- private generateTestApp(index: number): string {
79
- const complexity = this.config.appComplexity
80
- const baseApp = {
81
- app: {
82
- name: `Load Test App ${index}`,
83
- slug: `load-test-app-${index}`,
84
- version: "1.0.0",
85
- external_app_id: `load-test-${index}`,
86
- description: `Load testing app ${index}`,
87
- author: "Load Test Runner"
88
- },
89
- installation: {
90
- pack_installation: {
91
- account_id: "${TARGET_ACCOUNT_ID}",
92
- external_app_id: `load-test-${index}`,
93
- external_app_version: "1.0.0",
94
- install_mode: "full",
95
- manifest_version: 1
96
- },
97
- app_creation: [
98
- {
99
- slug: `load-test-app-${index}`,
100
- name: `Load Test App ${index}`,
101
- installed_pack_id: "${PACK_INSTALLATION_ID}",
102
- min_role: "member",
103
- nav_items: [
104
- {
105
- key: "dashboard",
106
- to: `/load-test-${index}`,
107
- label: "Dashboard",
108
- icon: "layout-dashboard",
109
- min_role: "member"
110
- }
111
- ]
112
- }
113
- ],
114
- migrations: [],
115
- verification: [
116
- { check: "app_definition_exists", slug: `load-test-app-${index}` }
117
- ]
118
- }
119
- }
120
-
121
- // Add complexity-based migrations
122
- if (complexity === 'medium') {
123
- baseApp.installation.migrations = [
124
- {
125
- file: `migrations/001_app_${index}_setup.sql`,
126
- description: `Create app ${index} item types and views`,
127
- rollback_file: `migrations/rollback_001_app_${index}_setup.sql`
128
- },
129
- {
130
- file: `migrations/002_app_${index}_data.sql`,
131
- description: `Seed app ${index} categories and templates`,
132
- dependencies: [`001_app_${index}_setup`]
133
- }
134
- ]
135
- baseApp.installation.verification.push(
136
- { check: "item_type_exists", slug: `app_${index}_item` },
137
- { check: "view_exists", slug: `app_${index}_dashboard` }
138
- )
139
- } else if (complexity === 'complex') {
140
- baseApp.installation.migrations = [
141
- {
142
- file: `migrations/001_app_${index}_setup.sql`,
143
- description: `Create app ${index} item types and views`,
144
- rollback_file: `migrations/rollback_001_app_${index}_setup.sql`
145
- },
146
- {
147
- file: `migrations/002_app_${index}_tables.sql`,
148
- description: `Create app ${index} custom tables`,
149
- dependencies: [`001_app_${index}_setup`]
150
- },
151
- {
152
- file: `migrations/003_app_${index}_data.sql`,
153
- description: `Seed app ${index} categories and templates`,
154
- dependencies: [`001_app_${index}_setup`, `002_app_${index}_tables`]
155
- },
156
- {
157
- file: `migrations/004_app_${index}_automations.sql`,
158
- description: `Create app ${index} automation rules`,
159
- dependencies: [`002_app_${index}_tables`, `003_app_${index}_data`]
160
- }
161
- ]
162
- baseApp.installation.verification.push(
163
- { check: "item_type_exists", slug: `app_${index}_item` },
164
- { check: "view_exists", slug: `app_${index}_dashboard` },
165
- { check: "view_exists", slug: `app_${index}_list` },
166
- { check: "integration_exists", integration_id: `app_${index}_integration` }
167
- )
168
- baseApp.installation.app_creation[0].nav_items.push(
169
- { key: "list", to: `/load-test-${index}/list`, label: "List", icon: "list", min_role: "member" },
170
- { key: "settings", to: `/load-test-${index}/settings`, label: "Settings", icon: "settings", min_role: "admin" }
171
- )
172
- }
173
-
174
- return yaml.dump(baseApp)
175
- }
176
-
177
- /**
178
- * Simulate app installation steps
179
- */
180
- private async simulateInstallation(appIndex: number): Promise<TestResult> {
181
- const result: TestResult = {
182
- appId: `load-test-app-${appIndex}`,
183
- startTime: performance.now(),
184
- endTime: 0,
185
- duration: 0,
186
- success: false,
187
- steps: {
188
- validation: 0,
189
- packInstallation: 0,
190
- appCreation: 0,
191
- migrations: 0,
192
- verification: 0
193
- }
194
- }
195
-
196
- try {
197
- // Generate test app YAML
198
- const appYaml = this.generateTestApp(appIndex)
199
-
200
- // Step 1: Validation (simulate schema validation)
201
- const validationStart = performance.now()
202
- await this.simulateValidation(appYaml)
203
- result.steps.validation = performance.now() - validationStart
204
-
205
- // Step 2: Pack Installation
206
- const packStart = performance.now()
207
- await this.simulatePackInstallation(result.appId)
208
- result.steps.packInstallation = performance.now() - packStart
209
-
210
- // Step 3: App Creation
211
- const appStart = performance.now()
212
- await this.simulateAppCreation(result.appId)
213
- result.steps.appCreation = performance.now() - appStart
214
-
215
- // Step 4: Migrations
216
- const migrationsStart = performance.now()
217
- const migrationCount = this.config.appComplexity === 'simple' ? 0 :
218
- this.config.appComplexity === 'medium' ? 2 : 4
219
- await this.simulateMigrations(result.appId, migrationCount)
220
- result.steps.migrations = performance.now() - migrationsStart
221
-
222
- // Step 5: Verification
223
- const verificationStart = performance.now()
224
- const verificationCount = this.config.appComplexity === 'simple' ? 1 :
225
- this.config.appComplexity === 'medium' ? 3 : 5
226
- await this.simulateVerification(result.appId, verificationCount)
227
- result.steps.verification = performance.now() - verificationStart
228
-
229
- result.success = true
230
- } catch (error) {
231
- result.error = error instanceof Error ? error.message : String(error)
232
- }
233
-
234
- result.endTime = performance.now()
235
- result.duration = result.endTime - result.startTime
236
-
237
- return result
238
- }
239
-
240
- /**
241
- * Simulate validation step
242
- */
243
- private async simulateValidation(appYaml: string): Promise<void> {
244
- // Simulate YAML parsing and schema validation
245
- const complexity = this.config.appComplexity
246
- const delay = complexity === 'simple' ? 10 : complexity === 'medium' ? 25 : 50
247
-
248
- await this.sleep(delay)
249
-
250
- // Parse YAML to simulate actual validation work
251
- yaml.load(appYaml)
252
- }
253
-
254
- /**
255
- * Simulate pack installation
256
- */
257
- private async simulatePackInstallation(appId: string): Promise<void> {
258
- // Simulate database insert for installed_packs
259
- const complexity = this.config.appComplexity
260
- const delay = complexity === 'simple' ? 20 : complexity === 'medium' ? 40 : 80
261
-
262
- await this.sleep(delay)
263
- }
264
-
265
- /**
266
- * Simulate app creation
267
- */
268
- private async simulateAppCreation(appId: string): Promise<void> {
269
- // Simulate app_definitions creation
270
- const complexity = this.config.appComplexity
271
- const delay = complexity === 'simple' ? 15 : complexity === 'medium' ? 30 : 60
272
-
273
- await this.sleep(delay)
274
- }
275
-
276
- /**
277
- * Simulate migrations
278
- */
279
- private async simulateMigrations(appId: string, count: number): Promise<void> {
280
- // Simulate running SQL migrations
281
- for (let i = 0; i < count; i++) {
282
- const delay = this.config.appComplexity === 'simple' ? 10 :
283
- this.config.appComplexity === 'medium' ? 25 : 50
284
- await this.sleep(delay)
285
- }
286
- }
287
-
288
- /**
289
- * Simulate verification steps
290
- */
291
- private async simulateVerification(appId: string, count: number): Promise<void> {
292
- // Simulate verification checks
293
- for (let i = 0; i < count; i++) {
294
- await this.sleep(5)
295
- }
296
- }
297
-
298
- /**
299
- * Sleep helper
300
- */
301
- private sleep(ms: number): Promise<void> {
302
- return new Promise(resolve => setTimeout(resolve, ms))
303
- }
304
-
305
- /**
306
- * Run concurrent load test
307
- */
308
- async runLoadTest(): Promise<LoadTestReport> {
309
- console.log(`🚀 Starting load test...`)
310
- console.log(`Configuration:`, this.config)
311
-
312
- this.running = true
313
- this.startTime = performance.now()
314
- this.results = []
315
-
316
- const concurrentBatches = Math.ceil(this.config.totalApps / this.config.concurrentInstalls)
317
-
318
- for (let batch = 0; batch < concurrentBatches; batch++) {
319
- const startIndex = batch * this.config.concurrentInstalls
320
- const endIndex = Math.min(startIndex + this.config.concurrentInstalls, this.config.totalApps)
321
- const batchSize = endIndex - startIndex
322
-
323
- console.log(`📦 Running batch ${batch + 1}/${concurrentBatches} (${batchSize} apps)`)
324
-
325
- // Run installations concurrently
326
- const batchPromises = []
327
- for (let i = startIndex; i < endIndex; i++) {
328
- batchPromises.push(this.simulateInstallation(i))
329
- }
330
-
331
- const batchResults = await Promise.all(batchPromises)
332
- this.results.push(...batchResults)
333
-
334
- // Report progress
335
- const completed = this.results.length
336
- const successRate = (this.results.filter(r => r.success).length / this.results.length * 100).toFixed(1)
337
- console.log(`✅ Completed ${completed}/${this.config.totalApps} apps (${successRate}% success rate)`)
338
-
339
- // Check if we should stop due to time limit
340
- const elapsed = (performance.now() - this.startTime) / 1000
341
- if (elapsed >= this.config.testDuration) {
342
- console.log(`⏰ Time limit reached, stopping test`)
343
- break
344
- }
345
- }
346
-
347
- this.running = false
348
- return this.generateReport()
349
- }
350
-
351
- /**
352
- * Generate comprehensive report
353
- */
354
- private generateReport(): LoadTestReport {
355
- const successfulTests = this.results.filter(r => r.success)
356
- const failedTests = this.results.filter(r => !r.success)
357
-
358
- const durations = successfulTests.map(r => r.duration)
359
- const avgDuration = durations.length > 0 ? durations.reduce((a, b) => a + b, 0) / durations.length : 0
360
- const minDuration = durations.length > 0 ? Math.min(...durations) : 0
361
- const maxDuration = durations.length > 0 ? Math.max(...durations) : 0
362
-
363
- const totalElapsed = (performance.now() - this.startTime) / 1000
364
- const throughput = this.results.length / totalElapsed
365
-
366
- // Error aggregation
367
- const errorMap = new Map<string, number>()
368
- for (const test of failedTests) {
369
- const error = test.error || 'Unknown error'
370
- errorMap.set(error, (errorMap.get(error) || 0) + 1)
371
- }
372
-
373
- const errors = Array.from(errorMap.entries()).map(([error, count]) => ({ error, count }))
374
-
375
- // Step performance analysis
376
- const stepPerformance = {
377
- validation: this.calculateStepPerformance('validation'),
378
- packInstallation: this.calculateStepPerformance('packInstallation'),
379
- appCreation: this.calculateStepPerformance('appCreation'),
380
- migrations: this.calculateStepPerformance('migrations'),
381
- verification: this.calculateStepPerformance('verification')
382
- }
383
-
384
- return {
385
- config: this.config,
386
- results: this.results,
387
- summary: {
388
- totalTests: this.results.length,
389
- successfulTests: successfulTests.length,
390
- failedTests: failedTests.length,
391
- averageDuration: avgDuration,
392
- minDuration,
393
- maxDuration,
394
- throughput,
395
- errors
396
- },
397
- performance: stepPerformance
398
- }
399
- }
400
-
401
- /**
402
- * Calculate performance metrics for a specific step
403
- */
404
- private calculateStepPerformance(step: keyof TestResult['steps']) {
405
- const values = this.results.filter(r => r.success).map(r => r.steps[step])
406
- return {
407
- avg: values.length > 0 ? values.reduce((a, b) => a + b, 0) / values.length : 0,
408
- min: values.length > 0 ? Math.min(...values) : 0,
409
- max: values.length > 0 ? Math.max(...values) : 0
410
- }
411
- }
412
- }
413
-
414
- /**
415
- * Pretty print report
416
- */
417
- function printReport(report: LoadTestReport): void {
418
- console.log('\n' + '='.repeat(80))
419
- console.log('📊 LOAD TEST REPORT')
420
- console.log('='.repeat(80))
421
-
422
- console.log('\n🔧 Configuration:')
423
- console.log(` Concurrent Installs: ${report.config.concurrentInstalls}`)
424
- console.log(` Total Apps: ${report.config.totalApps}`)
425
- console.log(` App Complexity: ${report.config.appComplexity}`)
426
- console.log(` Test Duration: ${report.config.testDuration}s`)
427
-
428
- console.log('\n📈 Summary:')
429
- console.log(` Total Tests: ${report.summary.totalTests}`)
430
- console.log(` Successful: ${report.summary.successfulTests} (${(report.summary.successfulTests / report.summary.totalTests * 100).toFixed(1)}%)`)
431
- console.log(` Failed: ${report.summary.failedTests} (${(report.summary.failedTests / report.summary.totalTests * 100).toFixed(1)}%)`)
432
- console.log(` Average Duration: ${report.summary.averageDuration.toFixed(2)}ms`)
433
- console.log(` Min Duration: ${report.summary.minDuration.toFixed(2)}ms`)
434
- console.log(` Max Duration: ${report.summary.maxDuration.toFixed(2)}ms`)
435
- console.log(` Throughput: ${report.summary.throughput.toFixed(2)} tests/second`)
436
-
437
- if (report.summary.errors.length > 0) {
438
- console.log('\n❌ Errors:')
439
- report.summary.errors.forEach(({ error, count }) => {
440
- console.log(` ${error}: ${count}`)
441
- })
442
- }
443
-
444
- console.log('\n⚡ Step Performance:')
445
- Object.entries(report.performance).forEach(([step, perf]) => {
446
- console.log(` ${step}:`)
447
- console.log(` Avg: ${perf.avg.toFixed(2)}ms`)
448
- console.log(` Min: ${perf.min.toFixed(2)}ms`)
449
- console.log(` Max: ${perf.max.toFixed(2)}ms`)
450
- })
451
-
452
- console.log('\n' + '='.repeat(80))
453
- }
454
-
455
- // CLI setup
456
- program
457
- .name('load-test-app-install')
458
- .description('Load testing for Spine app installation system')
459
- .version('1.0.0')
460
- .option('-c, --concurrent <number>', 'Number of concurrent installations', '10')
461
- .option('-t, --total <number>', 'Total number of apps to install', '100')
462
- .option('-x, --complexity <type>', 'App complexity (simple, medium, complex)', 'medium')
463
- .option('-d, --duration <seconds>', 'Maximum test duration in seconds', '300')
464
- .option('-r, --report-interval <seconds>', 'Progress report interval', '10')
465
- .action(async (options) => {
466
- const config: LoadTestConfig = {
467
- concurrentInstalls: parseInt(options.concurrent),
468
- totalApps: parseInt(options.total),
469
- appComplexity: options.complexity as 'simple' | 'medium' | 'complex',
470
- testDuration: parseInt(options.duration),
471
- reportInterval: parseInt(options.reportInterval)
472
- }
473
-
474
- const runner = new LoadTestRunner(config)
475
- const report = await runner.runLoadTest()
476
- printReport(report)
477
-
478
- // Exit with error code if there were failures
479
- if (report.summary.failedTests > 0) {
480
- process.exit(1)
481
- }
482
- })
483
-
484
- program.parse()
@@ -1,22 +0,0 @@
1
- #!/usr/bin/env bash
2
-
3
- # Netlify Dev Wrapper - Start dev server for Spine.
4
- #
5
- # Purpose: Execute Vite directly to avoid npx/npm indirection issues under Netlify CLI.
6
- # - Called by: netlify dev (via netlify.toml [dev].command)
7
- # - .framework/ is the working core directory
8
- #
9
- # Integration: Part of the development workflow, bridges Netlify CLI and Vite.
10
- #
11
- # Dependencies: vite, netlify CLI
12
-
13
- set -euo pipefail
14
-
15
- SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
16
- PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
17
-
18
- echo "Starting Netlify dev for Spine..."
19
-
20
- # Start Vite dev server directly (.assembled/src is now the root)
21
- echo " Starting Vite on port 3001..."
22
- exec "$PROJECT_ROOT/node_modules/.bin/vite" --config "$PROJECT_ROOT/config/vite.config.ts"
package/vitest.config.ts DELETED
@@ -1,45 +0,0 @@
1
- import { defineConfig } from 'vitest/config'
2
- import { readFileSync, existsSync } from 'fs'
3
- import { resolve } from 'path'
4
-
5
- // Load .xenv.test so integration tests get real DB credentials before any
6
- // worker module graph (db.ts, principal.ts) evaluates createClient() calls.
7
- const xenvTest = resolve(__dirname, '.framework/.xenv.test')
8
- if (existsSync(xenvTest)) {
9
- for (const line of readFileSync(xenvTest, 'utf8').split('\n')) {
10
- const t = line.trim()
11
- if (!t || t.startsWith('#')) continue
12
- const eq = t.indexOf('=')
13
- if (eq === -1) continue
14
- const k = t.slice(0, eq).trim()
15
- const v = t.slice(eq + 1).trim().replace(/^["']|["']$/g, '')
16
- if (!process.env[k]) process.env[k] = v
17
- }
18
- }
19
-
20
- export default defineConfig({
21
- test: {
22
- // Stub SUPABASE_URL etc. before any module is imported
23
- setupFiles: ['.framework/tests/setup.ts'],
24
- // Each test file gets its own module instance (important for vi.mock isolation)
25
- isolate: true,
26
- // Allow .ts extension imports (tsx-style)
27
- environment: 'node',
28
- // Resolve .ts imports as themselves (no .js→.ts rewriting needed in tests)
29
- include: [
30
- '.framework/tests/unit/**/*.test.ts',
31
- '.framework/tests/integration/**/*.test.ts',
32
- '.framework/tests/api/**/*.test.ts'
33
- ],
34
- // Global test timeout — integration + API tests may hit Supabase / local server
35
- testTimeout: 20000,
36
- // Don't fail the suite on integration tests if env isn't configured
37
- passWithNoTests: true,
38
- // Persist results to public.test_runs after every run
39
- reporters: ['default', './.framework/tests/reporter.ts']
40
- },
41
- resolve: {
42
- // Allow bare .ts imports (the CLI + shared code uses these)
43
- extensions: ['.ts', '.js', '.json']
44
- }
45
- })