six-degrees 0.2.1 → 0.3.0

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 (470) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/app-path-routes-manifest.json +10 -0
  3. package/.next/standalone/.next/build-manifest.json +3 -3
  4. package/.next/standalone/.next/prerender-manifest.json +39 -11
  5. package/.next/standalone/.next/required-server-files.json +4 -1
  6. package/.next/standalone/.next/routes-manifest.json +60 -0
  7. package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
  8. package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  9. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  10. package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
  11. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  12. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  13. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  14. package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  15. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  16. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  17. package/.next/standalone/.next/server/app/_not-found.rsc +10 -10
  18. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +10 -10
  19. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +9 -9
  20. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  21. package/.next/standalone/.next/server/app/api/admin-delete/route.js +3 -2
  22. package/.next/standalone/.next/server/app/api/admin-delete/route.js.nft.json +1 -1
  23. package/.next/standalone/.next/server/app/api/admin-update/route.js +3 -2
  24. package/.next/standalone/.next/server/app/api/admin-update/route.js.nft.json +1 -1
  25. package/.next/standalone/.next/server/app/api/bridges/route.js +3 -2
  26. package/.next/standalone/.next/server/app/api/bridges/route.js.nft.json +1 -1
  27. package/.next/standalone/.next/server/app/api/bulk-import/route.js +3 -2
  28. package/.next/standalone/.next/server/app/api/bulk-import/route.js.nft.json +1 -1
  29. package/.next/standalone/.next/server/app/api/company-scores/legacy/route/app-paths-manifest.json +3 -0
  30. package/.next/standalone/.next/server/app/api/company-scores/legacy/route/build-manifest.json +12 -0
  31. package/.next/standalone/.next/server/app/api/company-scores/legacy/route/server-reference-manifest.json +4 -0
  32. package/.next/standalone/.next/server/app/api/company-scores/legacy/route.js +9 -0
  33. package/.next/standalone/.next/server/app/api/company-scores/legacy/route.js.map +5 -0
  34. package/.next/standalone/.next/server/app/api/company-scores/legacy/route.js.nft.json +1 -0
  35. package/.next/standalone/.next/server/app/api/company-scores/legacy/route_client-reference-manifest.js +3 -0
  36. package/.next/standalone/.next/server/app/api/company-scores/route.js +3 -2
  37. package/.next/standalone/.next/server/app/api/company-scores/route.js.nft.json +1 -1
  38. package/.next/standalone/.next/server/app/api/connections/route.js +3 -2
  39. package/.next/standalone/.next/server/app/api/connections/route.js.nft.json +1 -1
  40. package/.next/standalone/.next/server/app/api/data/export/route/app-paths-manifest.json +3 -0
  41. package/.next/standalone/.next/server/app/api/data/export/route/build-manifest.json +12 -0
  42. package/.next/standalone/.next/server/app/api/data/export/route/server-reference-manifest.json +4 -0
  43. package/.next/standalone/.next/server/app/api/data/export/route.js +7 -0
  44. package/.next/standalone/.next/server/app/api/data/export/route.js.map +5 -0
  45. package/.next/standalone/.next/server/app/api/data/export/route.js.nft.json +1 -0
  46. package/.next/standalone/.next/server/app/api/data/export/route_client-reference-manifest.js +3 -0
  47. package/.next/standalone/.next/server/app/api/data/import/route/app-paths-manifest.json +3 -0
  48. package/.next/standalone/.next/server/app/api/data/import/route/build-manifest.json +12 -0
  49. package/.next/standalone/.next/server/app/api/data/import/route/server-reference-manifest.json +4 -0
  50. package/.next/standalone/.next/server/app/api/data/import/route.js +8 -0
  51. package/.next/standalone/.next/server/app/api/data/import/route.js.map +5 -0
  52. package/.next/standalone/.next/server/app/api/data/import/route.js.nft.json +1 -0
  53. package/.next/standalone/.next/server/app/api/data/import/route_client-reference-manifest.js +3 -0
  54. package/.next/standalone/.next/server/app/api/data/restart/route/app-paths-manifest.json +3 -0
  55. package/.next/standalone/.next/server/app/api/data/restart/route/build-manifest.json +12 -0
  56. package/.next/standalone/.next/server/app/api/data/restart/route/server-reference-manifest.json +4 -0
  57. package/.next/standalone/.next/server/app/api/data/restart/route.js +8 -0
  58. package/.next/standalone/.next/server/app/api/data/restart/route.js.map +5 -0
  59. package/.next/standalone/.next/server/app/api/data/restart/route.js.nft.json +1 -0
  60. package/.next/standalone/.next/server/app/api/data/restart/route_client-reference-manifest.js +3 -0
  61. package/.next/standalone/.next/server/app/api/data/reveal/route/app-paths-manifest.json +3 -0
  62. package/.next/standalone/.next/server/app/api/data/reveal/route/build-manifest.json +12 -0
  63. package/.next/standalone/.next/server/app/api/data/reveal/route/server-reference-manifest.json +4 -0
  64. package/.next/standalone/.next/server/app/api/data/reveal/route.js +7 -0
  65. package/.next/standalone/.next/server/app/api/data/reveal/route.js.map +5 -0
  66. package/.next/standalone/.next/server/app/api/data/reveal/route.js.nft.json +1 -0
  67. package/.next/standalone/.next/server/app/api/data/reveal/route_client-reference-manifest.js +3 -0
  68. package/.next/standalone/.next/server/app/api/data/route/app-paths-manifest.json +3 -0
  69. package/.next/standalone/.next/server/app/api/data/route/build-manifest.json +12 -0
  70. package/.next/standalone/.next/server/app/api/data/route/server-reference-manifest.json +4 -0
  71. package/.next/standalone/.next/server/app/api/data/route.js +7 -0
  72. package/.next/standalone/.next/server/app/api/data/route.js.map +5 -0
  73. package/.next/standalone/.next/server/app/api/data/route.js.nft.json +1 -0
  74. package/.next/standalone/.next/server/app/api/data/route_client-reference-manifest.js +3 -0
  75. package/.next/standalone/.next/server/app/api/delete-cluster/route.js +3 -2
  76. package/.next/standalone/.next/server/app/api/delete-cluster/route.js.nft.json +1 -1
  77. package/.next/standalone/.next/server/app/api/ingest/route.js +2 -2
  78. package/.next/standalone/.next/server/app/api/ingest/route.js.nft.json +1 -1
  79. package/.next/standalone/.next/server/app/api/network/route.js +3 -2
  80. package/.next/standalone/.next/server/app/api/network/route.js.nft.json +1 -1
  81. package/.next/standalone/.next/server/app/api/notifications/route.js +3 -2
  82. package/.next/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
  83. package/.next/standalone/.next/server/app/api/outreach/route.js +3 -2
  84. package/.next/standalone/.next/server/app/api/outreach/route.js.nft.json +1 -1
  85. package/.next/standalone/.next/server/app/api/queue/route.js +3 -2
  86. package/.next/standalone/.next/server/app/api/queue/route.js.nft.json +1 -1
  87. package/.next/standalone/.next/server/app/api/scraper/route.js +3 -2
  88. package/.next/standalone/.next/server/app/api/scraper/route.js.nft.json +1 -1
  89. package/.next/standalone/.next/server/app/api/settings/route/app-paths-manifest.json +3 -0
  90. package/.next/standalone/.next/server/app/api/settings/route/build-manifest.json +12 -0
  91. package/.next/standalone/.next/server/app/api/settings/route/server-reference-manifest.json +4 -0
  92. package/.next/standalone/.next/server/app/api/settings/route.js +9 -0
  93. package/.next/standalone/.next/server/app/api/settings/route.js.map +5 -0
  94. package/.next/standalone/.next/server/app/api/settings/route.js.nft.json +1 -0
  95. package/.next/standalone/.next/server/app/api/settings/route_client-reference-manifest.js +3 -0
  96. package/.next/standalone/.next/server/app/api/settings/sector-preview/route/app-paths-manifest.json +3 -0
  97. package/.next/standalone/.next/server/app/api/settings/sector-preview/route/build-manifest.json +12 -0
  98. package/.next/standalone/.next/server/app/api/settings/sector-preview/route/server-reference-manifest.json +4 -0
  99. package/.next/standalone/.next/server/app/api/settings/sector-preview/route.js +8 -0
  100. package/.next/standalone/.next/server/app/api/settings/sector-preview/route.js.map +5 -0
  101. package/.next/standalone/.next/server/app/api/settings/sector-preview/route.js.nft.json +1 -0
  102. package/.next/standalone/.next/server/app/api/settings/sector-preview/route_client-reference-manifest.js +3 -0
  103. package/.next/standalone/.next/server/app/api/settings/sector-suggestions/route/app-paths-manifest.json +3 -0
  104. package/.next/standalone/.next/server/app/api/settings/sector-suggestions/route/build-manifest.json +12 -0
  105. package/.next/standalone/.next/server/app/api/settings/sector-suggestions/route/server-reference-manifest.json +4 -0
  106. package/.next/standalone/.next/server/app/api/settings/sector-suggestions/route.js +8 -0
  107. package/.next/standalone/.next/server/app/api/settings/sector-suggestions/route.js.map +5 -0
  108. package/.next/standalone/.next/server/app/api/settings/sector-suggestions/route.js.nft.json +1 -0
  109. package/.next/standalone/.next/server/app/api/settings/sector-suggestions/route_client-reference-manifest.js +3 -0
  110. package/.next/standalone/.next/server/app/api/setup-profile/route.js +3 -2
  111. package/.next/standalone/.next/server/app/api/setup-profile/route.js.nft.json +1 -1
  112. package/.next/standalone/.next/server/app/api/unlock/route.js +3 -2
  113. package/.next/standalone/.next/server/app/api/unlock/route.js.nft.json +1 -1
  114. package/.next/standalone/.next/server/app/api/update/route.js +1 -1
  115. package/.next/standalone/.next/server/app/api/update/route.js.nft.json +1 -1
  116. package/.next/standalone/.next/server/app/api/update-images/route.js +3 -2
  117. package/.next/standalone/.next/server/app/api/update-images/route.js.nft.json +1 -1
  118. package/.next/standalone/.next/server/app/api/users/route.js +3 -2
  119. package/.next/standalone/.next/server/app/api/users/route.js.nft.json +1 -1
  120. package/.next/standalone/.next/server/app/avatars/[file]/route.js +2 -1
  121. package/.next/standalone/.next/server/app/avatars/[file]/route.js.nft.json +1 -1
  122. package/.next/standalone/.next/server/app/favicon.ico/route.js +2 -1
  123. package/.next/standalone/.next/server/app/favicon.ico/route.js.nft.json +1 -1
  124. package/.next/standalone/.next/server/app/import/page.js.nft.json +1 -1
  125. package/.next/standalone/.next/server/app/import/page_client-reference-manifest.js +1 -1
  126. package/.next/standalone/.next/server/app/import.html +1 -1
  127. package/.next/standalone/.next/server/app/import.rsc +12 -12
  128. package/.next/standalone/.next/server/app/import.segments/_full.segment.rsc +12 -12
  129. package/.next/standalone/.next/server/app/import.segments/_tree.segment.rsc +1 -1
  130. package/.next/standalone/.next/server/app/import.segments/import/__PAGE__.segment.rsc +11 -11
  131. package/.next/standalone/.next/server/app/index.html +1 -1
  132. package/.next/standalone/.next/server/app/index.rsc +12 -12
  133. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +11 -11
  134. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +12 -12
  135. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  136. package/.next/standalone/.next/server/app/launch/page.js.nft.json +1 -1
  137. package/.next/standalone/.next/server/app/launch/page_client-reference-manifest.js +1 -1
  138. package/.next/standalone/.next/server/app/launch.html +2 -2
  139. package/.next/standalone/.next/server/app/launch.rsc +12 -12
  140. package/.next/standalone/.next/server/app/launch.segments/_full.segment.rsc +12 -12
  141. package/.next/standalone/.next/server/app/launch.segments/_tree.segment.rsc +1 -1
  142. package/.next/standalone/.next/server/app/launch.segments/launch/__PAGE__.segment.rsc +11 -11
  143. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  144. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  145. package/.next/standalone/.next/server/app/paths/page.js.nft.json +1 -1
  146. package/.next/standalone/.next/server/app/paths/page_client-reference-manifest.js +1 -1
  147. package/.next/standalone/.next/server/app/paths.html +1 -1
  148. package/.next/standalone/.next/server/app/paths.rsc +12 -12
  149. package/.next/standalone/.next/server/app/paths.segments/_full.segment.rsc +12 -12
  150. package/.next/standalone/.next/server/app/paths.segments/_tree.segment.rsc +1 -1
  151. package/.next/standalone/.next/server/app/paths.segments/paths/__PAGE__.segment.rsc +11 -11
  152. package/.next/standalone/.next/server/app/profile/page.js.nft.json +1 -1
  153. package/.next/standalone/.next/server/app/profile/page_client-reference-manifest.js +1 -1
  154. package/.next/standalone/.next/server/app/profile.html +1 -1
  155. package/.next/standalone/.next/server/app/profile.rsc +12 -12
  156. package/.next/standalone/.next/server/app/profile.segments/_full.segment.rsc +12 -12
  157. package/.next/standalone/.next/server/app/profile.segments/_tree.segment.rsc +1 -1
  158. package/.next/standalone/.next/server/app/profile.segments/profile/__PAGE__.segment.rsc +11 -11
  159. package/.next/standalone/.next/server/app/queue/page.js.nft.json +1 -1
  160. package/.next/standalone/.next/server/app/queue/page_client-reference-manifest.js +1 -1
  161. package/.next/standalone/.next/server/app/queue.html +1 -1
  162. package/.next/standalone/.next/server/app/queue.rsc +12 -12
  163. package/.next/standalone/.next/server/app/queue.segments/_full.segment.rsc +12 -12
  164. package/.next/standalone/.next/server/app/queue.segments/_tree.segment.rsc +1 -1
  165. package/.next/standalone/.next/server/app/queue.segments/queue/__PAGE__.segment.rsc +11 -11
  166. package/.next/standalone/.next/server/app/settings/page/app-paths-manifest.json +3 -0
  167. package/.next/standalone/.next/server/app/settings/page/build-manifest.json +20 -0
  168. package/.next/standalone/.next/server/app/settings/page/next-font-manifest.json +11 -0
  169. package/.next/standalone/.next/server/app/settings/page/react-loadable-manifest.json +1 -0
  170. package/.next/standalone/.next/server/app/settings/page/server-reference-manifest.json +4 -0
  171. package/.next/standalone/.next/server/app/settings/page.js +13 -0
  172. package/.next/standalone/.next/server/app/settings/page.js.map +5 -0
  173. package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -0
  174. package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +3 -0
  175. package/.next/standalone/.next/server/app/settings.html +1 -0
  176. package/.next/standalone/.next/server/app/settings.meta +26 -0
  177. package/.next/standalone/.next/server/app/settings.rsc +24 -0
  178. package/.next/standalone/.next/server/app/settings.segments/_full.segment.rsc +24 -0
  179. package/.next/standalone/.next/server/app/settings.segments/_tree.segment.rsc +4 -0
  180. package/.next/standalone/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +28 -0
  181. package/.next/standalone/.next/server/app/setup/page.js.nft.json +1 -1
  182. package/.next/standalone/.next/server/app/setup/page_client-reference-manifest.js +1 -1
  183. package/.next/standalone/.next/server/app/setup.html +1 -1
  184. package/.next/standalone/.next/server/app/setup.rsc +12 -12
  185. package/.next/standalone/.next/server/app/setup.segments/_full.segment.rsc +12 -12
  186. package/.next/standalone/.next/server/app/setup.segments/_tree.segment.rsc +1 -1
  187. package/.next/standalone/.next/server/app/setup.segments/setup/__PAGE__.segment.rsc +11 -11
  188. package/.next/standalone/.next/server/app-paths-manifest.json +10 -0
  189. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0-rnla2._.js +3 -0
  190. package/.next/standalone/.next/server/chunks/[root-of-the-server]__00la_y0._.js +3 -0
  191. package/.next/standalone/.next/server/chunks/[root-of-the-server]__07t47cm._.js +3 -0
  192. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0cj5jqc._.js +3 -0
  193. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0e0fei3._.js +3 -0
  194. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0i5hdu4._.js +3 -0
  195. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0ljcioj._.js +3 -0
  196. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0ljnyho._.js +3 -0
  197. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0o5-tcg._.js +3 -0
  198. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0qrnous._.js +3 -0
  199. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0t3v1a1._.js +3 -0
  200. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0uag-k5._.js +8 -0
  201. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0um1uey._.js +3 -0
  202. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0wmexuc._.js +3 -0
  203. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0xu34sz._.js +3 -0
  204. package/.next/standalone/.next/server/chunks/[root-of-the-server]__133knx1._.js +3 -0
  205. package/.next/standalone/.next/server/chunks/[root-of-the-server]__14ou7j5._.js +3 -0
  206. package/.next/standalone/.next/server/chunks/[root-of-the-server]__15-17hl._.js +3 -0
  207. package/.next/standalone/.next/server/chunks/[root-of-the-server]__16iu0hv._.js +3 -0
  208. package/.next/standalone/.next/server/chunks/[root-of-the-server]__19b7mig._.js +3 -0
  209. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1bbcwub._.js +8 -0
  210. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1eris29._.js +3 -0
  211. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1gjo_cq._.js +3 -0
  212. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1kbl21f._.js +3 -0
  213. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1qcm08_._.js +3 -0
  214. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1rphsdk._.js +3 -0
  215. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1t3rugi._.js +3 -0
  216. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1w25q0m._.js +3 -0
  217. package/.next/standalone/.next/server/chunks/_072jl0y._.js +3 -0
  218. package/.next/standalone/.next/server/chunks/_0lw8_i0._.js +3 -0
  219. package/.next/standalone/.next/server/chunks/_1_fynia._.js +21 -3
  220. package/.next/standalone/.next/server/chunks/_1fn30_l._.js +3 -0
  221. package/.next/standalone/.next/server/chunks/_1itd1o_._.js +2 -1
  222. package/.next/standalone/.next/server/chunks/_1iwkh8t._.js +1 -1
  223. package/.next/standalone/.next/server/chunks/_1mxn_lb._.js +3 -0
  224. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_company-scores_legacy_route_actions_1ncspu_.js +3 -0
  225. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_data_export_route_actions_1lkimty.js +3 -0
  226. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_data_import_route_actions_1eji0kd.js +3 -0
  227. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_data_restart_route_actions_00_-u6o.js +3 -0
  228. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_data_reveal_route_actions_0-moqtn.js +3 -0
  229. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_data_route_actions_0j0w5ep.js +3 -0
  230. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_settings_route_actions_1bpm9ac.js +3 -0
  231. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_settings_sector-preview_route_actions_0w79454.js +3 -0
  232. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_settings_sector-suggestions_route_actions_1eoqugp.js +3 -0
  233. package/.next/standalone/.next/server/chunks/lib_db-client_15le7cw.js +155 -0
  234. package/.next/standalone/.next/server/chunks/{lib_rpc_0mc73lk.js → lib_rpc_00tx2sm.js} +1 -1
  235. package/.next/standalone/.next/server/chunks/lib_rpc_02-qa4d.js +3 -0
  236. package/.next/standalone/.next/server/chunks/lib_rpc_02ndsg2.js +3 -0
  237. package/.next/standalone/.next/server/chunks/lib_rpc_08q5vp6.js +3 -0
  238. package/.next/standalone/.next/server/chunks/lib_rpc_0_8i3ft.js +3 -0
  239. package/.next/standalone/.next/server/chunks/lib_rpc_0c9d9ti.js +5 -2
  240. package/.next/standalone/.next/server/chunks/lib_rpc_0huvw-3.js +3 -0
  241. package/.next/standalone/.next/server/chunks/lib_rpc_0ip2vdh.js +3 -0
  242. package/.next/standalone/.next/server/chunks/lib_rpc_0jzisgh.js +3 -0
  243. package/.next/standalone/.next/server/chunks/lib_rpc_0yi9xvd.js +3 -0
  244. package/.next/standalone/.next/server/chunks/lib_rpc_1jyhd0o.js +3 -0
  245. package/.next/standalone/.next/server/chunks/lib_rpc_1kn59-i.js +3 -0
  246. package/.next/standalone/.next/server/chunks/lib_rpc_1q2jkza.js +3 -0
  247. package/.next/standalone/.next/server/chunks/lib_rpc_1vpm1sk.js +3 -0
  248. package/.next/standalone/.next/server/chunks/lib_rpc_1x6p_31.js +3 -0
  249. package/.next/standalone/.next/server/chunks/node_modules_next_1zc5q0a._.js +158 -0
  250. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0mocm6d._.js → [root-of-the-server]__0an6blh._.js} +3 -3
  251. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1m0255u._.js +3 -0
  252. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0bipr5s._.js → [root-of-the-server]__1z1j3ek._.js} +2 -2
  253. package/.next/standalone/.next/server/chunks/ssr/_07u8byv._.js +3 -0
  254. package/.next/standalone/.next/server/chunks/ssr/_08r_mlf._.js +3 -0
  255. package/.next/standalone/.next/server/chunks/ssr/{_0ggabjc._.js → _0942v8n._.js} +1 -1
  256. package/.next/standalone/.next/server/chunks/ssr/{_1djpk8t._.js → _0hl_t7r._.js} +2 -2
  257. package/.next/standalone/.next/server/chunks/ssr/_0tb83dw._.js +132 -0
  258. package/.next/standalone/.next/server/chunks/ssr/_1-87bs1._.js +3 -0
  259. package/.next/standalone/.next/server/chunks/ssr/_17gui6a._.js +1 -1
  260. package/.next/standalone/.next/server/chunks/ssr/_next-internal_server_app_settings_page_actions_11x4dq5.js +3 -0
  261. package/.next/standalone/.next/server/chunks/ssr/app_launch_page_19t0dyd.js +2 -2
  262. package/.next/standalone/.next/server/chunks/ssr/app_page_1fazqbf.js +4 -4
  263. package/.next/standalone/.next/server/chunks/ssr/app_profile_page_0u3-l5y.js +1 -1
  264. package/.next/standalone/.next/server/chunks/ssr/app_queue_page_0c6znd6.js +5 -5
  265. package/.next/standalone/.next/server/chunks/ssr/app_settings_page_1f8mjj_.js +3 -0
  266. package/.next/standalone/.next/server/chunks/ssr/app_setup_page_1-282zx.js +2 -2
  267. package/.next/standalone/.next/server/chunks/ssr/lib_0i8v-s3._.js +1 -1
  268. package/.next/standalone/.next/server/chunks/ssr/node_modules_1f8t_rp._.js +23 -0
  269. package/.next/standalone/.next/server/chunks/ssr/node_modules_1nkgb45._.js +2 -2
  270. package/.next/standalone/.next/server/chunks/ssr/{node_modules_01xbj_9._.js → node_modules_1wax83z._.js} +3 -3
  271. package/.next/standalone/.next/server/chunks/ssr/{node_modules_next_dist_00nap8h._.js → node_modules_next_dist_1bunoni._.js} +2 -2
  272. package/.next/standalone/.next/server/edge/chunks/[root-of-the-server]__0pco7a6._.js +2 -2
  273. package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
  274. package/.next/standalone/.next/server/middleware-manifest.json +15 -7
  275. package/.next/standalone/.next/server/next-font-manifest.js +1 -1
  276. package/.next/standalone/.next/server/next-font-manifest.json +4 -0
  277. package/.next/standalone/.next/server/pages/404.html +1 -1
  278. package/.next/standalone/.next/server/pages/500.html +1 -1
  279. package/.next/standalone/.next/server/prefetch-hints.json +14 -0
  280. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  281. package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
  282. package/.next/standalone/.next/static/chunks/06x3jiiz96m5t.js +1 -0
  283. package/.next/standalone/.next/static/chunks/{34at5d2ifl62i.js → 0ngx9s6-zgshe.js} +5 -5
  284. package/.next/standalone/.next/static/chunks/0q-_khndfxubv.js +2 -0
  285. package/.next/standalone/.next/static/chunks/1c79veqedvubt.js +1 -0
  286. package/.next/standalone/.next/static/chunks/1chp3nx45meg5.js +44 -0
  287. package/.next/standalone/.next/static/chunks/1irqj0lf-fu3d.js +1 -0
  288. package/.next/standalone/.next/static/chunks/1uadqylrod5_v.js +1 -0
  289. package/.next/standalone/.next/static/chunks/23u0zclgwpc4d.js +1 -0
  290. package/.next/standalone/.next/static/chunks/289ktj97di6zg.js +1 -0
  291. package/.next/standalone/.next/static/chunks/2b3lmf8e6uj8m.js +16 -0
  292. package/.next/standalone/.next/static/chunks/2jz311xl1pp_8.js +1 -0
  293. package/.next/standalone/.next/static/chunks/3npq5yd7c4dmn.js +2 -0
  294. package/.next/standalone/.next/static/qqqcxvzBUizkECrT4swyK/_clientMiddlewareManifest.js +14 -0
  295. package/.next/standalone/CHANGELOG.md +298 -0
  296. package/.next/standalone/CONTRIBUTING.md +5 -2
  297. package/.next/standalone/README.md +138 -30
  298. package/.next/standalone/SECURITY.md +117 -10
  299. package/.next/standalone/app/api/company-scores/legacy/route.js +32 -0
  300. package/.next/standalone/app/api/company-scores/route.js +20 -11
  301. package/.next/standalone/app/api/data/export/route.js +49 -0
  302. package/.next/standalone/app/api/data/import/route.js +83 -0
  303. package/.next/standalone/app/api/data/restart/route.js +37 -0
  304. package/.next/standalone/app/api/data/reveal/route.js +14 -0
  305. package/.next/standalone/app/api/data/route.js +39 -0
  306. package/.next/standalone/app/api/ingest/route.js +15 -47
  307. package/.next/standalone/app/api/scraper/route.js +264 -125
  308. package/.next/standalone/app/api/settings/route.js +58 -0
  309. package/.next/standalone/app/api/settings/sector-preview/route.js +38 -0
  310. package/.next/standalone/app/api/settings/sector-suggestions/route.js +20 -0
  311. package/.next/standalone/app/api/update/route.js +188 -23
  312. package/.next/standalone/app/avatars/[file]/route.js +4 -2
  313. package/.next/standalone/app/components/CompanyScores.js +28 -7
  314. package/.next/standalone/app/components/EmptyState.js +8 -0
  315. package/.next/standalone/app/components/ForceGraph.js +39 -35
  316. package/.next/standalone/app/components/LegacyScoresCard.js +129 -0
  317. package/.next/standalone/app/components/Sidebar.js +11 -10
  318. package/.next/standalone/app/components/UpdatePanel.js +306 -119
  319. package/.next/standalone/app/components/UserProvider.js +4 -3
  320. package/.next/standalone/app/components/settings/DataSection.js +437 -0
  321. package/.next/standalone/app/components/settings/SectorSection.js +445 -0
  322. package/.next/standalone/app/components/ui.js +62 -0
  323. package/.next/standalone/app/launch/page.js +30 -20
  324. package/.next/standalone/app/page.js +13 -0
  325. package/.next/standalone/app/paths/page.js +12 -4
  326. package/.next/standalone/app/profile/page.js +41 -8
  327. package/.next/standalone/app/queue/page.js +8 -2
  328. package/.next/standalone/app/settings/page.js +96 -0
  329. package/.next/standalone/app/setup/page.js +32 -16
  330. package/.next/standalone/bin/args.mjs +44 -0
  331. package/.next/standalone/bin/six-degrees.mjs +9 -15
  332. package/.next/standalone/lib/companies.js +44 -119
  333. package/.next/standalone/lib/csv.js +8 -0
  334. package/.next/standalone/lib/data-export.js +170 -0
  335. package/.next/standalone/lib/data-folder.js +238 -0
  336. package/.next/standalone/lib/data-import.js +878 -0
  337. package/.next/standalone/lib/db-client.js +48 -3
  338. package/.next/standalone/lib/durable.js +73 -0
  339. package/.next/standalone/lib/gate.js +90 -1
  340. package/.next/standalone/lib/ingest.js +40 -0
  341. package/.next/standalone/lib/legacy-offer.js +185 -0
  342. package/.next/standalone/lib/legacy-scores.js +77 -0
  343. package/.next/standalone/lib/linkedin-limits.js +124 -1
  344. package/.next/standalone/lib/rpc.js +121 -13
  345. package/.next/standalone/lib/sample-stats.js +16 -0
  346. package/.next/standalone/lib/scan-progress.js +13 -0
  347. package/.next/standalone/lib/scan-state.js +53 -0
  348. package/.next/standalone/lib/scanner-python.js +685 -0
  349. package/.next/standalone/lib/scanner-setup.js +104 -0
  350. package/.next/standalone/lib/scoring.js +747 -138
  351. package/.next/standalone/lib/scraper-client.js +9 -5
  352. package/.next/standalone/lib/sector-directory.js +1532 -0
  353. package/.next/standalone/lib/sector-focus.js +163 -0
  354. package/.next/standalone/lib/sector-labels.js +81 -0
  355. package/.next/standalone/lib/settings-effects.js +59 -0
  356. package/.next/standalone/lib/settings.js +83 -0
  357. package/.next/standalone/lib/updater-job.js +838 -0
  358. package/.next/standalone/lib/updater.js +494 -0
  359. package/.next/standalone/middleware.js +25 -28
  360. package/.next/standalone/next.config.mjs +19 -3
  361. package/.next/standalone/package-lock.json +2 -2
  362. package/.next/standalone/package.json +1 -2
  363. package/.next/standalone/scripts/apply-update.sh +482 -0
  364. package/.next/standalone/scripts/build-app.mjs +251 -9
  365. package/.next/standalone/scripts/requirements.txt +106 -4
  366. package/.next/standalone/scripts/test-release-server.mjs +143 -0
  367. package/.next/standalone/server.js +1 -1
  368. package/.next/static/chunks/06x3jiiz96m5t.js +1 -0
  369. package/.next/static/chunks/{34at5d2ifl62i.js → 0ngx9s6-zgshe.js} +5 -5
  370. package/.next/static/chunks/0q-_khndfxubv.js +2 -0
  371. package/.next/static/chunks/1c79veqedvubt.js +1 -0
  372. package/.next/static/chunks/1chp3nx45meg5.js +44 -0
  373. package/.next/static/chunks/1irqj0lf-fu3d.js +1 -0
  374. package/.next/static/chunks/1uadqylrod5_v.js +1 -0
  375. package/.next/static/chunks/23u0zclgwpc4d.js +1 -0
  376. package/.next/static/chunks/289ktj97di6zg.js +1 -0
  377. package/.next/static/chunks/2b3lmf8e6uj8m.js +16 -0
  378. package/.next/static/chunks/2jz311xl1pp_8.js +1 -0
  379. package/.next/static/chunks/3npq5yd7c4dmn.js +2 -0
  380. package/.next/static/qqqcxvzBUizkECrT4swyK/_clientMiddlewareManifest.js +14 -0
  381. package/CHANGELOG.md +298 -0
  382. package/README.md +138 -30
  383. package/SECURITY.md +117 -10
  384. package/bin/args.mjs +44 -0
  385. package/bin/six-degrees.mjs +9 -15
  386. package/lib/companies.js +44 -119
  387. package/lib/csv.js +8 -0
  388. package/lib/data-export.js +170 -0
  389. package/lib/data-folder.js +238 -0
  390. package/lib/data-import.js +878 -0
  391. package/lib/db-client.js +48 -3
  392. package/lib/durable.js +73 -0
  393. package/lib/gate.js +90 -1
  394. package/lib/ingest.js +40 -0
  395. package/lib/legacy-offer.js +185 -0
  396. package/lib/legacy-scores.js +77 -0
  397. package/lib/linkedin-limits.js +124 -1
  398. package/lib/rpc.js +121 -13
  399. package/lib/sample-stats.js +16 -0
  400. package/lib/scan-progress.js +13 -0
  401. package/lib/scan-state.js +53 -0
  402. package/lib/scanner-python.js +685 -0
  403. package/lib/scanner-setup.js +104 -0
  404. package/lib/scoring.js +747 -138
  405. package/lib/scraper-client.js +9 -5
  406. package/lib/sector-directory.js +1532 -0
  407. package/lib/sector-focus.js +163 -0
  408. package/lib/sector-labels.js +81 -0
  409. package/lib/settings-effects.js +59 -0
  410. package/lib/settings.js +83 -0
  411. package/lib/updater-job.js +838 -0
  412. package/lib/updater.js +494 -0
  413. package/package.json +1 -2
  414. package/scripts/requirements.txt +106 -4
  415. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0jrmmj-._.js +0 -150
  416. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0qx548g._.js +0 -151
  417. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1an3leo._.js +0 -150
  418. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1m8zedk._.js +0 -155
  419. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1zor0ys._.js +0 -3
  420. package/.next/standalone/.next/server/chunks/_0_rp-01._.js +0 -3
  421. package/.next/standalone/.next/server/chunks/_0hzdk79._.js +0 -3
  422. package/.next/standalone/.next/server/chunks/_0ow7u5r._.js +0 -3
  423. package/.next/standalone/.next/server/chunks/_0t0zc2d._.js +0 -3
  424. package/.next/standalone/.next/server/chunks/_0wa631d._.js +0 -3
  425. package/.next/standalone/.next/server/chunks/_13ccnao._.js +0 -3
  426. package/.next/standalone/.next/server/chunks/_13es063._.js +0 -3
  427. package/.next/standalone/.next/server/chunks/_142872j._.js +0 -3
  428. package/.next/standalone/.next/server/chunks/_18wsb_a._.js +0 -8
  429. package/.next/standalone/.next/server/chunks/_1e-4h5h._.js +0 -3
  430. package/.next/standalone/.next/server/chunks/_1gvvd7n._.js +0 -158
  431. package/.next/standalone/.next/server/chunks/_1moda66._.js +0 -3
  432. package/.next/standalone/.next/server/chunks/_1p6ghzv._.js +0 -3
  433. package/.next/standalone/.next/server/chunks/_1xmmi_v._.js +0 -3
  434. package/.next/standalone/.next/server/chunks/_1z-yrlf._.js +0 -3
  435. package/.next/standalone/.next/server/chunks/ssr/_0bf3x4q._.js +0 -3
  436. package/.next/standalone/.next/server/chunks/ssr/app_paths_page_1ol90m7.js +0 -4
  437. package/.next/standalone/.next/static/ZGTiDrZ5NHGETgGdlhssu/_clientMiddlewareManifest.js +0 -6
  438. package/.next/standalone/.next/static/chunks/0jk64vo17avsb.js +0 -1
  439. package/.next/standalone/.next/static/chunks/0s65dsrthylo6.js +0 -2
  440. package/.next/standalone/.next/static/chunks/0uyfdhi8dek85.js +0 -16
  441. package/.next/standalone/.next/static/chunks/220-ne82aus0c.js +0 -44
  442. package/.next/standalone/.next/static/chunks/229haorf0f19b.js +0 -2
  443. package/.next/standalone/.next/static/chunks/2g54uafnwuakc.js +0 -1
  444. package/.next/standalone/.next/static/chunks/2spwqs6b6dx13.js +0 -1
  445. package/.next/standalone/.next/static/chunks/38dlepuubiox0.js +0 -1
  446. package/.next/standalone/scripts/score-connections.sql +0 -80
  447. package/.next/standalone/scripts/score_new_connections.sql +0 -77
  448. package/.next/standalone/site/app.js +0 -84
  449. package/.next/standalone/site/index.html +0 -221
  450. package/.next/standalone/site/style.css +0 -155
  451. package/.next/standalone/site/video/install-mac-poster.jpg +0 -0
  452. package/.next/standalone/site/video/install-mac.mp4 +0 -0
  453. package/.next/standalone/site/video/linux-poster.jpg +0 -0
  454. package/.next/standalone/site/video/linux.mp4 +0 -0
  455. package/.next/standalone/site/video/scan-poster.jpg +0 -0
  456. package/.next/standalone/site/video/scan.mp4 +0 -0
  457. package/.next/static/ZGTiDrZ5NHGETgGdlhssu/_clientMiddlewareManifest.js +0 -6
  458. package/.next/static/chunks/0jk64vo17avsb.js +0 -1
  459. package/.next/static/chunks/0s65dsrthylo6.js +0 -2
  460. package/.next/static/chunks/0uyfdhi8dek85.js +0 -16
  461. package/.next/static/chunks/220-ne82aus0c.js +0 -44
  462. package/.next/static/chunks/229haorf0f19b.js +0 -2
  463. package/.next/static/chunks/2g54uafnwuakc.js +0 -1
  464. package/.next/static/chunks/2spwqs6b6dx13.js +0 -1
  465. package/.next/static/chunks/38dlepuubiox0.js +0 -1
  466. package/scripts/score_new_connections.sql +0 -77
  467. /package/.next/standalone/.next/static/{ZGTiDrZ5NHGETgGdlhssu → qqqcxvzBUizkECrT4swyK}/_buildManifest.js +0 -0
  468. /package/.next/standalone/.next/static/{ZGTiDrZ5NHGETgGdlhssu → qqqcxvzBUizkECrT4swyK}/_ssgManifest.js +0 -0
  469. /package/.next/static/{ZGTiDrZ5NHGETgGdlhssu → qqqcxvzBUizkECrT4swyK}/_buildManifest.js +0 -0
  470. /package/.next/static/{ZGTiDrZ5NHGETgGdlhssu → qqqcxvzBUizkECrT4swyK}/_ssgManifest.js +0 -0
