forgecad 0.9.13 → 0.9.15

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 (216) hide show
  1. package/LICENSE +6 -4
  2. package/README.md +8 -4
  3. package/dist/assets/{AdminPage-DramHHDf.js → AdminPage-CDyGUinA.js} +2 -2
  4. package/dist/assets/{BenchmarkPage-Bjgkh5m9.js → BenchmarkPage-DfPMY_-d.js} +4 -15
  5. package/dist/assets/{BlogPage-n_HGP3Qm.js → BlogPage-kF0fkdJT.js} +2 -2
  6. package/dist/assets/{DocsPage-WCIkPmzC.js → DocsPage-B954L3YN.js} +9 -3
  7. package/dist/assets/EditorApp-Beb-IZ0y.js +14014 -0
  8. package/dist/assets/{EditorApp-BAnckbsk.css → EditorApp-CuDLxKqL.css} +698 -0
  9. package/dist/assets/{EmbedViewer-DEZKqdfW.js → EmbedViewer-C77B-TrF.js} +3 -3
  10. package/dist/assets/{LandingPageProofDriven-CeRIctuj.js → LandingPageProofDriven-Cr6fXMDj.js} +35 -37
  11. package/dist/assets/LegalPage-BRlScr9A.css +91 -0
  12. package/dist/assets/LegalPage-Dzklqmmg.js +39 -0
  13. package/dist/assets/{PricingPage-BMedqFef.css → PricingPage-BPF6HKyO.css} +25 -0
  14. package/dist/assets/{PricingPage-rIRa8p4Y.js → PricingPage-zWXkvlwl.js} +19 -19
  15. package/dist/assets/{SettingsPage-BqCUvEXM.js → SettingsPage-Bz0of4KQ.js} +2 -2
  16. package/dist/assets/app-CE3sYcV7.css +3890 -0
  17. package/dist/assets/{app-BUZqJvSO.js → app-D3kDkggg.js} +2305 -960
  18. package/dist/assets/cli/{render-lhGxj50Y.js → render-DSY3mMQa.js} +423 -30
  19. package/dist/assets/{constructionHistoryWorker-ipD1jcIv.js → constructionHistoryWorker-gpDo-uH2.js} +927 -243
  20. package/dist/assets/{evalWorker-CHXSe_-u.js → evalWorker-CU0Ke6DP.js} +7799 -4163
  21. package/dist/assets/{forgecad_geometry-BVnIeXMG.js → forgecad_geometry-Dgceylq9.js} +43 -1
  22. package/dist/assets/{forgecad_geometry_bg-DufhhCBV.wasm → forgecad_geometry_bg-dD4RNQF1.wasm} +0 -0
  23. package/dist/assets/{inspectWorker-DeRnMVv1.js → inspectWorker-COyp8XXA.js} +927 -243
  24. package/dist/assets/{javascript-70-4uGcz.js → javascript-1kQXfVaz.js} +1 -1
  25. package/dist/assets/landing-proof-driven-DiGqdtWa.js +18 -0
  26. package/dist/assets/{landing-proof-driven-oFYW6mjz.css → landing-proof-driven-ORyigZ6p.css} +13 -7
  27. package/dist/assets/legalContent-ZfFGMmi4.js +251 -0
  28. package/dist/assets/{manifold-D1LZIHqn.js → manifold-BRI5prcH.js} +1 -1
  29. package/dist/assets/{manifold-C2fwoTgd.js → manifold-C-3h2M7p.js} +2 -2
  30. package/dist/assets/{manifold-BTkzxi9V.js → manifold-DNkrUWpA.js} +1 -1
  31. package/dist/assets/{reportWorker-Cq1qGmg0.js → reportWorker-CdBz5bNg.js} +7537 -10856
  32. package/dist/assets/{scalar-sampling-budget-D9Qv_UlJ.js → scalar-sampling-budget-wJF98aY9.js} +6943 -4345
  33. package/dist/assets/{scanProxyWorker-Bs2TDgLw.js → scanProxyWorker-B-9VbLIs.js} +32 -1
  34. package/dist/assets/{renderSceneState-Dr0xPq1A.js → targets-B9sGB5nB.js} +27 -1
  35. package/dist/assets/{vendor-react-Da3A2QmU.js → vendor-react-6j1Kke-Y.js} +6 -5
  36. package/dist/cli/render.html +1 -1
  37. package/dist/docs/index.html +2 -2
  38. package/dist/docs-raw/AI/ai-native-cad.md +50 -0
  39. package/dist/docs-raw/AI/usage.md +9 -17
  40. package/dist/docs-raw/CLI.md +71 -21
  41. package/dist/docs-raw/component-model.md +27 -11
  42. package/dist/docs-raw/generated/assembly.md +301 -212
  43. package/dist/docs-raw/generated/concepts.md +238 -240
  44. package/dist/docs-raw/generated/core.md +283 -6
  45. package/dist/docs-raw/generated/curves.md +274 -361
  46. package/dist/docs-raw/generated/lib.md +7 -1
  47. package/dist/docs-raw/generated/output.md +19 -4
  48. package/dist/docs-raw/generated/runtime-names.md +41 -0
  49. package/dist/docs-raw/generated/sdf.md +31 -0
  50. package/dist/docs-raw/generated/sheet-metal.md +9 -0
  51. package/dist/docs-raw/generated/sketch.md +44 -1
  52. package/dist/docs-raw/generated/viewport.md +14 -6
  53. package/dist/docs-raw/guides/coordinate-system.md +20 -16
  54. package/dist/docs-raw/guides/geometry-conventions.md +2 -2
  55. package/dist/docs-raw/guides/inspection-bundles.md +2 -1
  56. package/dist/docs-raw/guides/joint-design.md +24 -0
  57. package/dist/docs-raw/guides/positioning.md +13 -3
  58. package/dist/docs-raw/legal/privacy.md +63 -0
  59. package/dist/docs-raw/legal/software-license.md +55 -0
  60. package/dist/docs-raw/legal/terms.md +87 -0
  61. package/dist/docs-raw/skills/forgecad-3d-reconstruction.md +3 -3
  62. package/dist/docs-raw/skills/forgecad-blockout-model.md +1 -1
  63. package/dist/docs-raw/skills/forgecad-component-model.md +11 -2
  64. package/dist/docs-raw/skills/forgecad-high-level-spec.md +1 -1
  65. package/dist/docs-raw/skills/forgecad-image-replicator.md +8 -8
  66. package/dist/docs-raw/skills/forgecad-lld.md +1 -1
  67. package/dist/docs-raw/skills/forgecad-make-a-model.md +4 -4
  68. package/dist/docs-raw/skills/forgecad-model-grader.md +2 -2
  69. package/dist/docs-raw/skills/forgecad-prepare-prompt.md +2 -2
  70. package/dist/docs-raw/skills/forgecad-project.md +1 -1
  71. package/dist/docs-raw/skills/forgecad-reconstruction-benchmark.md +4 -4
  72. package/dist/docs-raw/skills/forgecad-render-inspect.md +4 -2
  73. package/dist/docs-raw/skills/forgecad-visual-spec.md +1 -1
  74. package/dist/docs-raw/skills/forgecad.md +4 -3
  75. package/dist/index.html +40 -12
  76. package/dist/llms.txt +8 -0
  77. package/dist/site.webmanifest +1 -1
  78. package/dist/sitemap.xml +49 -13
  79. package/dist-cli/{check-compiler-LOXCPEOI.js → check-compiler-SDX5QIXI.js} +1 -2
  80. package/dist-cli/{check-query-propagation-BAKNVWXR.js → check-query-propagation-EAYEFT77.js} +1 -2
  81. package/dist-cli/{chunk-RY43WF46.js → chunk-N4O47JLF.js} +13772 -9938
  82. package/dist-cli/forgecad.js +2387 -899
  83. package/dist-cli/{forgecad_geometry-GYVNKPIE.js → forgecad_geometry-QOQIIP53.js} +42 -1
  84. package/dist-cli/forgecad_geometry_bg.wasm +0 -0
  85. package/dist-cli/{solver-46FFSK2U.js → solver-OK4HECRH.js} +0 -1
  86. package/dist-skill/CONTEXT.md +1120 -724
  87. package/dist-skill/SKILL.md +3 -2
  88. package/dist-skill/docs/API/core/concepts.md +64 -1
  89. package/dist-skill/docs/CLI.md +71 -21
  90. package/dist-skill/docs/generated/assembly.md +277 -229
  91. package/dist-skill/docs/generated/core.md +283 -6
  92. package/dist-skill/docs/generated/curves.md +272 -362
  93. package/dist-skill/docs/generated/lib.md +7 -1
  94. package/dist-skill/docs/generated/output.md +19 -4
  95. package/dist-skill/docs/generated/runtime-names.md +41 -0
  96. package/dist-skill/docs/generated/sdf.md +31 -0
  97. package/dist-skill/docs/generated/sheet-metal.md +9 -0
  98. package/dist-skill/docs/generated/sketch.md +44 -2
  99. package/dist-skill/docs/generated/viewport.md +5 -90
  100. package/dist-skill/docs/guides/coordinate-system.md +20 -16
  101. package/dist-skill/docs/guides/geometry-conventions.md +2 -2
  102. package/dist-skill/docs/guides/inspection-bundles.md +2 -1
  103. package/dist-skill/docs/guides/joint-design.md +24 -0
  104. package/dist-skill/docs/guides/positioning.md +13 -3
  105. package/dist-skill/library/forgecad-3d-reconstruction/SKILL.md +2 -2
  106. package/dist-skill/library/forgecad-component-model/SKILL.md +10 -1
  107. package/dist-skill/library/forgecad-image-replicator/SKILL.md +6 -6
  108. package/dist-skill/library/forgecad-image-replicator/scripts/compare_images.py +166 -0
  109. package/dist-skill/library/forgecad-make-a-model/SKILL.md +3 -3
  110. package/dist-skill/library/forgecad-model-grader/SKILL.md +1 -1
  111. package/dist-skill/library/forgecad-prepare-prompt/SKILL.md +1 -1
  112. package/dist-skill/library/forgecad-reconstruction-benchmark/SKILL.md +3 -3
  113. package/dist-skill/library/forgecad-render-inspect/SKILL.md +3 -1
  114. package/examples/api/assembly-kinematics-foundation.forge.js +65 -0
  115. package/examples/api/assembly-kinematics-four-bar.forge.js +115 -0
  116. package/examples/api/assembly-kinematics-limb.forge.js +116 -0
  117. package/examples/api/connector-frame-rig-chain.forge.js +102 -0
  118. package/examples/api/exact-sheet-shell-assembly.forge.js +0 -2
  119. package/examples/api/exact-surface-studio.forge.js +6 -8
  120. package/examples/api/helix-basics.forge.js +6 -6
  121. package/examples/api/lean-foundations/README.md +12 -0
  122. package/examples/api/lean-foundations/curve-blend-exact.forge.js +22 -0
  123. package/examples/api/lean-foundations/curve-fit-interpolation.forge.js +18 -0
  124. package/examples/api/lean-foundations/curve-helix-canonicalization.forge.js +27 -0
  125. package/examples/api/lean-foundations/curve-route-canonicalization.forge.js +16 -0
  126. package/examples/api/lean-foundations/curve-trim-reverse.forge.js +24 -0
  127. package/examples/api/lean-foundations/exact-curve-arc.forge.js +36 -0
  128. package/examples/api/mixed-edge-finishes-proof.forge.js +8 -11
  129. package/examples/api/route3d-elbow.forge.js +68 -0
  130. package/examples/api/transition-curves.forge.js +44 -15
  131. package/examples/api/y-blend-corner-showcase.forge.js +0 -2
  132. package/examples/generative/coral-vase.forge.js +1 -1
  133. package/examples/nurbs-tube.forge.js +1 -1
  134. package/package.json +14 -18
  135. package/dist/assets/EditorApp-CP9Za6tm.js +0 -13630
  136. package/dist/assets/app-CsHnaBWt.css +0 -1789
  137. package/dist/docs-raw/API/README.md +0 -16
  138. package/dist/docs-raw/API/core/concepts.md +0 -118
  139. package/dist/docs-raw/INDEX.md +0 -138
  140. package/dist/docs-raw/RELEASING.md +0 -87
  141. package/dist/docs-raw/agent-native-api.md +0 -27
  142. package/dist/docs-raw/beta-deployment.md +0 -304
  143. package/dist/docs-raw/beta-operations.md +0 -325
  144. package/dist/docs-raw/blueprint-first.md +0 -145
  145. package/dist/docs-raw/cli-monetization.md +0 -112
  146. package/dist/docs-raw/coding-best-practices.md +0 -120
  147. package/dist/docs-raw/coding.md +0 -340
  148. package/dist/docs-raw/deployment.md +0 -374
  149. package/dist/docs-raw/guides/skill-maintenance.md +0 -161
  150. package/dist/docs-raw/guides/surface-members.md +0 -82
  151. package/dist/docs-raw/internals/backend-vocabulary.md +0 -35
  152. package/dist/docs-raw/internals/compiler.md +0 -307
  153. package/dist/docs-raw/internals/constraint-solver-quality.md +0 -161
  154. package/dist/docs-raw/internals/constraint-solver.md +0 -176
  155. package/dist/docs-raw/internals/shape-from-slices.md +0 -152
  156. package/dist/docs-raw/internals/sketch-2d-pipeline.md +0 -108
  157. package/dist/docs-raw/platform/admin.md +0 -45
  158. package/dist/docs-raw/platform/architecture.md +0 -82
  159. package/dist/docs-raw/platform/auth.md +0 -139
  160. package/dist/docs-raw/platform/email.md +0 -67
  161. package/dist/docs-raw/platform/google-oauth-setup.md +0 -88
  162. package/dist/docs-raw/platform/observability.md +0 -197
  163. package/dist/docs-raw/platform/projects.md +0 -111
  164. package/dist/docs-raw/platform/sharing.md +0 -90
  165. package/dist/docs-raw/product/README.md +0 -39
  166. package/dist/docs-raw/product/api-as-product-language.md +0 -13
  167. package/dist/docs-raw/product/business-model.md +0 -15
  168. package/dist/docs-raw/product/competitive-positioning.md +0 -17
  169. package/dist/docs-raw/product/creative-manufacturing.md +0 -15
  170. package/dist/docs-raw/product/founder-story.md +0 -11
  171. package/dist/docs-raw/product/manufacturing-workflows.md +0 -15
  172. package/dist/docs-raw/product/onboarding-first-experience.md +0 -256
  173. package/dist/docs-raw/product/product-loop.md +0 -17
  174. package/dist/docs-raw/product/strategic-decisions.md +0 -22
  175. package/dist/docs-raw/product/user-outreach-email-templates.md +0 -161
  176. package/dist/docs-raw/product/user-segments.md +0 -15
  177. package/dist/docs-raw/product/vision.md +0 -26
  178. package/dist/docs-raw/rl-environments.md +0 -508
  179. package/dist/docs-raw/runbook.md +0 -611
  180. package/dist-cli/check-compiler-LOXCPEOI.js.map +0 -1
  181. package/dist-cli/check-query-propagation-BAKNVWXR.js.map +0 -1
  182. package/dist-cli/chunk-RY43WF46.js.map +0 -1
  183. package/dist-cli/forgecad.js.map +0 -1
  184. package/dist-cli/forgecad_geometry-GYVNKPIE.js.map +0 -1
  185. package/dist-cli/solver-46FFSK2U.js.map +0 -1
  186. package/dist-skill/SKILL-dev.md +0 -145
  187. package/dist-skill/docs-dev/API/core/concepts.md +0 -118
  188. package/dist-skill/docs-dev/CLI.md +0 -647
  189. package/dist-skill/docs-dev/agent-native-api.md +0 -27
  190. package/dist-skill/docs-dev/blueprint-first.md +0 -145
  191. package/dist-skill/docs-dev/coding-best-practices.md +0 -120
  192. package/dist-skill/docs-dev/coding.md +0 -340
  193. package/dist-skill/docs-dev/component-model.md +0 -164
  194. package/dist-skill/docs-dev/generated/assembly.md +0 -794
  195. package/dist-skill/docs-dev/generated/core.md +0 -2117
  196. package/dist-skill/docs-dev/generated/curves.md +0 -2583
  197. package/dist-skill/docs-dev/generated/lib.md +0 -169
  198. package/dist-skill/docs-dev/generated/output.md +0 -247
  199. package/dist-skill/docs-dev/generated/sdf.md +0 -446
  200. package/dist-skill/docs-dev/generated/sheet-metal.md +0 -504
  201. package/dist-skill/docs-dev/generated/sketch.md +0 -1811
  202. package/dist-skill/docs-dev/generated/viewport.md +0 -585
  203. package/dist-skill/docs-dev/generated/wood.md +0 -108
  204. package/dist-skill/docs-dev/guides/coordinate-system.md +0 -46
  205. package/dist-skill/docs-dev/guides/geometry-conventions.md +0 -52
  206. package/dist-skill/docs-dev/guides/inspection-bundles.md +0 -485
  207. package/dist-skill/docs-dev/guides/joint-design.md +0 -78
  208. package/dist-skill/docs-dev/guides/modeling-recipes.md +0 -78
  209. package/dist-skill/docs-dev/guides/positioning.md +0 -161
  210. package/dist-skill/docs-dev/guides/skill-maintenance.md +0 -161
  211. package/dist-skill/docs-dev/internals/backend-vocabulary.md +0 -35
  212. package/dist-skill/docs-dev/internals/compiler.md +0 -307
  213. package/dist-skill/docs-dev/internals/constraint-solver-quality.md +0 -161
  214. package/dist-skill/docs-dev/internals/constraint-solver.md +0 -176
  215. package/dist-skill/docs-dev/internals/sketch-2d-pipeline.md +0 -108
  216. package/dist-skill/library/forgecad-image-replicator/scripts/compare_images.mjs +0 -289