package/README.md CHANGED
@@ -22,7 +22,8 @@
22
22
 
23
23
  **Which download?** Apple menu → **About This Mac**. If it says "Chip: Apple M…", take
24
24
  **Apple Silicon**. If it says "Processor: …Intel…", take **Intel**. It needs **macOS 13.5
25
- (Ventura) or later**, and it's about 185 MB.
25
+ (Ventura) or later**, and it's about 220 MB. Everything the scanner needs except Google
26
+ Chrome is inside, Python included, so there's nothing else to install.
26
27
 
27
28
  **The first time you open it**, macOS stops it, because the app isn't signed with a
28
29
  paid Apple certificate yet:
@@ -49,16 +50,25 @@ It downloads the right version for your Mac, checks the file is exactly the one
49
50
  published here, puts **Six Degrees** in Applications and opens it.
50
51
  [Read the script](install.sh) first if you like.
51
52
 
52
- **Updating.** Choose *Six Degrees → Check for Updates…*, scroll to **Updates** at the
53
- bottom of the page that opens, and click **Check for updates**. Nothing checks by
54
- itself. If there's a newer version, it gives you the Terminal line to paste, which
55
- replaces the app even while it's running. Downloading the new `.dmg` works too; you'll
56
- repeat step 3 once for it.
53
+ **Updating.** Choose *Six Degrees → Check for Updates…* (or open **Settings** with the ⚙
54
+ button or ⌘,). It opens the Updates section and checks. Nothing checks by
55
+ itself. If there's a newer version, click **Install and restart**: the app downloads it
56
+ from GitHub, checks it against the release's published checksums and checks that its code
57
+ signature is intact, closes, puts the new version in its place and opens it again. If the
58
+ new version can't be put in place, won't open, or closes before its first page appears,
59
+ your old one is put back and opened. Once the new one has started, the version you had is
60
+ kept, zipped, in `~/Library/Caches/Six Degrees` until the next update: if the new one
61
+ misbehaves later, unzip it and drag the app into Applications to go back. When the app
62
+ can't update itself (for example, it's running from the disk image), it says why and what
63
+ to do, usually with a Terminal line to paste and what that line will do. Copies of 0.2.1
64
+ and older don't have the button yet, so they take the Terminal line once more.
65
+ Downloading the new `.dmg` works too; you'll repeat step 3 once for it.
57
66
 
58
67
  Your network isn't stored in the app. It's in a hidden folder in your home folder,
59
68
  `.six-degrees` (open it any time with *Help → Show the Data Folder*), so updates never
60
69
  touch it. Each new version also copies your data into its `backups` folder before it
61
- first opens it.
70
+ first opens it. To take it to another computer, see
71
+ [Moving to a new computer](#moving-to-a-new-computer).
62
72
 
63
73
  **Linux:** install **Node 22.13 or later** (from nodejs.org or nvm; Ubuntu's own
64
74
  `nodejs` package is too old), then run:
@@ -70,10 +80,12 @@ npx six-degrees
70
80
  It opens http://127.0.0.1:6363 in your browser (`--no-open` on a machine without a
71
81
  desktop), keeps your data in `~/.six-degrees` (it prints the folder when it starts;
72
82
  `--data-dir` puts it elsewhere), and stops with Ctrl-C. To update, stop it and run
73
- `npx six-degrees@latest`; the Updates panel at the bottom of the Scan page gives the same
74
- line. Scanning LinkedIn also needs Google Chrome (not Chromium) and Python 3.9+ with venv
75
- (on Ubuntu: `sudo apt install python3-venv`). It's tested on Ubuntu, and works on a Mac
76
- too if you'd rather not install the app.
83
+ `npx six-degrees@latest`; **Settings → Updates** gives the same
84
+ line. Scanning LinkedIn also needs Google Chrome (not Chromium), and Python: your own 3.10
85
+ to 3.14 if you have it (on Ubuntu with `python3-venv`), or, if not, the Scan page's **Set
86
+ up the scanner** button downloads a private copy into your data folder (24–33 MB, from
87
+ GitHub, checked against a checksum built into Six Degrees). It's tested on Ubuntu, and
88
+ works on a Mac too if you'd rather not install the app.
77
89
 