@@ -1,197 +0,0 @@
1
- # Observability
2
-
3
- ForgeCAD uses a self-hosted observability stack on Hetzner:
4
-
5
- - Grafana for dashboards and Explore
6
- - Prometheus for metrics
7
- - Loki for logs
8
- - Alloy for Docker log collection
9
- - node-exporter and cAdvisor for host and container metrics
10
- - Uptime Kuma for black-box uptime checks
11
-
12
- ## Why this setup
13
-
14
- We explicitly do **not** use the app admin page as the primary operational surface.
15
-
16
- The goals are:
17
-
18
- - Tailscale-first private operator workflow
19
- - real dashboards and query UIs
20
- - logs and metrics on the same box
21
- - no paid SaaS requirement
22
- - minimal public exposure
23
-
24
- ## Access model
25
-
26
- Operator-facing observability ports bind only to the Hetzner host's Tailscale address, defaulting to `100.118.68.93`.
27
- Reach them directly from any authorized device on the tailnet:
28
-
29
- - Grafana: `http://100.118.68.93:3000`
30
- - Uptime Kuma: `http://100.118.68.93:3001`
31
- - Prometheus: `http://100.118.68.93:9090`
32
- - Loki: `http://100.118.68.93:3100`
33
- - Alloy UI: `http://100.118.68.93:12345`
34
-
35
- This keeps the stack private without adding a public reverse proxy or requiring an SSH tunnel for routine access.
36
- If the host's Tailscale IP changes, set `OBSERVABILITY_TAILSCALE_IP` in `/home/kostard/forgecad-observability/.env` before redeploying.
37
- The Compose file uses pinned image digests rather than floating `latest` tags so repeat deploys stay predictable.
38
-
39
- ## Deploy
40
-
41
- ```bash
42
- bash scripts/prod/observability-deploy.sh
43
- ```
44
-
45
- The deploy script:
46
-
47
- 1. syncs `ops/observability/` to `/home/kostard/forgecad-observability` on Hetzner
48
- 2. creates `/home/kostard/forgecad-observability/.env` if it does not already exist
49
- 3. pulls fresh images
50
- 4. starts the stack with `docker compose up -d`
51
-
52
- ## Check status
53
-
54
- ```bash
55
- bash scripts/prod/observability-status.sh
56
- ```
57
-
58
- ## Incident Workflow
59
-
60
- This stack is the primary way we debug production incidents.
61
-
62
- 1. Make sure your laptop is connected to Tailscale.
63
-
64
- 2. Check Uptime Kuma first:
65
-
66
- - `http://100.118.68.93:3001`
67
- - Use it to answer "is the site/API reachable from outside?" before diving into internals.
68
-
69
- 3. Check Grafana next:
70
-
71
- - `http://100.118.68.93:3000`
72
- - Start with the `ForgeCAD Host Overview` dashboard.
73
- - Then switch to `ForgeCAD Web Requests` for throughput, 4xx/5xx rate, latency, and top API routes.
74
- - Then switch to `Explore` for live investigation.
75
-
76
- 4. In Grafana Explore, use:
77
-
78
- - `Loki` when you want logs
79
- - `Prometheus` when you want metrics
80
-
81
- Useful Loki queries:
82
-
83
- ```text
84
- {container=~"forgecad-web-.*|forgecad-backend-web-.*"}
85
- {container=~"forgecad-web-.*|forgecad-backend-web-.*"} |= "error"
86
- {container=~"forgecad-web-.*|forgecad-beta-web-.*"} |= "DB slow query"
87
- {container=~"forgecad-web-.*|forgecad-beta-web-.*"} | json | event="db.query"
88
- {container=~"forgecad-beta-.*"}
89
- {container="kamal-proxy"}
90
- ```
91
-
92
- Useful Prometheus queries:
93
-
94
- ```text
95
- up
96
- node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes
97
- 100 * (1 - node_filesystem_avail_bytes{mountpoint="/",fstype!~"tmpfs|overlay"} / node_filesystem_size_bytes{mountpoint="/",fstype!~"tmpfs|overlay"})
98
- sum by (container) (rate(container_cpu_usage_seconds_total{container!=""}[5m]))
99
- sum(rate(forge_http_request_total[$__rate_interval]))
100
- sum(rate(forge_http_request_total{surface="api",status_class="5xx"}[$__rate_interval]))
101
- histogram_quantile(0.95, sum by (le) (rate(forge_http_request_duration_seconds_bucket[$__rate_interval])))
102
- topk(10, sum by (forge_env, method, route) (rate(forge_http_request_total{surface="api"}[$__rate_interval])))
103
- sum by (forge_env, operation) (rate(forge_db_query_total[$__rate_interval]))
104
- histogram_quantile(0.95, sum by (forge_env, operation, le) (rate(forge_db_query_duration_seconds_bucket[$__rate_interval])))
105
- sum by (forge_env, relation) (rate(forge_db_slow_query_total[$__rate_interval]))
106
- ```
107
-
108
- 5. Use the `ForgeCAD Web Requests` dashboard when the issue smells app-level traffic, request failures, or latency:
109
-
110
- - overall request rate
111
- - API-only request rate
112
- - 4xx and 5xx rates
113
- - P95 request latency
114
- - request concurrency
115
- - top API routes by throughput, 4xx rate, 5xx rate, and latency
116
-
117
- Health probes to `/api/health` are intentionally excluded so low-traffic charts stay focused on real user traffic instead of uptime polling.
118
-
119
- 6. Use the `ForgeCAD DB Queries` dashboard when the issue smells database-related:
120
-
121
- - Query rate by operation
122
- - P95 query latency by operation
123
- - Slow-query rate
124
- - Error-query rate
125
- - Top relations by average latency
126
- - Queries currently in flight
127
-
128
- The dashboard is backed by app-native metrics from the ForgeCAD web service, not host-level guesses.
129
-
130
- 6. Re-check prod explicitly after any restart or deploy:
131
-
132
- ```bash
133
- curl -fsS https://forgecad.io/api/health
134
- ```
135
-
136
- 7. If observability itself is degraded, fall back to SSH and direct Docker inspection:
137
-
138
- ```bash
139
- ssh hetzner
140
- docker ps --format "{{.Names}}\t{{.Status}}"
141
- docker logs --tail 200 <container>
142
- df -h /
143
- free -h
144
- ```
145
-
146
- ## Tool Roles
147
-
148
- - `Grafana`: main operator UI for dashboards, Explore, and datasource-backed queries
149
- - `Loki`: log backend queried through Grafana Explore
150
- - `Prometheus`: metrics backend and alert rule evaluation
151
- - `Uptime Kuma`: external uptime/status checks
152
-
153
- ## Credentials
154
-
155
- Grafana admin credentials live on Hetzner in `/home/kostard/forgecad-observability/.env`.
156
-
157
- ## What phase 1 covers
158
-
159
- - host CPU, memory, and disk metrics
160
- - container CPU and memory metrics
161
- - Docker stdout/stderr logs in Loki
162
- - app-native HTTP request metrics from the ForgeCAD web app
163
- - app-native DB query metrics from the ForgeCAD web app
164
- - Grafana data sources and a starter host dashboard
165
- - a provisioned `ForgeCAD Web Requests` dashboard
166
- - a provisioned `ForgeCAD DB Queries` dashboard
167
- - starter Prometheus alert rules for target health, memory, disk, and observability restarts
168
- - Uptime Kuma for health checks and notifications
169
-
170
- Prometheus reaches the web app metrics listener over the private `kamal` Docker network. The app exposes `/metrics` on an internal metrics port, not through the public Cloudflare route.
171
-
172
- ## What phase 1 does not cover
173
-
174
- - distributed Loki storage
175
- - Postgres-native query stats such as `pg_stat_statements`
176
- - tracing / Tempo
177
- - public Grafana hostnames
178
- - automatic provisioning of Uptime Kuma monitors
179
-
180
- Those can be added later once the basic operator loop is working.
181
-
182
- ## First Alerts
183
-
184
- Phase 1 ships starter Prometheus rules for:
185
-
186
- - observability targets going down
187
- - host memory staying below 10% available
188
- - root disk staying below 15% free
189
- - observability containers restarting
190
-
191
- These are intentionally conservative. Let them bake before wiring noisy notifications.
192
-
193
- ## Rollback and Safety
194
-
195
- - Stop the stack with `cd /home/kostard/forgecad-observability && docker compose down` if it causes unexpected pressure.
196
- - The observability services bind only to the host's Tailscale address, so they stay off the public internet and do not compete with Kamal for `80/443`.
197
- - Prod health should always be rechecked with `curl -fsS https://forgecad.io/api/health` after any observability deploy or restart.
@@ -1,111 +0,0 @@
1
- # Projects and File Management
2
-
3
- Projects are the top-level container for user work in ForgeCAD. Each project groups related scripts and output files under a single name with access controls.
4
-
5
- ## Project Model
6
-
7
- Each project has:
8
-
9
- | Field | Type | Description |
10
- |-------|------|-------------|
11
- | `id` | UUID | Primary key |
12
- | `slug` | string | URL-safe identifier, unique per owner |
13
- | `name` | string | Display name |
14
- | `visibility` | `private` \| `public` | Controls unauthenticated access |
15
- | `ownerId` | UUID | Foreign key to the user who created the project |
16
-
17
- Source: `server/db/schema.ts`
18
-
19
- ## Member Roles
20
-
21
- Projects support collaborative access through membership:
22
-
23
- | Role | Capabilities |
24
- |------|-------------|
25
- | **owner** | Full control: rename, delete, manage members, read/write files |
26
- | **editor** | Read and write files (save, delete, mkdir) |
27
- | **viewer** | Read files, watch for changes |
28
-
29
- The owner is always the user who created the project. Ownership cannot be transferred through the membership API.
30
-
31
- ## File Storage
32
-
33
- Project files are stored on disk, not in the database. The storage root is configured by the `FORGE_STORAGE_ROOT` environment variable (default: `/data/projects` in Docker). Each project gets an isolated directory under this root.
34
-
35
- See [deployment.md](../deployment.md) for Docker volume and storage configuration.
36
-
37
- ### Supported File Types
38
-
39
- | Extension | Purpose |
40
- |-----------|---------|
41
- | `.forge.js` | ForgeCAD model scripts |
42
- | `.js` | Utility modules (imported by scripts) |
43
- | `.svg` | Vector assets |
44
- | `.dxf` | 2D CAD profile assets |
45
- | `.stl`, `.3mf` | Exported mesh files |
46
-
47
- ### Path Traversal Protection
48
-
49
- All file operations validate resolved paths against the project's storage directory. Any path that escapes the project root (via `..` segments or symlinks) is rejected. This check runs in `server/storage.ts` before any read or write reaches the filesystem.
50
-
51
- ### Storage Quotas
52
-
53
- Each user has a storage quota tracked via `storage_used_bytes` on the user record.
54
-
55
- | Limit | Value |
56
- |-------|-------|
57
- | Storage per user | 50 MB |
58
- | Projects per user | 20 |
59
-
60
- The quota is checked before every file write. Storage counters are adjusted atomically and clamped to zero to prevent negative drift from race conditions or deleted files.
61
-
62
- Source: `server/quotas.ts`
63
-
64
- ## Real-Time File Watching
65
-
66
- Clients can subscribe to file changes via Server-Sent Events:
67
-
68
- ```
69
- GET /api/projects/:id/watch
70
- ```
71
-
72
- This endpoint streams events whenever files in the project are created, modified, or deleted. The editor uses this to stay in sync when multiple clients have the same project open.
73
-
74
- ## API Endpoints
75
-
76
- ### Projects
77
-
78
- | Method | Route | Min Role | Purpose |
79
- |--------|-------|----------|---------|
80
- | GET | `/api/projects` | -- | List the authenticated user's projects |
81
- | POST | `/api/projects` | -- | Create a new project |
82
- | GET | `/api/projects/:id` | viewer | Get project details |
83
- | PATCH | `/api/projects/:id` | owner | Update project name, slug, or visibility |
84
- | DELETE | `/api/projects/:id` | owner | Delete project and all its files |
85
-
86
- ### Members
87
-
88
- | Method | Route | Min Role | Purpose |
89
- |--------|-------|----------|---------|
90
- | GET | `/api/projects/:id/members` | viewer | List project members |
91
- | POST | `/api/projects/:id/members` | owner | Add a member by user ID |
92
- | PATCH | `/api/projects/:id/members/:userId` | owner | Change a member's role |
93
- | DELETE | `/api/projects/:id/members/:userId` | owner | Remove a member |
94
-
95
- ### Files
96
-
97
- | Method | Route | Min Role | Purpose |
98
- |--------|-------|----------|---------|
99
- | GET | `/api/projects/:id/watch` | viewer | SSE stream of file changes |
100
- | POST | `/api/projects/:id/save` | editor | Write file contents to disk |
101
- | POST | `/api/projects/:id/delete` | editor | Delete a file |
102
- | POST | `/api/projects/:id/mkdir` | editor | Create a directory |
103
- | GET | `/api/projects/:id/read-binary` | viewer | Download a binary file (meshes, assets) |
104
-
105
- Source: `server/routes/projects.ts`, `server/routes/files.ts`
106
-
107
- ## Related
108
-
109
- - [Architecture](architecture.md) -- system overview and deployment topology
110
- - [Sharing](sharing.md) -- model publishing and public URLs
111
- - [Deployment](../deployment.md) -- storage volume configuration, Docker setup
@@ -1,90 +0,0 @@
1
- # Model Sharing and Publishing
2
-
3
- ForgeCAD supports multiple ways to share models. Two categories exist: **server-backed publishing** (persistent URLs, requires auth to publish) and **client-side sharing** (no server needed, data encoded in the URL).
4
-
5
- See [architecture.md](architecture.md) for the full URL route table.
6
-
7
- ## Server-backed publishing
8
-
9
- Authenticated users can publish models to get a stable, public URL. Published models are stored in the `shared_files` database table.
10
-
11
- ### Database schema (`shared_files`)
12
-
13
- | Column | Type | Notes |
14
- |--------|------|-------|
15
- | `id` | uuid | Primary key |
16
- | `share_id` | text | Unique, 10-char nanoid -- the URL identifier |
17
- | `owner_id` | uuid | FK to `users.id`, cascade delete |
18
- | `filename` | text | Original filename |
19
- | `code` | text | Full source code |
20
- | `title` | text | Optional display title |
21
- | `created_at` | timestamptz | Auto-set |
22
- | `updated_at` | timestamptz | Auto-set, updated on re-publish |
23
-
24
- ### Public URLs
25
-
26
- | URL | Behavior |
27
- |-----|----------|
28
- | `/m/:shareId` | Full model preview: source code panel + 3D viewport |
29
- | `/m/:shareId?embed=1` | Viewport only, no UI chrome -- designed for iframe embeds |
30
-
31
- No authentication is required to view a published model.
32
-
33
- ### API endpoints
34
-
35
- | Method | Route | Auth | Purpose |
36
- |--------|-------|------|---------|
37
- | GET | `/api/shares/:shareId` | None | Fetch a published model (code, title, author name, timestamps) |
38
- | GET | `/api/shares` | Required | List the authenticated user's published models |
39
- | POST | `/api/shares` | Required | Publish a new model or update an existing one |
40
- | DELETE | `/api/shares/:shareId` | Required (owner or admin) | Unpublish a model |
41
-
42
- ### Publish behavior
43
-
44
- - If the user already has a published model with the same filename, `POST /api/shares` updates the existing share rather than creating a new one. The `share_id` is preserved so existing links remain valid.
45
- - Each user may publish up to **100** models. Exceeding this limit returns `403` with `{ error: "Share limit reached" }`.
46
- - All publish, update, and delete operations are recorded in the `audit_log` table.
47
-
48
- ### Audit trail
49
-
50
- Every share mutation writes to `audit_log` with one of these actions:
51
- - `share.publish` -- new model published
52
- - `share.update` -- existing model code/title updated
53
- - `share.delete` -- model unpublished
54
-
55
- ## Client-side sharing (no server)
56
-
57
- These methods encode model data directly into the URL. They work without authentication and without the hosted backend.
58
-
59
- ### Inline code (hash fragment)
60
-
61
- Format: `/app#code/<filename>/<lz-compressed-code>`
62
-
63
- The code is compressed with `lz-string` (`compressToEncodedURIComponent`) and placed in the URL hash. Since hash fragments are not sent to the server, this works entirely client-side. Encoding and decoding logic lives in `src/share.ts`.
64
-
65
- ### Multi-file bundles (hash fragment)
66
-
67
- Format: `/app#bundle/<lz-compressed-packed>`
68
-
69
- Packs multiple files into a single compressed payload using null-byte separators: `entry\0filename1\0code1\0filename2\0code2...`. Used when a model has import dependencies.
70
-
71
- ### Gist sharing
72
-
73
- Format: `/app?gist=<github-gist-id>`
74
-
75
- Fetches code from a public GitHub Gist at load time.
76
-
77
- ### URL sharing
78
-
79
- Format: `/app?url=<external-url>`
80
-
81
- Fetches code from any publicly accessible URL at load time.
82
-
83
- ## Source files
84
-
85
- | File | Role |
86
- |------|------|
87
- | `server/routes/shares.ts` | API route handlers for publish/unpublish/list |
88
- | `server/db/schema.ts` | `sharedFiles` table definition and types |
89
- | `src/pages/SharedModelPage.tsx` | Frontend page rendering `/m/:shareId` |
90
- | `src/share.ts` | Client-side encode/decode for hash-based sharing |
@@ -1,39 +0,0 @@
1
- # Product Docs
2
-
3
- These docs are product-first. They are for PMs, founders, designers, product engineers, and strategic reviewers who need to decide what ForgeCAD should become.
4
-
5
- They intentionally overlap with developer docs in a few places, but they have a different job. Product docs explain the market, user, workflow, and business reason behind a direction. Developer docs explain how to implement it safely.
6
-
7
- Use the generated API docs and ForgeCAD skills for exact API usage. Use this folder to decide which API vocabulary, workflow, customer segment, or manufacturing route deserves attention.
8
-
9
- ## Themes
10
-
11
- | Theme | Read this when the question is |
12
- |---|---|
13
- | [Vision](vision.md) | What is ForgeCAD, really? |
14
- | [Founder Story](founder-story.md) | Why did this product start, and what problem did it reveal? |
15
- | [API As Product Language](api-as-product-language.md) | Why does API vocabulary matter as product strategy? |
16
- | [Product Loop](product-loop.md) | What loop makes AI-authored CAD reliable? |
17
- | [User Segments](user-segments.md) | Who are we building for first, next, and later? |
18
- | [Creative Manufacturing](creative-manufacturing.md) | What is the first wedge? |
19
- | [Manufacturing Workflows](manufacturing-workflows.md) | How should we think about 3D printing, laser cutting, CNC, furniture, robotics, and export routes? |
20
- | [Competitive Positioning](competitive-positioning.md) | How should ForgeCAD be compared to OpenSCAD, CadQuery, Fusion, Onshape, Zoo, and prompt-to-CAD tools? |
21
- | [Business Model](business-model.md) | Where can early revenue come from? |
22
- | [Strategic Decisions](strategic-decisions.md) | How should future product bets be judged? |
23
-
24
- ## Tactical Product Docs
25
-
26
- These docs are narrower product operating notes:
27
-
28
- - [First Account Onboarding](onboarding-first-experience.md) - source of truth for new-account first-run behavior.
29
- - [User Outreach Email Templates](user-outreach-email-templates.md) - founder-style user discovery and onboarding outreach.
30
-
31
- Theme docs should stay short and easy to scan. Tactical docs may be longer when they contain templates, checklists, or implementation maps, but they should still link back here so the product reading path stays clear.
32
-
33
- ## How To Use This Folder
34
-
35
- Start with [Vision](vision.md), [Product Loop](product-loop.md), and [Creative Manufacturing](creative-manufacturing.md) if you are new to the product.
36
-
37
- Read [Manufacturing Workflows](manufacturing-workflows.md) before deciding whether to add a manufacturing feature such as CNC primitives, slicer integration, sheet workflows, or furniture cut lists.
38
-
39
- Read [Strategic Decisions](strategic-decisions.md) when a feature sounds exciting but the product reason is still fuzzy.
@@ -1,13 +0,0 @@
1
- # API As Product Language
2
-
3
- In ForgeCAD, the API is not only a developer convenience. It is the product language that AI agents use to express physical intent.
4
-
5
- This is why API design is a product decision. When the API has a first-class concept like a connector, gear, sheet bend, inspection bundle, or manufacturing export, the agent can discover it in docs, compose it, validate it, and explain it to the user. When the API lacks that concept, the agent improvises with lower-level geometry and the product becomes fragile.
6
-
7
- ForgeCAD skills should teach the API that exists. Product docs should help decide which vocabulary deserves to exist next. Those are different jobs. The skills can say how to use a function; product docs should say why that family of functions matters to users, markets, workflows, and business strategy.
8
-
9
- The best API additions reduce how much specialist knowledge the agent must recreate from scratch. A strong agent can learn a lot from documentation, but documentation should not become a substitute for a domain-shaped product surface. If three agents would implement three fragile versions of the same common manufacturing idea, ForgeCAD likely needs a real concept for it.
10
-
11
- Product managers should look for repeated recipes, repeated user friction, repeated validation failures, and repeated market requests. Those are signals that the product vocabulary is too weak. The answer may be a new API, a better workflow, a diagnostic, a starter template, a partner integration, or a higher-level export path.
12
-
13
- The product goal is not the largest possible API. The goal is a vocabulary that makes common physical design intent obvious, inspectable, and manufacturable.
@@ -1,15 +0,0 @@
1
- # Business Model
2
-
3
- ForgeCAD has three early business paths. They should be explored deliberately instead of blended into one vague market.
4
-
5
- The first path is Pro users in creative manufacturing. These are makers, engineers, designers, educators, and small teams who want stronger AI-assisted modeling, exports, private projects, and validation workflows. This path proves repeat usage and product-led demand.
6
-
7
- The second path is embedded parametric commerce. Furniture companies, custom product stores, marketplaces, and printer ecosystems can use ForgeCAD underneath a guided customization experience. The buyer is not paying for "CAD." They are paying for safer customization, fewer manual design steps, better visuals, manufacturing logic, and a shorter path from user intent to orderable object.
8
-
9
- The third path is strategic enterprise or AI-CAD pilots. These customers care about agent evaluation, semantic CAD generation, backend routing, data, export reliability, or integration into existing workflows. This path can create revenue and strategic signal, but it can also pull the product toward custom services too early.
10
-
11
- The product should separate model authoring value from hosted workflow value. A partner may pay for a parametric product family, an embed, hosting, support, usage, or an integration. Those are different products, even if they share the same engine.
12
-
13
- For early business judgement, the strongest evidence is not a broad market slide. The strongest evidence is a repeated paid job: users or partners ask ForgeCAD to generate useful physical objects, the loop succeeds, the output is trusted, and the customer returns.
14
-
15
- Pricing and deal numbers belong in private planning docs when they include negotiation anchors. The permanent product docs should preserve the strategic shape: Pro subscriptions, partner integrations, OEM/marketplace pilots, and enterprise AI-CAD workflows.
@@ -1,17 +0,0 @@
1
- # Competitive Positioning
2
-
3
- ForgeCAD should not be positioned as "OpenSCAD but newer" or "a JavaScript clone of existing CAD-as-code." That framing makes the product sound like a library choice. The stronger framing is that ForgeCAD is an AI-native workflow for editable, manufacturable physical design.
4
-
5
- OpenSCAD proved that code can be a CAD interface for programmers. CadQuery and build123d show that Python can express serious parametric CAD with an exact kernel. Replicad shows that browser and JavaScript CAD can be elegant. These tools are valuable, but they are mainly library or authoring environments.
6
-
7
- Fusion, Onshape, and SolidWorks are professional CAD systems. They are powerful because they serve trained users, teams, manufacturing workflows, and enterprise expectations. They are not naturally shaped around autonomous agents editing semantic source, running validation, producing inspection evidence, and routing outputs from a project folder.
8
-
9
- Prompt-to-CAD tools are close to the user's desire: describe an object and get geometry. The risk is that the result becomes a dead artifact. ForgeCAD should win by keeping the model editable, parameterized, validated, and exportable after generation.
10
-
11
- Zoo and KCL are closer to the same future because they also connect code, AI, and CAD. ForgeCAD's strongest differentiation should be backend-agnostic intent, JavaScript/TypeScript familiarity, local-agent workflow, validation evidence, project sync, and an early focus on daily creative manufacturing rather than only professional CAD replacement.
12
-
13
- The one-line positioning:
14
-
15
- **OpenSCAD made code a CAD interface for programmers. Fusion and Onshape made CAD collaborative for professionals. ForgeCAD makes editable physical design accessible to AI agents and daily users.**
16
-
17
- Product work should reinforce that sentence. If a feature only makes ForgeCAD look like a smaller traditional CAD tool, it needs a sharper reason to exist.
@@ -1,15 +0,0 @@
1
- # Creative Manufacturing
2
-
3
- Creative manufacturing is the first product wedge.
4
-
5
- The user has a real-world problem and access to a way to make things: a 3D printer, laser cutter, CNC service, local workshop, online manufacturing service, or a partner marketplace. They do not want to spend weeks learning traditional CAD. They want to turn everyday intent into a usable object.
6
-
7
- The objects are practical and personal: drawer organizers, brackets, adapters, cable guides, kitchen and bathroom helpers, electronics enclosures, fixtures, toys, lamps, furniture fittings, small mechanisms, replacement parts, and custom mounts.
8
-
9
- This wedge is different from professional CAD replacement. ForgeCAD does not need to beat Fusion, Onshape, or SolidWorks on every enterprise workflow to be useful. It needs to make the first useful object dramatically easier for people who are currently blocked by CAD expertise.
10
-
11
- The wedge is also different from pure prompt-to-mesh. The result should remain editable. If the adapter is 2 mm too short, the user should change a parameter or ask the agent to adjust the model, then validate and export again. If the furniture fitting needs a different screw pattern, the model should carry enough intent to change safely.
12
-
13
- The product should favor workflows where repeated small wins compound. A user who makes one useful object can make another. A printer company that helps users make useful objects sells more printer value. A furniture site that lets customers safely customize dimensions reduces friction around fit.
14
-
15
- Creative manufacturing is not a small niche if the loop becomes reliable. It is the habit of solving physical problems with generated, editable, manufacturable objects.
@@ -1,11 +0,0 @@
1
- # Founder Story
2
-
3
- ForgeCAD started from a long-running curiosity about AI interfaces: what does the AI see, what language does it act through, and how much better does it become when the interface is engineered for it?
4
-
5
- That question became practical during a physical design problem. Ruben wanted to make a custom loft table and realized that a closed CAD system was a poor surface for AI help. If the object lives only inside a complex GUI or proprietary binary state, the AI cannot reliably inspect it, change it, run it, and learn from errors.
6
-
7
- Code was not chosen because code is magical. Code was chosen because it is both machine-operable and human-readable. The deeper requirement is an expressive representation that AI can learn, humans can inspect, and tools can validate. ForgeCAD uses code as that representation today because it gives parameters, composition, reviewability, and a natural path for agent workflows.
8
-
9
- The early browser-first implementation used Manifold and Three.js because fast iteration mattered. A user or agent could change the model and see something quickly. Over time, the product grew beyond browser preview into multiple backends, exact export exploration, hosted projects, sharing, skills, inspection bundles, and manufacturing outputs.
10
-
11
- The important origin lesson is not "build a CAD-as-code tool." The lesson is "design the interface AI needs in order to make physical objects responsibly." ForgeCAD exists because the AI age changes who does the modeling work and therefore changes what the CAD interface should be.
@@ -1,15 +0,0 @@
1
- # Manufacturing Workflows
2
-
3
- Manufacturing workflows should be evaluated as product routes, not only as geometry features.
4
-
5
- 3D printing is the easiest first route because STL/3MF outputs are familiar, iteration is local, and users tolerate prototypes. The product value is not only export. It is parameter checks, wall-thickness evidence, connectivity checks, print-oriented templates, and the ability for an agent to repair the model after feedback.
6
-
7
- Laser cutting and sheet workflows are natural next routes because they turn design intent into flat parts, joints, labels, nesting, and assembly guidance. The product question is whether ForgeCAD can reduce the user's need to manually plan tabs, kerf, slots, bend reliefs, and cut sheets.
8
-
9
- CNC should be treated carefully. "Add CNC primitives" should not mean adding random geometry helpers named after machining words. The user need is closer to stock, workholding, material, tool access, pockets, contours, drilling, dogbones, tabs, tolerances, and safe output routing. A PM should ask whether the feature helps the AI express manufacturable machining intent and whether ForgeCAD can validate enough of that intent to be trusted.
10
-
11
- Furniture and custom product workflows are especially business-relevant. A customer does not want a CAD editor inside a furniture store. They want safe customization, dimensions, visuals, price logic, BOM/cut-list logic, and an orderable product. ForgeCAD can be the parametric engine underneath that experience.
12
-
13
- Robotics and mechanism workflows matter because they show ForgeCAD is not just static shapes. Connectors, joints, collision checks, exports, and kinematic evidence can make the product valuable for users who need motion and system-level relationships.
14
-
15
- The decision rule is simple: a manufacturing workflow is strong when it connects user intent to a validated output route. If ForgeCAD cannot validate or constrain the route yet, the feature may still be worth exploring, but it should be framed as discovery rather than production promise.