78
90
  **Windows:** not yet. There's no Windows app, and `npx six-degrees` doesn't run on
79
91
  Windows yet; npm says so if you try.
@@ -93,7 +105,8 @@ npm run start:packaged # opens http://127.0.0.1:6363 in your browser
93
105
 
94
106
  To update later: stop it (Ctrl-C), then
95
107
  `git pull && npm ci && npm run build && npm run start:packaged`.
96
- Scanning LinkedIn also needs Python 3.9+ and Google Chrome (see below).
108
+ Scanning LinkedIn also needs Google Chrome, and Python 3.10 to 3.14 or the Scan page's
109
+ **Set up the scanner** (see below).
97
110
  </details>
98
111
 
99
112
  ## What it is
@@ -136,9 +149,10 @@ The app opens on a welcome screen with three ways in, and asks nothing about you
136
149
 
137
150
  - **Scan my LinkedIn**: a guided page that ticks each step off as it goes. It sets up
138
151
  the scanner in one click, you sign into LinkedIn yourself in a Chrome window, and then
139
- it scans. Needs Google Chrome and Python 3.9+; the page checks that
140
- both are installed and says what's missing. The app marks this *Recommended* because
141
- it's the only way to Degrees and Outlink. Read the warning above first.
152
+ it scans. Needs Google Chrome. The Mac app brings its own Python; with `npx six-degrees`
153
+ the page uses yours, or sets up a private one with a click. It checks and says what's
154
+ missing. The app marks this *Recommended* because it's the only way to Degrees and
155
+ Outlink. Read the warning above first.
142
156
  - **Import my LinkedIn CSV**: LinkedIn's official export, read on your machine. On
143
157
  LinkedIn: **Settings & Privacy → Data privacy → Get a copy of your data →
144
158
  Connections**. LinkedIn emails a link in about ten minutes; unzip it and drop
@@ -148,7 +162,7 @@ The app opens on a welcome screen with three ways in, and asks nothing about you
148
162
 
149
163
  | | Your scan | Your `Connections.csv` | Sample network |
150
164
  |---|---|---|---|
151
- | Setup | Python + Chrome, once | ~10 min (LinkedIn emails the file) | none |
165
+ | Setup | Chrome (Python comes with the Mac app) | ~10 min (LinkedIn emails the file) | none |
152
166
  | Network Circle, Paths | ✅ | ✅ | ✅ |
153
167
  | **Degrees** (people you *haven't* met) | ✅ | — | ✅ |
154
168
  | **Outlink** (getting introduced) | ✅ | — | — |
@@ -208,18 +222,36 @@ tiers: S ≥ 7.5 A ≥ 5.5 B ≥ 4.0 C ≥ 2.5 D < 2.5
208
222
  - **Title (1–10)** comes from someone's current role in their headline, with former
209
223
  roles at 70%; current students are capped.
210
224
  - **Company score (1–10)** is the one you set (Paths → Scores) if there is one. Otherwise
211
- it comes from a list of well-known companies, or from how many of your people work
212
- there.
225
+ it comes from a built-in list of well-known companies, or from how many of your people
226
+ work there. The built-in list is the same for everyone and follows one rule: only
227
+ companies most US professionals would recognise (household names, the largest companies,
228
+ top investment, consulting, law and accounting firms, frontier AI labs, top universities),
229
+ scored 7 to 10. Anything else is estimated from your network. If you scanned with an
230
+ earlier version, Paths → Scores offers once to keep its old scores for the companies in
231
+ your network whose score changed.
232
+ - **Your sector (Settings, optional):** pick up to three sectors you work in, and companies
233
+ in them get +1 ("lean") or +2 ("strong") on that score, once, never above 10 and never on
234
+ a score you set. A pick is one of twelve broad industries or a narrower sector from a
235
+ built-in list of about fifty (Dental, Real Estate, Software & SaaS…). A sector matches by a
236
+ fixed list of words: in the company's name, or in the headlines of at least half of the
237
+ people you know there, where a job every kind of company has (recruiter, accountant,
238
+ software engineer) doesn't count. An industry includes its sectors, and a company's one
239
+ industry when the known list or the company's name gives it, not when only its people's
240
+ job titles do. Settings suggests the sectors your network is in and shows what would
241
+ change before you save.
213
242
  - Multiplying means seniority counts for more at a bigger company. A VP at a company
214
243
  scored 10 gets 9.0; a founder at an unknown company, 6.7.
215
- - **Reach bonus (up to 1.5)**: investor, YC, an audience in the millions. It counts half
216
- at an unknown company, because headlines are self-written.
244
+ - **Reach bonus (up to 1.5)**: investor, YC, an audience in the millions, the top award
245
+ of any field (a Nobel, a Pulitzer, an Oscar, an Olympic medal…). It counts half
246
+ at an unknown company, because headlines are self-written (your sector doesn't change
247
+ that).
217
248
  - **Bridge boost (up to 1)**: someone whose mapped circle is unusually strong.
218
249
 
219
- Scanned and sample people show the working ("VP / Partner / GM (9) · Snap (9/10) · +0.7
250
+ Scanned and sample people show the working ("VP / Partner / GM (9) · Adobe (8/10) · +0.7
220
251
  strong circle"). A CSV import shows the score only, and uses the built-in company list
221
- rather than your own scores. The model is [`lib/scoring.js`](lib/scoring.js), explained
222
- in [`docs/brain/SCORING.md`](docs/brain/SCORING.md).
252
+ rather than your own scores or sectors; the sample network keeps its own. The model is
253
+ [`lib/scoring.js`](lib/scoring.js), explained in
254
+ [`docs/brain/SCORING.md`](docs/brain/SCORING.md).
223
255
 
224
256
  It estimates **network position**, not what anyone is worth as a person.
225
257
 
@@ -232,11 +264,21 @@ It estimates **network position**, not what anyone is worth as a person.
232
264
  - The app contacts only these, and only when you act:
233
265
  - **LinkedIn**, while you scan. Also, until a profile photo has been saved to your
234
266
  computer, the app shows it straight from LinkedIn's image server.
235
- - **PyPI** (the Python package library), once, to download the scanner's add-ons.
267
+ - Only without the Mac app (which carries the scanner's Python and add-ons inside it),
268
+ once, when you set the scanner up: **PyPI** (the Python package library) for the
269
+ scanner's add-ons, and, if the computer has no Python the scanner can use, **GitHub**
270
+ for a copy of Python when you click *Set up the scanner*. Every file is checked
271
+ against a checksum built into Six Degrees.
236
272
  - **GitHub**, only when you click *Check for updates*, to read the newest version
237
- number.
273
+ number. In the Mac app, also when you then click *Install and restart*, to download
274
+ that version and the file of checksums that proves it's the one published.
238
275
 
239
276
  Nothing about you is sent, and nothing checks on its own.
277
+ - A **copy of your network** that you save (Settings → Your data) is a file you keep
278
+ wherever you choose; the app never uploads it. It holds the names, headlines and profile
279
+ links of the people in your network, their photos unless you leave them out, your
280
+ settings, and the scanner's progress and LinkedIn budget. Your LinkedIn sign-in is never
281
+ in it. Keep it private, and delete it once it's imported.
240
282
  - The web framework's own anonymous usage stats are turned off.
241
283
 
242
284
  See [SECURITY.md](SECURITY.md) for the threat model.
@@ -245,15 +287,81 @@ See [SECURITY.md](SECURITY.md) for the threat model.
245
287
 
246
288
  ```
247
289
  .six-degrees/ in your home folder (hidden)
248
- ├── six-degrees.sqlite your network: connections, scores, tiers, queue
249
- ├── backups/ a copy of the database before each new version touches it
290
+ ├── six-degrees.sqlite your network: connections, scores, tiers, queue, settings
291
+ ├── backups/ copies of the database from before each new version, and
292
+ │ before an import, touched it
250
293
  ├── avatars/ profile photos, if you scan
251
294
  ├── chrome-profile/ the scanner's Chrome sign-in, if you scan (see below)
252
- ├── venv/ the scanner's Python add-ons, if you set it up
295
+ ├── venv/ the scanner's Python add-ons, if you set it up without the Mac app
296
+ ├── python/ a private Python for them, if Set up the scanner downloaded one
253
297
  ├── pushback/ what LinkedIn's page said if it ever pushed back
254
298
  └── *.json the scanner's budget, cooldown, progress and skip lists
255
299
  ```
256
300
 
301
+ **Settings → Your data** shows where this folder is (with *Copy the path* and *Show in
302
+ Finder*), what each part takes up, and the backups in it.
303
+
304
+ ### Moving to a new computer
305
+
306
+ 1. On the old computer, open **Settings → Your data** and click **Save a copy of my
307
+ network**. You get one file, `Six Degrees backup <date>.sixdegrees`, with your network,
308
+ your settings, the scanner's progress, skip lists and LinkedIn budget, and the profile
309
+ photos of the people in it (untick them to leave them out; they come back as you scan
310
+ again).
311
+ 2. Move that file to the new computer yourself (a USB stick, AirDrop). It holds other
312
+ people's names and photos, so don't post it or share it.
313
+ 3. On the new computer, install Six Degrees, open **Settings → Your data**, choose the
314
+ file and click **Import**. It's checked first, and nothing changes if it isn't a whole
315
+ and undamaged Six Degrees copy. If that computer already has a network, you're asked to
316
+ confirm that the import replaces it. The two networks are never merged. Your LinkedIn
317
+ search budget is the one thing that is: it belongs to your LinkedIn account, not to a
318
+ computer, so searches made on either computer still count, a pause on scanning set on
319
+ either stays until it ends, and budget limits already set on that computer stay.
320
+ 4. The import finishes the next time Six Degrees starts. The Mac app does that with
321
+ **Restart now**; with `npx six-degrees`, press Ctrl-C and start it again. If another
322
+ copy of Six Degrees has the same folder open (one started from the Terminal, say), the
323
+ import waits, and Settings says so. What was there before is kept in `backups/`
324
+ (`before-import-…`), and those copies are never deleted automatically: see
325
+ [Undo an import](#undo-an-import).
326
+ 5. Sign in to LinkedIn again on the new computer before you scan. Your sign-in never goes
327
+ into a copy. A network opened from a LinkedIn CSV isn't in the copy either: it lives in
328
+ its browser tab, so import the CSV again there.
329
+
330
+ ### Undo an import
331
+
332
+ An import keeps what it replaced in the data folder's `backups/`, named with the time it
333
+ finished (Settings → Your data shows the exact name):
334
+
335
+ - `before-import-<time>.sqlite`: your network as it was.
336
+ - `before-import-<time>-files/`: its profile photos (`avatars/`), the scanner's notes about
337
+ it (`bridge-progress.json`, `bridge-skips.json`, `bridge-unclear.json`), and a copy of
338
+ your LinkedIn budget files as they were.
339
+
340
+ To put it back (there's no button for this yet):
341
+
342
+ 1. Quit Six Degrees (⌘Q in the Mac app, Ctrl-C for `npx six-degrees`). Do the rest while
343
+ it's closed.
344
+ 2. Open the data folder (Settings → Your data → *Show in Finder*, or `~/.six-degrees`).
345
+ Move these out of it, to the Trash or somewhere safe if you might want the imported
346
+ network again: `six-degrees.sqlite`, and `six-degrees.sqlite-wal` and
347
+ `six-degrees.sqlite-shm` if they're there (a `-wal` left beside a different database
348
+ is replayed into it and damages it), then `avatars/` and the three `bridge-*.json`
349
+ files.
350
+ 3. Copy `backups/before-import-<time>.sqlite` into the data folder and rename the copy
351
+ `six-degrees.sqlite`. If `before-import-<time>.sqlite-wal` and `-shm` files are beside
352
+ it, copy them too, renamed to match (`six-degrees.sqlite-wal`,
353
+ `six-degrees.sqlite-shm`).
354
+ 4. Copy `avatars/` and the three `bridge-*.json` files from
355
+ `backups/before-import-<time>-files/` back into the data folder.
356
+ 5. Leave `linkedin-activity.json`, `linkedin-cooldown.json` and `scan-limits.json` as they
357
+ are. They're your LinkedIn account's budget, which the import kept (it only added the
358
+ other computer's searches), so they're right whichever network you use.
359
+ 6. Open Six Degrees again.
360
+
361
+ Don't put the live folder in iCloud Drive or Dropbox to share it between computers
362
+ instead. A sync service that copies the database while it's open can damage it, and it
363
+ would also sync your LinkedIn sign-in.
364
+
257
365
  **To remove everything:** quit the app and drag **Six Degrees** from Applications to the
258
366
  Trash. Then in Finder choose **Go → Go to Folder…** (⇧⌘G), paste `~/.six-degrees` and
259
367
  move that folder to the Trash. Do the same for
@@ -271,8 +379,8 @@ Nothing to configure. Two optional environment variables exist:
271
379
 
272
380
  | Variable | Purpose |
273
381
  |---|---|
274
- | `SIX_DEGREES_HOME` | Where your data lives. Defaults to `~/.six-degrees`. It's read at launch, so it applies to `npx six-degrees` and source runs (npx also takes `--data-dir`; see `npx six-degrees --help`), not when the Mac app is opened from the Dock or Finder. |
275
- | `ADMIN_TOKEN` | Not needed on your own computer. The app listens only on 127.0.0.1 and isn't built to be exposed: don't put it behind a tunnel or bind it to another address ([SECURITY.md](SECURITY.md)). If it's ever bound elsewhere, the six routes that delete data, run the scanner or update a copy run from source refuse every caller without this token, including the app's own buttons. Everything else, including reading your whole network, stays open. |
382
+ | `SIX_DEGREES_HOME` | Where your data lives. Defaults to `~/.six-degrees`. It's read at launch, so it applies to `npx six-degrees` and source runs (npx also takes `--data-dir`; see `npx six-degrees --help`), not when the Mac app is opened from the Dock or Finder. A relative folder is taken from the folder you run the command in. |
383
+ | `ADMIN_TOKEN` | Not needed on your own computer. The app listens only on 127.0.0.1 and isn't built to be exposed: don't put it behind a tunnel or bind it to another address ([SECURITY.md](SECURITY.md)). If it's ever bound elsewhere, the ten routes that delete, replace or hand over your data, run the scanner, open the data folder or update a copy run from source refuse every caller without this token, including the app's own buttons. Everything else, including reading your whole network, stays open. |
276
384
 
277
385
  ## Contributing
278
386
 
package/SECURITY.md CHANGED
@@ -12,20 +12,90 @@ This app is designed to run **on your own machine, against your own network**.
12
12
 
13
13
  - The web UI binds to localhost. It is not hardened for exposure to the
14
14
  internet, and it has no multi-user authentication or per-user authorization.
15
- - Six API routes are gated (`admin-delete`, `admin-update`, `delete-cluster`,
16
- `setup-profile`, `scraper`, `update`). The first four can irreversibly
17
- destroy or rewrite data, `scraper` starts processes, and `update` changes the
18
- code that runs next. While the server is bound to 127.0.0.1 they need no
19
- token — anyone who can reach it can already open the database file directly,
20
- so a token there adds friction rather than safety. If it is bound to any
21
- other address, every caller must send `ADMIN_TOKEN` as a bearer, including
22
- this machine and the app's own buttons, and the routes refuse to run when it
23
- is unset.
15
+ - Ten API routes are gated (`admin-delete`, `admin-update`, `delete-cluster`,
16
+ `setup-profile`, `scraper`, `update`, and Settings → Your data's
17
+ `data/export`, `data/import`, `data/restart`, `data/reveal`). The first four
18
+ can irreversibly destroy or rewrite data, `scraper` starts processes, and
19
+ `update` changes the code that runs next. `data/export` hands over the whole
20
+ network in one file, `data/import` replaces it, `data/restart` stops the
21
+ server, and `data/reveal` starts a process (Finder, or the Linux file
22
+ browser, on the data folder's own path). While the server is bound to
23
+ 127.0.0.1 they need no token — anyone who can reach it can already open the
24
+ database file directly, so a token there adds friction rather than safety. If
25
+ it is bound to any other address, every caller must send `ADMIN_TOKEN` as a
26
+ bearer, including this machine and the app's own buttons, and the routes
27
+ refuse to run when it is unset. Reading the data folder's facts
28
+ (`GET /api/data`: its path and sizes) changes nothing and stays open, like
29
+ every other read.
24
30
  - A localhost-bound service is still reachable by any web page you visit — the
25
31
  binding keeps other machines out, not your own browser. Every mutating API
26
32
  request is therefore refused when the browser reports it came from another
27
- site (`Sec-Fetch-Site`, with `Origin` as a fallback). Command-line callers
33
+ site (`Sec-Fetch-Site`, with `Origin` as a fallback). That includes other
34
+ ports on this same machine: a page from another local app or dev server is
35
+ refused unless its `Origin` is exactly this app's address. Command-line callers
28
36
  such as the scanner send neither header and are unaffected.
37
+ - A website can also make its own domain point at `127.0.0.1` (DNS rebinding).
38
+ The browser then treats the app as that site's own origin, which would let
39
+ the page read the network and send writes. While the app is bound to
40
+ loopback, every request to `/api` and `/avatars` must be addressed to
41
+ `127.0.0.1`, `localhost` or `[::1]` (the `Host` header); any other name gets
42
+ a 421.
43
+ - The Mac app's **Install and restart** (behind the `update` route's gate)
44
+ downloads only what GitHub's `releases/latest` names for this repository,
45
+ and only the version the user's check was shown (the server remembers it):
46
+ this Mac's `.dmg` by its exact file name, from that release's own download
47
+ address, never a pre-release and never a version or address sent by the page.
48
+ Nothing replaces the app unless the image matches the release's `SHA256SUMS`
49
+ (a release without one is refused), the app inside passes
50
+ `codesign --verify --deep --strict` (its code signature is intact), is Six
51
+ Degrees (its bundle id) at exactly that version, runs on this macOS and chip,
52
+ and has no link pointing outside itself. The checksums come from the same
53
+ release, so they catch a corrupted, truncated or swapped download, not a
54
+ compromised GitHub account; that is the same trust as the Terminal
55
+ installer. The app is only signed ad hoc, so the signature proves it is
56
+ whole, not who made it. The swap is done by a script shipped inside the app
57
+ (`scripts/apply-update.sh`), started with a clean environment, and it moves
58
+ only the app: the data folder is never read, moved or written. It stops only
59
+ the app's own processes, the ones the server names and those whose
60
+ executable is inside the app, never a program that merely has a file or
61
+ folder of the app open (a Terminal in its folder, an editor). It never
62
+ replaces an app another user of the Mac has open. `SIX_DEGREES_TEST_RELEASES`
63
+ (for tests) is honoured only for a `127.0.0.1` address.
64
+ - **The scanner's Python.** The Mac app carries its own: CPython 3.12.14 from
65
+ python-build-standalone (release 20260814), which the build checks against a
66
+ SHA-256 pinned in `lib/scanner-python.js` before unpacking it, with the
67
+ scanner's packages installed from PyPI when the app is built. Those packages
68
+ are pinned in `scripts/requirements.txt`: an exact version and the SHA-256 of
69
+ every file pip may install, wheels only, so pip refuses any other file and
70
+ nothing is built from source. The Python is signed ad hoc like the rest of the
71
+ app and sealed into its signature, which `codesign --verify --deep --strict`
72
+ checks (in CI, and before the in-app updater uses a download). It runs
73
+ isolated from the user's Python settings (`-E -s`: no `PYTHON*` variable and
74
+ no user site-packages count), so nothing of the user's can stand in for its
75
+ packages, and no scan writes bytecode into the app, on this Python or any
76
+ other.
77
+ - **Set up the scanner** (the Scan page, for `npx six-degrees` and source copies
78
+ on a computer with no Python 3.10–3.14 it can use) downloads only when that
79
+ button is pressed, and only from two places:
80
+ - **GitHub's release download** for python-build-standalone (`github.com`,
81
+ which hands the file over from GitHub's own download server): the one file
82
+ pinned for this operating system and chip (`lib/scanner-python.js`: Linux
83
+ x64 and arm64, macOS Apple Silicon and Intel). Its size and SHA-256 must
84
+ match before it is even named, let alone unpacked; a file that doesn't is
85
+ deleted.
86
+ - **PyPI** (`pypi.org`, `files.pythonhosted.org`) for the scanner's packages,
87
+ every file checked against `scripts/requirements.txt`. (pip follows your
88
+ own pip settings for which index, proxy and certificates to use, if you
89
+ have any; the hashes still have to match. Settings that would install the
90
+ packages somewhere other than `venv/` (`PIP_TARGET`, `PIP_PREFIX`,
91
+ `PIP_ROOT`, `PIP_USER`) are left out, and Install checks that the packages
92
+ load from `venv/` before it says it has finished.)
93
+
94
+ The Python lands in the data folder's `python/`, the packages in `venv/`;
95
+ nothing outside the data folder changes, and neither is ever exported. The
96
+ checksums come from this repository, not from the servers, so a swapped or
97
+ corrupted download is refused; a release that was compromised before its
98
+ checksums were taken would not be.
29
99
  - Values stored in the database are treated as untrusted text and escaped
30
100
  before rendering. Do not reintroduce `innerHTML` (including d3's `.html()`)
31
101
  for anything data-bearing.
@@ -43,6 +113,43 @@ Everything stays local:
43
113
  If you run the scanner, `chrome-profile/` in the data directory holds a live
44
114
  logged-in LinkedIn session. Never copy, sync, or commit it.
45
115
 
116
+ ### Moving your data (Settings → Your data)
117
+
118
+ - **An export** is one `.sixdegrees` file the user saves and carries. It is
119
+ built from an allow-list (the database, the photos its rows still point at,
120
+ and the scanner's six progress and budget files), never from the folder minus
121
+ a few things, so `chrome-profile/`, `venv/`, `python/`, `backups/` and
122
+ `pushback/` never travel, and links are never followed out of the folder (a link standing in
123
+ for `avatars/` itself included). The app never uploads it. It holds other
124
+ people's names, headlines and photos, and the page says so.
125
+ - **An import is untrusted input**: the file came from somewhere else. Before
126
+ anything in the data folder changes, it must pass SQLite's own integrity
127
+ check (read with `trusted_schema` off), hold only the app's own ordinary
128
+ tables and indexes (no views, triggers, virtual tables or extra columns),
129
+ come from this version or an older one, match its own manifest, and carry
130
+ only allow-listed files whose names can't leave the data folder, each
131
+ matching its SHA-256. The LinkedIn budget files must also follow the rules
132
+ the app writes them by: limits only from the Scan page's own menu (the
133
+ scanner reads a daily limit of 0 as no limit at all). The network is then
134
+ rebuilt into this version's own schema, so only rows travel, never table
135
+ definitions. It is refused while a scan (or the scanner's setup) runs, and
136
+ replacing a network that has people needs a confirmation that names how many.
137
+ - **The upload never sits in memory.** Next copies the body of every request
138
+ `middleware.js` sees into memory before middleware decides anything, so the
139
+ import route is left out of it and makes the same checks itself
140
+ (`lib/gate.js requestRefusal`: rebinding, cross-site, the gate) before it
141
+ reads a byte. The body is then written to disk as it arrives, at most
142
+ 256 MB, and must match the size the page declared. Every other route keeps
143
+ Next's 10 MB limit.
144
+ - **It is applied at the next start**, never under the open database, and never
145
+ while another process has it open (a second copy of Six Degrees on the same
146
+ folder). What was there is kept first in `backups/before-import-<time>.sqlite`
147
+ (and its photos and files beside it), synced to the disk and checked (SQLite's
148
+ quick check, and every table's row count against the original) before the
149
+ original is replaced; those copies are never deleted automatically. The
150
+ LinkedIn budget files are merged with this computer's, not replaced: they
151
+ belong to the account.
152
+
46
153
  Never commit `public/avatars/` or any exported CSV — they contain real people.
47
154
  `public/demo-data.json` is committed, but only ever as the generated synthetic
48
155
  sample; CI fails the build if it appears without its `"synthetic":true` marker,
package/bin/args.mjs ADDED
@@ -0,0 +1,44 @@
1
+ // The npx launcher's command line, kept apart from bin/six-degrees.mjs (which
2
+ // starts a server the moment it runs) so the tests can read it directly.
3
+
4
+ import { homedir } from 'node:os';
5
+ import path from 'node:path';
6
+
7
+ /**
8
+ * A folder named on the command line, made absolute. The launcher changes into
9
+ * the package's own folder before the server starts, so a relative folder
10
+ * passed on as it is would land inside the npx cache, and be lost when that is
11
+ * cleared. A leading ~ is the home folder: the shell expands `--data-dir ~/x`
12
+ * but not `--data-dir=~/x`, which would otherwise make a folder named "~".
13
+ */
14
+ export function absoluteFolder(value, { cwd = process.cwd(), home = homedir() } = {}) {
15
+ const s = String(value);
16
+ const expanded = s === '~' ? home : s.startsWith('~/') ? path.join(home, s.slice(2)) : s;
17
+ return path.resolve(cwd, expanded);
18
+ }
19
+
20
+ /**
21
+ * @returns {{ port, open, dataDir, help, version, error }}
22
+ * dataDir is absolute (absoluteFolder), or null when not given.
23
+ */
24
+ export function parseArgs(argv, { env = process.env, cwd = process.cwd(), home = homedir() } = {}) {
25
+ const out = { port: Number(env.PORT) || 6363, open: true, dataDir: null };
26
+ for (let i = 0; i < argv.length; i++) {
27
+ const a = String(argv[i]);
28
+ if (a === '--port' || a === '-p') out.port = Number(argv[++i]);
29
+ else if (a === '--no-open') out.open = false;
30
+ else if (a === '--data-dir' || a.startsWith('--data-dir=')) {
31
+ const value = a === '--data-dir' ? argv[++i] : a.slice('--data-dir='.length);
32
+ if (value) out.dataDir = absoluteFolder(value, { cwd, home });
33
+ else out.error = '--data-dir needs a folder, for example: --data-dir ~/six-degrees-copy';
34
+ }
35
+ else if (a === '--help' || a === '-h') out.help = true;
36
+ else if (a === '--version' || a === '-v') out.version = true;
37
+ }
38
+ return out;
39
+ }
40
+
41
+ /** The data folder: --data-dir, else SIX_DEGREES_HOME, else ~/.six-degrees. Always absolute, for the same reason. */
42
+ export function resolveDataDir(args, { env = process.env, cwd = process.cwd(), home = homedir() } = {}) {
43
+ return absoluteFolder(args.dataDir || env.SIX_DEGREES_HOME || path.join(home, '.six-degrees'), { cwd, home });
44
+ }
@@ -10,8 +10,9 @@ import { createServer } from 'node:net';
10
10
  import { spawn } from 'node:child_process';
11
11
  import { fileURLToPath } from 'node:url';
12
12
  import { existsSync, mkdirSync } from 'node:fs';
13
- import { homedir, platform } from 'node:os';
13
+ import { platform } from 'node:os';
14
14
  import path from 'node:path';
15
+ import { parseArgs, resolveDataDir } from './args.mjs';
15
16
 
16
17
  const HERE = path.dirname(fileURLToPath(import.meta.url));
17
18
  const ROOT = path.join(HERE, '..');
@@ -33,19 +34,6 @@ function checkNode() {
33
34
  }
34
35
  }
35
36
 
36
- function parseArgs(argv) {
37
- const out = { port: Number(process.env.PORT) || 6363, open: true };
38
- for (let i = 0; i < argv.length; i++) {
39
- const a = argv[i];
40
- if (a === '--port' || a === '-p') out.port = Number(argv[++i]);
41
- else if (a === '--no-open') out.open = false;
42
- else if (a === '--data-dir') process.env.SIX_DEGREES_HOME = argv[++i];
43
- else if (a === '--help' || a === '-h') out.help = true;
44
- else if (a === '--version' || a === '-v') out.version = true;
45
- }
46
- return out;
47
- }
48
-
49
37
  const HELP = `
50
38
  six-degrees — map your professional network as a galaxy, on your own machine
51
39
 
@@ -106,9 +94,15 @@ async function main() {
106
94
  return;
107
95
  }
108
96
 
97
+ if (args.error) {
98
+ console.error(`\n ${args.error}\n`);
99
+ process.exit(1);
100
+ }
101
+
109
102
  checkNode();
110
103
 
111
- const dataDir = process.env.SIX_DEGREES_HOME || path.join(homedir(), '.six-degrees');
104
+ // Absolute (bin/args.mjs): the server runs from inside the package, not here.
105
+ const dataDir = resolveDataDir(args);
112
106
  if (!existsSync(dataDir)) mkdirSync(dataDir, { recursive: true });
113
107
 
114
108
  const server = path.join(ROOT, '.next', 'standalone', 'server.js');