nebulosity 1.0.0 → 1.1.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 (180) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/build-manifest.json +11 -11
  3. package/.next/diagnostics/route-bundle-stats.json +10 -10
  4. package/.next/fallback-build-manifest.json +3 -3
  5. package/.next/prerender-manifest.json +5 -5
  6. package/.next/server/app/_global-error/page/build-manifest.json +3 -3
  7. package/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  8. package/.next/server/app/_global-error.html +1 -1
  9. package/.next/server/app/_global-error.rsc +1 -1
  10. package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  11. package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  12. package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  13. package/.next/server/app/_not-found/page/build-manifest.json +3 -3
  14. package/.next/server/app/_not-found/page/next-font-manifest.json +2 -3
  15. package/.next/server/app/_not-found/page.js +3 -2
  16. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  17. package/.next/server/app/_not-found.html +1 -1
  18. package/.next/server/app/_not-found.rsc +27 -20
  19. package/.next/server/app/_not-found.segments/_full.segment.rsc +27 -20
  20. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +34 -26
  21. package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  22. package/.next/server/app/index.html +1 -1
  23. package/.next/server/app/index.rsc +29 -23
  24. package/.next/server/app/index.segments/__PAGE__.segment.rsc +33 -24
  25. package/.next/server/app/index.segments/_full.segment.rsc +29 -23
  26. package/.next/server/app/index.segments/_tree.segment.rsc +4 -5
  27. package/.next/server/app/page/build-manifest.json +3 -3
  28. package/.next/server/app/page/next-font-manifest.json +2 -3
  29. package/.next/server/app/page.js +4 -4
  30. package/.next/server/app/page_client-reference-manifest.js +1 -1
  31. package/.next/server/chunks/[root-of-the-server]__06blyow8irfw3._.js +3 -3
  32. package/.next/server/chunks/[root-of-the-server]__0bmqko-d8fd5k._.js +3 -3
  33. package/.next/server/chunks/[root-of-the-server]__0cmmlmvta4i0g._.js +3 -3
  34. package/.next/server/chunks/[root-of-the-server]__0jgr1dt1j95ku._.js +3 -3
  35. package/.next/server/chunks/[root-of-the-server]__0m0n163465-zb._.js +3 -3
  36. package/.next/server/chunks/[root-of-the-server]__0p7epsgp2b5m3._.js +3 -3
  37. package/.next/server/chunks/[root-of-the-server]__1i5e5sqg45ens._.js +3 -3
  38. package/.next/server/chunks/[root-of-the-server]__1vjt0neva-819._.js +3 -3
  39. package/.next/server/chunks/_0uqus0ehnijt-._.js +1 -1
  40. package/.next/server/chunks/lib_background_start_ts_11u_1uu8b9yuy._.js +1 -1
  41. package/.next/server/chunks/ssr/[root-of-the-server]__0_3l5tdzqy-td._.js +3 -0
  42. package/.next/server/chunks/ssr/[root-of-the-server]__10ockmlli-lun._.js +3 -0
  43. package/.next/server/chunks/ssr/{[root-of-the-server]__0dyligeswbb47._.js → [root-of-the-server]__16-gclvix9mjd._.js} +1 -1
  44. package/.next/server/chunks/ssr/[root-of-the-server]__1auodc3c0rppy._.js +3 -0
  45. package/.next/server/chunks/ssr/[root-of-the-server]__1cf6qt9agg_9-._.js +3 -3
  46. package/.next/server/chunks/ssr/[root-of-the-server]__1i9r59yk4i69p._.js +3 -0
  47. package/.next/server/chunks/ssr/[root-of-the-server]__1l3qp8u9yc_ig._.js +3 -0
  48. package/.next/server/chunks/ssr/_1p-0wsx9qfm68._.js +13 -0
  49. package/.next/server/chunks/ssr/app_map_18iu6j19jsqmu._.js +3 -0
  50. package/.next/server/chunks/ssr/node_modules_next_dist_1r3iqtbm45lqp._.js +3 -0
  51. package/.next/server/chunks/ssr/node_modules_next_dist_client_components_builtin_global-error_0q-w892nagajq.js +3 -0
  52. package/.next/server/middleware-build-manifest.js +11 -11
  53. package/.next/server/next-font-manifest.js +1 -1
  54. package/.next/server/next-font-manifest.json +4 -6
  55. package/.next/server/pages/404.html +1 -1
  56. package/.next/server/pages/500.html +1 -1
  57. package/.next/server/preview-props.json +3 -3
  58. package/.next/server/server-reference-manifest.js +1 -1
  59. package/.next/server/server-reference-manifest.json +1 -1
  60. package/.next/static/chunks/{1rljem7o1jtdo.js → 18kfexnrqek07.js} +1 -1
  61. package/.next/static/chunks/1hwbgd4nvvhg8.js +1 -0
  62. package/.next/static/chunks/25r4lkkf1shfo.css +3 -0
  63. package/.next/static/chunks/35ubvk2ivdjgs.js +1 -0
  64. package/.next/static/chunks/3ieqvmcg3hofj.js +31 -0
  65. package/.next/static/chunks/3w00e1w2125pp.js +11 -0
  66. package/.next/static/media/733da6bd8dac84c8-s.3hlisc-pwq13z.woff2 +0 -0
  67. package/.next/static/media/784318cea1dfcfa4-s.0-oo9_1x_xmvg.woff2 +0 -0
  68. package/.next/static/media/7e114457660b62ed-s.36fqqi66-3tjb.woff2 +0 -0
  69. package/.next/static/media/85e86a88f68a624a-s.357dd_6abeqge.woff2 +0 -0
  70. package/.next/static/media/9a321a2c78eff0b5-s.p.1bkzbscqrt8rl.woff2 +0 -0
  71. package/.next/static/media/9fecbd3e5ea9bccb-s.3_z45zcoc-xoz.woff2 +0 -0
  72. package/.next/static/media/c64053b510252f55-s.1kd-r_s9smv5m.woff2 +0 -0
  73. package/.next/static/media/c6a5c2fdc12da45c-s.p.17-aodiw50953.woff2 +0 -0
  74. package/.next/static/media/f263782c6a4bddee-s.1gyfqm5yhhzs7.woff2 +0 -0
  75. package/.next/trace +1 -1
  76. package/.next/trace-build +1 -1
  77. package/README.md +13 -4
  78. package/app/globals.css +91 -54
  79. package/app/layout.tsx +20 -11
  80. package/app/map/BackButton.tsx +5 -5
  81. package/app/map/BoxActions.tsx +20 -12
  82. package/app/map/Breadcrumb.tsx +132 -46
  83. package/app/map/DetailPanel.tsx +408 -297
  84. package/app/map/Explorer.tsx +268 -0
  85. package/app/map/Header.tsx +105 -0
  86. package/app/map/HelpDialog.tsx +37 -34
  87. package/app/map/Legend.tsx +19 -75
  88. package/app/map/LineCard.tsx +187 -0
  89. package/app/map/MapBox.tsx +73 -38
  90. package/app/map/MapCanvas.tsx +344 -115
  91. package/app/map/MapToolbar.tsx +377 -0
  92. package/app/map/MapView.tsx +217 -213
  93. package/app/map/RepoMenu.tsx +13 -12
  94. package/app/map/RoutedEdge.tsx +48 -16
  95. package/app/map/SearchPalette.tsx +6 -6
  96. package/app/map/SourceViewer.tsx +19 -17
  97. package/app/map/StatusBar.tsx +166 -0
  98. package/app/map/embed.ts +22 -2
  99. package/app/map/emphasis.ts +94 -8
  100. package/app/map/explorerRows.ts +85 -0
  101. package/app/map/flowNodes.ts +12 -7
  102. package/app/map/format.ts +2 -2
  103. package/app/map/history.ts +4 -3
  104. package/app/map/inspector.ts +113 -0
  105. package/app/map/labels.ts +66 -7
  106. package/app/map/narrow.ts +165 -85
  107. package/app/map/opening.ts +16 -0
  108. package/app/map/portals.ts +2 -2
  109. package/app/map/routes.ts +1060 -55
  110. package/app/map/runs.ts +108 -0
  111. package/app/map/shell.ts +91 -0
  112. package/app/map/shortcuts.ts +2 -1
  113. package/app/map/summaries.ts +41 -5
  114. package/app/map/text.ts +9 -1
  115. package/app/map/theme.ts +197 -0
  116. package/app/map/useDismiss.ts +20 -6
  117. package/app/map/useEditorBridge.ts +12 -1
  118. package/app/map/useThemeKind.ts +28 -0
  119. package/app/map/useWindowSize.ts +37 -0
  120. package/app/map/viewport.ts +134 -16
  121. package/app/map/weights.ts +80 -0
  122. package/app/page.tsx +3 -5
  123. package/lib/background/child.ts +2 -0
  124. package/lib/background/service.ts +26 -10
  125. package/lib/contracts.ts +25 -2
  126. package/lib/db/migrations/0011_plain_summaries_prompt_version.sql +1 -0
  127. package/lib/db/migrations/meta/0011_snapshot.json +1498 -0
  128. package/lib/db/migrations/meta/_journal.json +7 -0
  129. package/lib/db/schema.ts +2 -1
  130. package/lib/db/store/map.ts +6 -0
  131. package/lib/db/store/summaries.ts +14 -8
  132. package/lib/engine/describe.ts +2 -0
  133. package/lib/index/summarize/budget.ts +5 -2
  134. package/lib/index/summarize/claude.ts +19 -4
  135. package/lib/index/summarize/compare.ts +2 -2
  136. package/lib/index/summarize/plan.ts +73 -13
  137. package/lib/index/summarize/preview.ts +12 -9
  138. package/lib/index/summarize/prompts.ts +122 -25
  139. package/lib/index/summarize/run.ts +48 -18
  140. package/lib/index/summarize/snapshot.ts +7 -2
  141. package/lib/index/summarize/status.ts +3 -2
  142. package/lib/tools/text.ts +3 -2
  143. package/mcp/server.ts +1 -1
  144. package/package.json +4 -2
  145. package/scripts/commands/summarize-command.ts +27 -9
  146. package/.next/server/chunks/ssr/[root-of-the-server]__0ekw8p2ramybv._.js +0 -3
  147. package/.next/server/chunks/ssr/[root-of-the-server]__0fwbsqt9e2tr-._.js +0 -3
  148. package/.next/server/chunks/ssr/[root-of-the-server]__17_rqmx62cz59._.js +0 -3
  149. package/.next/server/chunks/ssr/[root-of-the-server]__1zfp6sltse4hf._.js +0 -3
  150. package/.next/server/chunks/ssr/_1d2woi6toj_0_._.js +0 -3
  151. package/.next/server/chunks/ssr/_1wfc1zz26g5ji._.js +0 -9
  152. package/.next/server/chunks/ssr/app_0gw6epmxyea3q._.js +0 -3
  153. package/.next/server/chunks/ssr/node_modules_@swc_helpers_cjs__interop_require_default_cjs_1ztp13a5szri_._.js +0 -3
  154. package/.next/server/chunks/ssr/node_modules_next_dist_1c5t_vsn6u8fr._.js +0 -3
  155. package/.next/static/chunks/02x9pxyl2d8om.css +0 -3
  156. package/.next/static/chunks/0p-0bv2dzer18.js +0 -7
  157. package/.next/static/chunks/10u7p2gj02qay.js +0 -1
  158. package/.next/static/chunks/31qp8jfkw0x2h.js +0 -31
  159. package/.next/static/media/123d516c9baeb953-s.1qc6dx89jd2qv.woff2 +0 -0
  160. package/.next/static/media/41ba59f553543ecf-s.3cb5lpr2l6xud.woff2 +0 -0
  161. package/.next/static/media/44ed10da57ebfb0e-s.2y65deuc30pmy.woff2 +0 -0
  162. package/.next/static/media/48eea41d8317494f-s.p.0wiir8udbzjvx.woff2 +0 -0
  163. package/.next/static/media/49b1d53681a91a99-s.1yd4_i3e35931.woff2 +0 -0
  164. package/.next/static/media/67bba87670b402d1-s.1u30mmyq6lnsd.woff2 +0 -0
  165. package/.next/static/media/6fca7e74603dd412-s.02z5rrbg5nt92.woff2 +0 -0
  166. package/.next/static/media/73263b2957b73100-s.2qt3tdwt-y9x_.woff2 +0 -0
  167. package/.next/static/media/7ac0b1cd3e695dd0-s.1i-sca43-qwng.woff2 +0 -0
  168. package/.next/static/media/916cd8a3bde3edf8-s.p.0oace-s_gkfks.woff2 +0 -0
  169. package/.next/static/media/a45aa1001bf9176f-s.2vemzm0itqzfy.woff2 +0 -0
  170. package/.next/static/media/a74d2542cc4c775f-s.29yke99gs9qpn.woff2 +0 -0
  171. package/.next/static/media/ab664c0e419cc841-s.3cvcemwuzoywn.woff2 +0 -0
  172. package/.next/static/media/c1b11b726b36a5e5-s.2rixgazldzomk.woff2 +0 -0
  173. package/.next/static/media/d6c1ff7e86974212-s.p.40sczeszzbjw1.woff2 +0 -0
  174. package/.next/static/media/faab88e4be272d29-s.0rgnxg2b64rzs.woff2 +0 -0
  175. package/app/map/ActivityBar.tsx +0 -81
  176. package/app/map/StatusPill.tsx +0 -93
  177. package/app/map/TopBar.tsx +0 -84
  178. /package/.next/static/{prDi039MhjlFqDOOwZ4aR → of6twfEZ3j95xtfQB_NSL}/_buildManifest.js +0 -0
  179. /package/.next/static/{prDi039MhjlFqDOOwZ4aR → of6twfEZ3j95xtfQB_NSL}/_clientMiddlewareManifest.js +0 -0
  180. /package/.next/static/{prDi039MhjlFqDOOwZ4aR → of6twfEZ3j95xtfQB_NSL}/_ssgManifest.js +0 -0
package/.next/trace CHANGED
@@ -1 +1 @@
1
- [{"name":"generate-buildid","duration":182,"timestamp":240792961,"id":4,"parentId":1,"tags":{},"startTime":1793078286800,"traceId":"8f1187a89963bc87"},{"name":"load-custom-routes","duration":1861,"timestamp":240793316,"id":5,"parentId":1,"tags":{},"startTime":1793078286800,"traceId":"8f1187a89963bc87"},{"name":"create-dist-dir","duration":536,"timestamp":240795232,"id":6,"parentId":1,"tags":{},"startTime":1793078286802,"traceId":"8f1187a89963bc87"},{"name":"clean","duration":354,"timestamp":240796426,"id":7,"parentId":1,"tags":{},"startTime":1793078286804,"traceId":"8f1187a89963bc87"},{"name":"discover-routes","duration":8486,"timestamp":240805486,"id":8,"parentId":1,"tags":{},"startTime":1793078286813,"traceId":"8f1187a89963bc87"},{"name":"create-root-mapping","duration":103,"timestamp":240814037,"id":9,"parentId":1,"tags":{},"startTime":1793078286821,"traceId":"8f1187a89963bc87"},{"name":"generate-route-types","duration":15721,"timestamp":240815425,"id":10,"parentId":1,"tags":{},"startTime":1793078286823,"traceId":"8f1187a89963bc87"},{"name":"public-dir-conflict-check","duration":85,"timestamp":240831271,"id":11,"parentId":1,"tags":{},"startTime":1793078286838,"traceId":"8f1187a89963bc87"},{"name":"generate-routes-manifest","duration":2122,"timestamp":240831452,"id":12,"parentId":1,"tags":{},"startTime":1793078286839,"traceId":"8f1187a89963bc87"},{"name":"turbopack-module-graph","duration":6131000,"timestamp":240897404,"id":15,"parentId":1,"tags":{},"startTime":1793078286905,"traceId":"8f1187a89963bc87"},{"name":"turbopack-write-entrypoints","duration":7386000,"timestamp":240857955,"id":17,"parentId":1,"tags":{},"startTime":1793078286865,"traceId":"8f1187a89963bc87"},{"name":"turbopack-emit","duration":2466000,"timestamp":248300689,"id":19,"parentId":1,"tags":{},"startTime":1793078294308,"traceId":"8f1187a89963bc87"},{"name":"run-turbopack","duration":10009117,"timestamp":240838480,"id":14,"parentId":1,"tags":{},"startTime":1793078286846,"traceId":"8f1187a89963bc87"},{"name":"turbopack-persistence","duration":1031000,"timestamp":250850143,"id":23,"parentId":1,"tags":{"reason":"stop","snapshot_duration_ms":2.8043,"persist_duration_ms":1027.6206000000002,"task_count":256,"bytes_written":60453219,"bytes_deleted":0},"startTime":1793078296857,"traceId":"8f1187a89963bc87"},{"name":"run-typescript","duration":12381790,"timestamp":250869828,"id":22,"parentId":1,"tags":{},"startTime":1793078296877,"traceId":"8f1187a89963bc87"},{"name":"generate-required-server-files","duration":737,"timestamp":263252133,"id":26,"parentId":1,"tags":{},"startTime":1793078309259,"traceId":"8f1187a89963bc87"},{"name":"check-static-error-page","duration":11456,"timestamp":263280143,"id":28,"parentId":27,"tags":{},"startTime":1793078309287,"traceId":"8f1187a89963bc87"},{"name":"is-page-static","duration":415713,"timestamp":263293352,"id":46,"parentId":30,"tags":{},"startTime":1793078309300,"traceId":"8f1187a89963bc87"},{"name":"check-page","duration":426030,"timestamp":263283202,"id":30,"parentId":27,"tags":{"page":"/_global-error"},"startTime":1793078309290,"traceId":"8f1187a89963bc87"},{"name":"is-page-static","duration":499620,"timestamp":263293532,"id":48,"parentId":43,"tags":{},"startTime":1793078309301,"traceId":"8f1187a89963bc87"},{"name":"check-page","duration":502042,"timestamp":263291228,"id":43,"parentId":27,"tags":{"page":"/icon.svg"},"startTime":1793078309298,"traceId":"8f1187a89963bc87"},{"name":"is-page-static","duration":504213,"timestamp":263293452,"id":47,"parentId":42,"tags":{},"startTime":1793078309301,"traceId":"8f1187a89963bc87"},{"name":"check-page","duration":506957,"timestamp":263290765,"id":42,"parentId":27,"tags":{"page":"/favicon.ico"},"startTime":1793078309298,"traceId":"8f1187a89963bc87"},{"name":"is-page-static","duration":557638,"timestamp":263292324,"id":45,"parentId":29,"tags":{},"startTime":1793078309299,"traceId":"8f1187a89963bc87"},{"name":"check-page","duration":568480,"timestamp":263281576,"id":29,"parentId":27,"tags":{"page":"/_not-found"},"startTime":1793078309289,"traceId":"8f1187a89963bc87"},{"name":"is-page-static","duration":816102,"timestamp":263297101,"id":50,"parentId":32,"tags":{},"startTime":1793078309304,"traceId":"8f1187a89963bc87"},{"name":"check-page","duration":825594,"timestamp":263287712,"id":32,"parentId":27,"tags":{"page":"/api/imports"},"startTime":1793078309295,"traceId":"8f1187a89963bc87"},{"name":"is-page-static","duration":827770,"timestamp":263298101,"id":52,"parentId":33,"tags":{},"startTime":1793078309305,"traceId":"8f1187a89963bc87"},{"name":"check-page","duration":837949,"timestamp":263288016,"id":33,"parentId":27,"tags":{"page":"/api/index"},"startTime":1793078309295,"traceId":"8f1187a89963bc87"},{"name":"is-page-static","duration":840409,"timestamp":263296547,"id":49,"parentId":31,"tags":{},"startTime":1793078309304,"traceId":"8f1187a89963bc87"},{"name":"check-page","duration":853528,"timestamp":263283523,"id":31,"parentId":27,"tags":{"page":"/api/describe"},"startTime":1793078309291,"traceId":"8f1187a89963bc87"},{"name":"is-page-static","duration":842565,"timestamp":263299656,"id":54,"parentId":36,"tags":{},"startTime":1793078309307,"traceId":"8f1187a89963bc87"},{"name":"check-page","duration":853358,"timestamp":263288947,"id":36,"parentId":27,"tags":{"page":"/api/live/stream"},"startTime":1793078309296,"traceId":"8f1187a89963bc87"},{"name":"is-page-static","duration":853599,"timestamp":263300066,"id":55,"parentId":37,"tags":{},"startTime":1793078309307,"traceId":"8f1187a89963bc87"},{"name":"check-page","duration":864466,"timestamp":263289298,"id":37,"parentId":27,"tags":{"page":"/api/repos"},"startTime":1793078309296,"traceId":"8f1187a89963bc87"},{"name":"is-page-static","duration":862704,"timestamp":263298409,"id":53,"parentId":35,"tags":{},"startTime":1793078309305,"traceId":"8f1187a89963bc87"},{"name":"check-page","duration":872576,"timestamp":263288625,"id":35,"parentId":27,"tags":{"page":"/api/live"},"startTime":1793078309296,"traceId":"8f1187a89963bc87"},{"name":"is-page-static","duration":867536,"timestamp":263300431,"id":56,"parentId":38,"tags":{},"startTime":1793078309308,"traceId":"8f1187a89963bc87"},{"name":"check-page","duration":878400,"timestamp":263289655,"id":38,"parentId":27,"tags":{"page":"/api/search"},"startTime":1793078309297,"traceId":"8f1187a89963bc87"},{"name":"is-page-static","duration":869068,"timestamp":263300737,"id":57,"parentId":39,"tags":{},"startTime":1793078309308,"traceId":"8f1187a89963bc87"},{"name":"check-page","duration":879922,"timestamp":263289933,"id":39,"parentId":27,"tags":{"page":"/api/source"},"startTime":1793078309297,"traceId":"8f1187a89963bc87"},{"name":"is-page-static","duration":872735,"timestamp":263301272,"id":59,"parentId":41,"tags":{},"startTime":1793078309308,"traceId":"8f1187a89963bc87"},{"name":"check-page","duration":883583,"timestamp":263290483,"id":41,"parentId":27,"tags":{"page":"/api/summarize"},"startTime":1793078309298,"traceId":"8f1187a89963bc87"},{"name":"is-page-static","duration":877576,"timestamp":263300973,"id":58,"parentId":40,"tags":{},"startTime":1793078309308,"traceId":"8f1187a89963bc87"},{"name":"check-page","duration":888421,"timestamp":263290198,"id":40,"parentId":27,"tags":{"page":"/api/status"},"startTime":1793078309297,"traceId":"8f1187a89963bc87"},{"name":"is-page-static","duration":911678,"timestamp":263297577,"id":51,"parentId":34,"tags":{},"startTime":1793078309305,"traceId":"8f1187a89963bc87"},{"name":"check-page","duration":921050,"timestamp":263288303,"id":34,"parentId":27,"tags":{"page":"/api/level"},"startTime":1793078309295,"traceId":"8f1187a89963bc87"},{"name":"is-page-static","duration":948582,"timestamp":263301721,"id":60,"parentId":44,"tags":{},"startTime":1793078309309,"traceId":"8f1187a89963bc87"},{"name":"check-page","duration":958966,"timestamp":263291426,"id":44,"parentId":27,"tags":{"page":"/"},"startTime":1793078309299,"traceId":"8f1187a89963bc87"},{"name":"static-check","duration":971171,"timestamp":263279264,"id":27,"parentId":1,"tags":{},"startTime":1793078309286,"traceId":"8f1187a89963bc87"},{"name":"write-routes-manifest","duration":533,"timestamp":264254475,"id":62,"parentId":1,"tags":{},"startTime":1793078310262,"traceId":"8f1187a89963bc87"},{"name":"load-dotenv","duration":37,"timestamp":264264606,"id":65,"parentId":64,"tags":{},"startTime":1793078310272,"traceId":"8f1187a89963bc87"},{"name":"run-export-path-map","duration":502,"timestamp":264266705,"id":66,"parentId":64,"tags":{},"startTime":1793078310274,"traceId":"8f1187a89963bc87"},{"name":"next-export","duration":329452,"timestamp":264263649,"id":64,"parentId":1,"tags":{},"startTime":1793078310271,"traceId":"8f1187a89963bc87"},{"name":"move-exported-app-not-found-","duration":1441,"timestamp":264595345,"id":67,"parentId":63,"tags":{},"startTime":1793078310602,"traceId":"8f1187a89963bc87"},{"name":"move-exported-app-global-error-","duration":867,"timestamp":264596889,"id":68,"parentId":63,"tags":{},"startTime":1793078310604,"traceId":"8f1187a89963bc87"},{"name":"static-generation","duration":341168,"timestamp":264256976,"id":63,"parentId":1,"tags":{},"startTime":1793078310264,"traceId":"8f1187a89963bc87"},{"name":"write-routes-manifest","duration":405,"timestamp":264598259,"id":69,"parentId":1,"tags":{},"startTime":1793078310605,"traceId":"8f1187a89963bc87"},{"name":"print-tree-view","duration":3049,"timestamp":264608723,"id":70,"parentId":1,"tags":{},"startTime":1793078310616,"traceId":"8f1187a89963bc87"},{"name":"write-route-bundle-stats","duration":5228,"timestamp":264611824,"id":71,"parentId":1,"tags":{},"startTime":1793078310619,"traceId":"8f1187a89963bc87"},{"name":"telemetry-flush","duration":56,"timestamp":264617088,"id":72,"parentId":1,"tags":{},"startTime":1793078310624,"traceId":"8f1187a89963bc87"},{"name":"next-build","duration":23873188,"timestamp":240744002,"id":1,"tags":{"buildMode":"default","version":"16.4.3","bundler":"turbopack","has-custom-webpack-config":"false","use-build-worker":"true"},"startTime":1793078286751,"traceId":"8f1187a89963bc87"}]
1
+ [{"name":"generate-buildid","duration":183,"timestamp":272764806,"id":4,"parentId":1,"tags":{},"startTime":1793397981188,"traceId":"443087a81efb0109"},{"name":"load-custom-routes","duration":1842,"timestamp":272765164,"id":5,"parentId":1,"tags":{},"startTime":1793397981189,"traceId":"443087a81efb0109"},{"name":"create-dist-dir","duration":565,"timestamp":272767061,"id":6,"parentId":1,"tags":{},"startTime":1793397981191,"traceId":"443087a81efb0109"},{"name":"clean","duration":354,"timestamp":272768334,"id":7,"parentId":1,"tags":{},"startTime":1793397981192,"traceId":"443087a81efb0109"},{"name":"discover-routes","duration":8249,"timestamp":272777046,"id":8,"parentId":1,"tags":{},"startTime":1793397981201,"traceId":"443087a81efb0109"},{"name":"create-root-mapping","duration":113,"timestamp":272785391,"id":9,"parentId":1,"tags":{},"startTime":1793397981209,"traceId":"443087a81efb0109"},{"name":"generate-route-types","duration":15571,"timestamp":272786795,"id":10,"parentId":1,"tags":{},"startTime":1793397981210,"traceId":"443087a81efb0109"},{"name":"public-dir-conflict-check","duration":82,"timestamp":272802495,"id":11,"parentId":1,"tags":{},"startTime":1793397981226,"traceId":"443087a81efb0109"},{"name":"generate-routes-manifest","duration":2244,"timestamp":272802683,"id":12,"parentId":1,"tags":{},"startTime":1793397981226,"traceId":"443087a81efb0109"},{"name":"turbopack-module-graph","duration":5969000,"timestamp":272868649,"id":15,"parentId":1,"tags":{},"startTime":1793397981292,"traceId":"443087a81efb0109"},{"name":"turbopack-write-entrypoints","duration":7170000,"timestamp":272831994,"id":17,"parentId":1,"tags":{},"startTime":1793397981256,"traceId":"443087a81efb0109"},{"name":"turbopack-emit","duration":2544000,"timestamp":280049652,"id":19,"parentId":1,"tags":{},"startTime":1793397988473,"traceId":"443087a81efb0109"},{"name":"run-turbopack","duration":9950933,"timestamp":272810215,"id":14,"parentId":1,"tags":{},"startTime":1793397981234,"traceId":"443087a81efb0109"},{"name":"turbopack-persistence","duration":926000,"timestamp":282762850,"id":23,"parentId":1,"tags":{"reason":"stop","snapshot_duration_ms":3.5530000000000004,"persist_duration_ms":922.6213,"task_count":256,"bytes_written":61340073,"bytes_deleted":0},"startTime":1793397991187,"traceId":"443087a81efb0109"},{"name":"run-typescript","duration":12861772,"timestamp":282797208,"id":22,"parentId":1,"tags":{},"startTime":1793397991221,"traceId":"443087a81efb0109"},{"name":"generate-required-server-files","duration":972,"timestamp":295659404,"id":26,"parentId":1,"tags":{},"startTime":1793398004083,"traceId":"443087a81efb0109"},{"name":"check-static-error-page","duration":10506,"timestamp":295685770,"id":28,"parentId":27,"tags":{},"startTime":1793398004109,"traceId":"443087a81efb0109"},{"name":"is-page-static","duration":414766,"timestamp":295697957,"id":46,"parentId":30,"tags":{},"startTime":1793398004122,"traceId":"443087a81efb0109"},{"name":"check-page","duration":423788,"timestamp":295689093,"id":30,"parentId":27,"tags":{"page":"/_global-error"},"startTime":1793398004113,"traceId":"443087a81efb0109"},{"name":"is-page-static","duration":498369,"timestamp":295698134,"id":48,"parentId":43,"tags":{},"startTime":1793398004122,"traceId":"443087a81efb0109"},{"name":"check-page","duration":500678,"timestamp":295695934,"id":43,"parentId":27,"tags":{"page":"/icon.svg"},"startTime":1793398004120,"traceId":"443087a81efb0109"},{"name":"is-page-static","duration":518272,"timestamp":295698051,"id":47,"parentId":42,"tags":{},"startTime":1793398004122,"traceId":"443087a81efb0109"},{"name":"check-page","duration":520836,"timestamp":295695557,"id":42,"parentId":27,"tags":{"page":"/favicon.ico"},"startTime":1793398004119,"traceId":"443087a81efb0109"},{"name":"is-page-static","duration":539146,"timestamp":295697026,"id":45,"parentId":29,"tags":{},"startTime":1793398004121,"traceId":"443087a81efb0109"},{"name":"check-page","duration":548630,"timestamp":295687643,"id":29,"parentId":27,"tags":{"page":"/_not-found"},"startTime":1793398004111,"traceId":"443087a81efb0109"},{"name":"is-page-static","duration":816951,"timestamp":295701535,"id":50,"parentId":32,"tags":{},"startTime":1793398004125,"traceId":"443087a81efb0109"},{"name":"check-page","duration":825700,"timestamp":295692904,"id":32,"parentId":27,"tags":{"page":"/api/imports"},"startTime":1793398004117,"traceId":"443087a81efb0109"},{"name":"is-page-static","duration":823463,"timestamp":295701039,"id":49,"parentId":31,"tags":{},"startTime":1793398004125,"traceId":"443087a81efb0109"},{"name":"check-page","duration":835162,"timestamp":295689402,"id":31,"parentId":27,"tags":{"page":"/api/describe"},"startTime":1793398004113,"traceId":"443087a81efb0109"},{"name":"is-page-static","duration":826569,"timestamp":295702426,"id":52,"parentId":34,"tags":{},"startTime":1793398004126,"traceId":"443087a81efb0109"},{"name":"check-page","duration":835629,"timestamp":295693424,"id":34,"parentId":27,"tags":{"page":"/api/level"},"startTime":1793398004117,"traceId":"443087a81efb0109"},{"name":"is-page-static","duration":831100,"timestamp":295703198,"id":54,"parentId":36,"tags":{},"startTime":1793398004127,"traceId":"443087a81efb0109"},{"name":"check-page","duration":840418,"timestamp":295693937,"id":36,"parentId":27,"tags":{"page":"/api/live/stream"},"startTime":1793398004118,"traceId":"443087a81efb0109"},{"name":"is-page-static","duration":840347,"timestamp":295703649,"id":55,"parentId":37,"tags":{},"startTime":1793398004127,"traceId":"443087a81efb0109"},{"name":"check-page","duration":849859,"timestamp":295694211,"id":37,"parentId":27,"tags":{"page":"/api/repos"},"startTime":1793398004118,"traceId":"443087a81efb0109"},{"name":"is-page-static","duration":854375,"timestamp":295702693,"id":53,"parentId":35,"tags":{},"startTime":1793398004126,"traceId":"443087a81efb0109"},{"name":"check-page","duration":863482,"timestamp":295693669,"id":35,"parentId":27,"tags":{"page":"/api/live"},"startTime":1793398004117,"traceId":"443087a81efb0109"},{"name":"is-page-static","duration":852721,"timestamp":295705129,"id":56,"parentId":38,"tags":{},"startTime":1793398004129,"traceId":"443087a81efb0109"},{"name":"check-page","duration":863425,"timestamp":295694471,"id":38,"parentId":27,"tags":{"page":"/api/search"},"startTime":1793398004118,"traceId":"443087a81efb0109"},{"name":"is-page-static","duration":859248,"timestamp":295702011,"id":51,"parentId":33,"tags":{},"startTime":1793398004126,"traceId":"443087a81efb0109"},{"name":"check-page","duration":868131,"timestamp":295693179,"id":33,"parentId":27,"tags":{"page":"/api/index"},"startTime":1793398004117,"traceId":"443087a81efb0109"},{"name":"is-page-static","duration":860330,"timestamp":295705435,"id":57,"parentId":39,"tags":{},"startTime":1793398004129,"traceId":"443087a81efb0109"},{"name":"check-page","duration":871129,"timestamp":295694730,"id":39,"parentId":27,"tags":{"page":"/api/source"},"startTime":1793398004118,"traceId":"443087a81efb0109"},{"name":"is-page-static","duration":860790,"timestamp":295706058,"id":59,"parentId":41,"tags":{},"startTime":1793398004130,"traceId":"443087a81efb0109"},{"name":"check-page","duration":871579,"timestamp":295695312,"id":41,"parentId":27,"tags":{"page":"/api/summarize"},"startTime":1793398004119,"traceId":"443087a81efb0109"},{"name":"is-page-static","duration":862904,"timestamp":295705735,"id":58,"parentId":40,"tags":{},"startTime":1793398004129,"traceId":"443087a81efb0109"},{"name":"check-page","duration":873651,"timestamp":295695031,"id":40,"parentId":27,"tags":{"page":"/api/status"},"startTime":1793398004119,"traceId":"443087a81efb0109"},{"name":"is-page-static","duration":923383,"timestamp":295706628,"id":60,"parentId":44,"tags":{},"startTime":1793398004130,"traceId":"443087a81efb0109"},{"name":"check-page","duration":933991,"timestamp":295696097,"id":44,"parentId":27,"tags":{"page":"/"},"startTime":1793398004120,"traceId":"443087a81efb0109"},{"name":"static-check","duration":944991,"timestamp":295685134,"id":27,"parentId":1,"tags":{},"startTime":1793398004109,"traceId":"443087a81efb0109"},{"name":"write-routes-manifest","duration":1088,"timestamp":296633401,"id":62,"parentId":1,"tags":{},"startTime":1793398005057,"traceId":"443087a81efb0109"},{"name":"load-dotenv","duration":34,"timestamp":296643846,"id":65,"parentId":64,"tags":{},"startTime":1793398005067,"traceId":"443087a81efb0109"},{"name":"run-export-path-map","duration":458,"timestamp":296646197,"id":66,"parentId":64,"tags":{},"startTime":1793398005070,"traceId":"443087a81efb0109"},{"name":"next-export","duration":262819,"timestamp":296642919,"id":64,"parentId":1,"tags":{},"startTime":1793398005067,"traceId":"443087a81efb0109"},{"name":"move-exported-app-not-found-","duration":1479,"timestamp":296907912,"id":67,"parentId":63,"tags":{},"startTime":1793398005332,"traceId":"443087a81efb0109"},{"name":"move-exported-app-global-error-","duration":745,"timestamp":296909496,"id":68,"parentId":63,"tags":{},"startTime":1793398005333,"traceId":"443087a81efb0109"},{"name":"static-generation","duration":274394,"timestamp":296636292,"id":63,"parentId":1,"tags":{},"startTime":1793398005060,"traceId":"443087a81efb0109"},{"name":"write-routes-manifest","duration":506,"timestamp":296910794,"id":69,"parentId":1,"tags":{},"startTime":1793398005334,"traceId":"443087a81efb0109"},{"name":"print-tree-view","duration":3124,"timestamp":296919991,"id":70,"parentId":1,"tags":{},"startTime":1793398005344,"traceId":"443087a81efb0109"},{"name":"write-route-bundle-stats","duration":4225,"timestamp":296923157,"id":71,"parentId":1,"tags":{},"startTime":1793398005347,"traceId":"443087a81efb0109"},{"name":"telemetry-flush","duration":67,"timestamp":296927421,"id":72,"parentId":1,"tags":{},"startTime":1793398005351,"traceId":"443087a81efb0109"},{"name":"next-build","duration":24213026,"timestamp":272714503,"id":1,"tags":{"buildMode":"default","version":"16.4.3","bundler":"turbopack","has-custom-webpack-config":"false","use-build-worker":"true"},"startTime":1793397981138,"traceId":"443087a81efb0109"}]
package/.next/trace-build CHANGED
@@ -1 +1 @@
1
- [{"name":"turbopack-module-graph","duration":6131000,"timestamp":240897404,"id":15,"parentId":1,"tags":{},"startTime":1793078286905,"traceId":"8f1187a89963bc87"},{"name":"turbopack-write-entrypoints","duration":7386000,"timestamp":240857955,"id":17,"parentId":1,"tags":{},"startTime":1793078286865,"traceId":"8f1187a89963bc87"},{"name":"turbopack-emit","duration":2466000,"timestamp":248300689,"id":19,"parentId":1,"tags":{},"startTime":1793078294308,"traceId":"8f1187a89963bc87"},{"name":"run-turbopack","duration":10009117,"timestamp":240838480,"id":14,"parentId":1,"tags":{},"startTime":1793078286846,"traceId":"8f1187a89963bc87"},{"name":"turbopack-persistence","duration":1031000,"timestamp":250850143,"id":23,"parentId":1,"tags":{"reason":"stop","snapshot_duration_ms":2.8043,"persist_duration_ms":1027.6206000000002,"task_count":256,"bytes_written":60453219,"bytes_deleted":0},"startTime":1793078296857,"traceId":"8f1187a89963bc87"},{"name":"run-typescript","duration":12381790,"timestamp":250869828,"id":22,"parentId":1,"tags":{},"startTime":1793078296877,"traceId":"8f1187a89963bc87"},{"name":"static-check","duration":971171,"timestamp":263279264,"id":27,"parentId":1,"tags":{},"startTime":1793078309286,"traceId":"8f1187a89963bc87"},{"name":"static-generation","duration":341168,"timestamp":264256976,"id":63,"parentId":1,"tags":{},"startTime":1793078310264,"traceId":"8f1187a89963bc87"},{"name":"telemetry-flush","duration":56,"timestamp":264617088,"id":72,"parentId":1,"tags":{},"startTime":1793078310624,"traceId":"8f1187a89963bc87"},{"name":"next-build","duration":23873188,"timestamp":240744002,"id":1,"tags":{"buildMode":"default","version":"16.4.3","bundler":"turbopack","has-custom-webpack-config":"false","use-build-worker":"true"},"startTime":1793078286751,"traceId":"8f1187a89963bc87"}]
1
+ [{"name":"turbopack-module-graph","duration":5969000,"timestamp":272868649,"id":15,"parentId":1,"tags":{},"startTime":1793397981292,"traceId":"443087a81efb0109"},{"name":"turbopack-write-entrypoints","duration":7170000,"timestamp":272831994,"id":17,"parentId":1,"tags":{},"startTime":1793397981256,"traceId":"443087a81efb0109"},{"name":"turbopack-emit","duration":2544000,"timestamp":280049652,"id":19,"parentId":1,"tags":{},"startTime":1793397988473,"traceId":"443087a81efb0109"},{"name":"run-turbopack","duration":9950933,"timestamp":272810215,"id":14,"parentId":1,"tags":{},"startTime":1793397981234,"traceId":"443087a81efb0109"},{"name":"turbopack-persistence","duration":926000,"timestamp":282762850,"id":23,"parentId":1,"tags":{"reason":"stop","snapshot_duration_ms":3.5530000000000004,"persist_duration_ms":922.6213,"task_count":256,"bytes_written":61340073,"bytes_deleted":0},"startTime":1793397991187,"traceId":"443087a81efb0109"},{"name":"run-typescript","duration":12861772,"timestamp":282797208,"id":22,"parentId":1,"tags":{},"startTime":1793397991221,"traceId":"443087a81efb0109"},{"name":"static-check","duration":944991,"timestamp":295685134,"id":27,"parentId":1,"tags":{},"startTime":1793398004109,"traceId":"443087a81efb0109"},{"name":"static-generation","duration":274394,"timestamp":296636292,"id":63,"parentId":1,"tags":{},"startTime":1793398005060,"traceId":"443087a81efb0109"},{"name":"telemetry-flush","duration":67,"timestamp":296927421,"id":72,"parentId":1,"tags":{},"startTime":1793398005351,"traceId":"443087a81efb0109"},{"name":"next-build","duration":24213026,"timestamp":272714503,"id":1,"tags":{"buildMode":"default","version":"16.4.3","bundler":"turbopack","has-custom-webpack-config":"false","use-build-worker":"true"},"startTime":1793397981138,"traceId":"443087a81efb0109"}]
package/README.md CHANGED
@@ -47,7 +47,10 @@ That's it. Here are some things to ask Claude Code.
47
47
 
48
48
  It'll use Nebulosity's tools when they help, and it can point things out on the Map while it explains. If something seems off, `nebulosity doctor` will tell you what's missing.
49
49
 
50
- ![Claude Code in VS Code's terminal, asked which folders inside src/vs import terminal.ts. It answers that five do, and the Map above highlights those five (workbench, platform, sessions, server and code) while base and editor stay plain](docs/screenshots/claude-map.png)
50
+ <picture>
51
+ <source media="(prefers-color-scheme: light)" srcset="docs/screenshots/claude-map-light.png">
52
+ <img alt="Claude Code in VS Code's terminal, asked which folders inside src/vs import terminal.ts. It answers that five do, and the Map above highlights those five (workbench, platform, sessions, server and code) while base and editor stay plain" src="docs/screenshots/claude-map.png">
53
+ </picture>
51
54
 
52
55
  ## Features
53
56
 
@@ -63,9 +66,12 @@ And it's **free**. Everything above works without an API key, and Nebulosity its
63
66
 
64
67
  ## VS Code extension
65
68
 
66
- The extension shows the Map beside your code. It follows whatever file you have open, opens a file when you click it on the Map, and can light up the files that import the one you're looking at.
69
+ The extension shows the Map beside your code. It follows whatever file you have open, opens a file when you double-click it on the Map or press Open in VS Code, and can light up the files that import the one you're looking at.
67
70
 
68
- ![The Nebulosity extension in VS Code. editor.main.ts is open in the editor and selected on the Map beside it, with lines to the files it imports and its summary open](docs/screenshots/vscode-extension.png)
71
+ <picture>
72
+ <source media="(prefers-color-scheme: light)" srcset="docs/screenshots/vscode-extension-light.png">
73
+ <img alt="The Nebulosity extension in VS Code. findModel.ts is open in the editor and selected on the Map beside it, with lilac lines to the files it imports and gold lines from the four that import it. Below, Claude Code was asked which files in that folder import findModel.ts, and the Map rings those four in orange" src="docs/screenshots/vscode-extension.png">
74
+ </picture>
69
75
 
70
76
  1. Install the `nebulosity` package and index your repo (see above).
71
77
  2. Install the **Nebulosity** extension from the [Marketplace](https://marketplace.visualstudio.com/items?itemName=andrewl746.nebulosity-vscode) or [Open VSX](https://open-vsx.org/extension/andrewl746/nebulosity-vscode), or run `code --install-extension andrewl746.nebulosity-vscode` in a terminal.
@@ -85,7 +91,10 @@ To add a key, [create one in the Claude Console](https://platform.claude.com/doc
85
91
 
86
92
  ## Architecture
87
93
 
88
- ![Nebulosity's architecture diagram. nebulosity index reads your repo into the index, a SQLite database on your machine, and the Map keeps it current on every save. The MCP server and the Map both read the index. Claude Code asks the MCP server and gets its answer, often in one call, and each call shows up on the Map. The only thing that leaves your machine is the optional AI summaries](docs/screenshots/architecture.png)
94
+ <picture>
95
+ <source media="(prefers-color-scheme: light)" srcset="docs/screenshots/architecture-light.png">
96
+ <img alt="Nebulosity's architecture diagram. nebulosity index reads your repo into the index, a SQLite database on your machine, and the Map keeps it current on every save. The MCP server and the Map both read the index. Claude Code asks the MCP server and gets its answer, often in one call, and each call shows up on the Map. The only thing that leaves your machine is the optional AI summaries" src="docs/screenshots/architecture.png">
97
+ </picture>
89
98
 
90
99
  `nebulosity index` reads your repo once and writes down every file, import and folder in a SQLite database on your machine. From then on, everything works from that index. When Claude Code asks a question, the MCP server answers from it, and the Map draws from the same data. While the Map is open, a background worker watches for saves and updates the index as you go, so neither one falls behind. And every time Claude Code uses one of Nebulosity's tools, the Map lights up what it's looking at.
91
100
 
package/app/globals.css CHANGED
@@ -1,75 +1,85 @@
1
1
  @import "tailwindcss";
2
2
 
3
3
  /*
4
- * The Map's colors (VISUAL_REFRESH.md §2): each token is defined once here and means one thing. Components use the
5
- * tokens (bg-surface, text-text-2, border-select, …), never a raw value. The owner's pick of 2026-10-13, "night violet +
6
- * cyan", taken from the logo (app/icon.svg): night-violet surfaces instead of violet-grey, lavender names, the selection
7
- * still vivid purple, the logo's violet for the overlays and its cyan for everything you click.
4
+ * The Map's colors (the Workbench redesign, 2026-10-27): each token is defined once here and means one thing, and
5
+ * components use the tokens (bg-node, text-text-2, border-accent, …), never a raw value. These are app/map/theme.ts's
6
+ * fromTheme for VS Code's Dark 2026, the browser's and the demo's palette (theme.test.ts checks they agree). Inside VS
7
+ * Code's panel the same tokens are set from the person's own theme (useTheme.ts), over these. Neutral grays, and purple
8
+ * only where it means something, in the logo's own colors, with gold for what uses the selection.
8
9
  */
9
10
  :root {
10
- --canvas: #0E0A1C; /* page and Map background, one flat night violet (the logo tile's dark end) */
11
- --surface: #22193F; /* boxes, inputs, cards: one step brighter than the canvas, so the content leads */
12
- --panel: #140E28; /* the details panel, drawers, dialogs */
13
- --hairline: #261B45; /* dividers */
14
- --border: #4B3B85; /* box and input borders, defined enough that boxes read as objects */
15
- --text: #F1EEF8; /* primary text: names, headings */
16
- --text-body: #D3C7EE; /* paragraphs: summaries, help */
17
- --text-2: #B9A9DE; /* secondary text, counts, labels */
18
- --title: #C7B3FF; /* lavender: a description's title (a summary's tagline, help headings) */
19
- --code: #D8CAFF; /* lavender: code identifiers in text */
20
- --code-bg: #2A1B52; /* the chip behind them */
21
- --folder: #A98BEA; /* lavender: the folder icon, so folders and files part at a glance */
22
- --neutral-edge: #7262A6; /* ordinary connections, bright enough to follow on the canvas (3.7:1) */
23
- --select: #B58AFF; /* purple: the selected box, its direct links, its path. Nothing else */
24
- --select-fill: #3A2178; /* the selected box's fill: strong enough that the box, not its lines, is seen first */
11
+ --canvas: #121314; /* under the Map: the editor's background */
12
+ --panel: #191A1B; /* the header, explorer, inspector, status bar and dialogs: the side bar's background */
13
+ --node: #222223; /* a box, an input, a chip */
14
+ --node-sel: #2A1E38; /* the selected box */
15
+ --row-sel: #332543; /* the selected row in the explorer and the inspector */
16
+ --divider: #2A2B2C; /* lines between areas */
17
+ --border: #464747; /* a box's, an input's and a button's border */
18
+ --linked-border: #8345BE; /* the border of a box linked to the selection */
19
+ --text: #BFBFBF; /* names and headings: the theme's own text */
20
+ --text-2: #999999; /* secondary text, counts, summaries */
21
+ --text-3: #8C8C8C; /* the quietest text: labels, the legend, the status bar */
22
+ --edge-dim: #464747; /* a line that isn't the selection's */
23
+ --edge-strong: #E9D5FF; /* the selection's lines out, and Uses' bars, underline and mark: the logo's spoke color */
24
+ --glyph-dim: #606061; /* a dot or a page icon that isn't linked to the selection */
25
+ --linked-glyph: #C084FC; /* the dots of what's linked to the selection, and their explorer bars: the logo's outer dots */
26
+ --accent: #A855F7; /* the selection's border, the selected dot's ring, the Contents tab, the one primary button */
27
+ --on-accent: #120C1C; /* text on the accent */
28
+ --core: #F0FDFF; /* the selected dot's core: the logo's own */
25
29
  --agent: #F08A4B; /* orange: what Claude Code is touching right now. Nothing else */
26
- --ok: #4CC38A; /* green: indexing status only */
27
30
  --danger: #F07A7A; /* errors and a failed stage */
28
- --control: #67E8F9; /* cyan (the logo's glow): something you click — links, text buttons, the overlays' buttons. Nothing else */
29
- --overlay: #2A1F52; /* raised night violet: every control on the Map (legend, page pill, zoom) */
30
- --overlay-line: #3A2D6B; /* dividers inside an overlay, and a control's hover */
31
- --overlay-text-2: #C9BCEB; /* secondary text on an overlay */
32
- --grid: #262039; /* the canvas's faint dot grid, so the Map has texture without competing with boxes */
31
+ --ok: #5FC9D9; /* the indexed dot. Nothing else */
32
+ --focus: #67E8F9; /* the keyboard focus ring */
33
+ --fade: 50%; /* how much of its color a box away from the selection keeps, mixed with the background */
34
+ /* gold: what uses the selection, across from the purple of what it uses (the owner, 2026-10-29, after pink) */
35
+ --used-by-edge: #FCD34D; /* the selection's lines in, and Used by's bars, underline and mark */
36
+ color-scheme: dark;
37
+ }
38
+
39
+ /* a light VS Code theme: native scrollbars and form controls go light too (useTheme.ts sets the kind) */
40
+ :root[data-kind="light"], :root[data-kind="hc-light"] {
41
+ color-scheme: light;
33
42
  }
34
43
 
35
44
  @theme inline {
36
45
  --color-canvas: var(--canvas);
37
- --color-surface: var(--surface);
38
46
  --color-panel: var(--panel);
39
- --color-hairline: var(--hairline);
47
+ --color-node: var(--node);
48
+ --color-node-sel: var(--node-sel);
49
+ --color-row-sel: var(--row-sel);
50
+ --color-divider: var(--divider);
40
51
  --color-border: var(--border);
52
+ --color-linked-border: var(--linked-border);
41
53
  --color-text: var(--text);
42
- --color-text-body: var(--text-body);
43
54
  --color-text-2: var(--text-2);
44
- --color-title: var(--title);
45
- --color-code: var(--code);
46
- --color-code-bg: var(--code-bg);
47
- --color-folder: var(--folder);
48
- --color-neutral-edge: var(--neutral-edge);
49
- --color-select: var(--select);
50
- --color-select-fill: var(--select-fill);
55
+ --color-text-3: var(--text-3);
56
+ --color-edge-dim: var(--edge-dim);
57
+ --color-edge-strong: var(--edge-strong);
58
+ --color-glyph-dim: var(--glyph-dim);
59
+ --color-linked-glyph: var(--linked-glyph);
60
+ --color-accent: var(--accent);
61
+ --color-on-accent: var(--on-accent);
62
+ --color-core: var(--core);
51
63
  --color-agent: var(--agent);
52
- --color-ok: var(--ok);
53
64
  --color-danger: var(--danger);
54
- --color-control: var(--control);
55
- --color-overlay: var(--overlay);
56
- --color-overlay-line: var(--overlay-line);
57
- --color-overlay-text-2: var(--overlay-text-2);
58
- --color-grid: var(--grid);
59
- --font-sans: var(--font-plex-sans);
60
- --font-mono: var(--font-plex-mono);
65
+ --color-ok: var(--ok);
66
+ --color-focus: var(--focus);
67
+ --color-used-by-edge: var(--used-by-edge);
68
+ --font-sans: var(--font-archivo);
69
+ --font-mono: var(--font-jetbrains-mono);
61
70
  }
62
71
 
63
72
  body {
64
73
  background: var(--canvas);
65
74
  color: var(--text);
66
- font-family: var(--font-plex-sans), system-ui, sans-serif;
75
+ font-family: var(--font-archivo), system-ui, sans-serif;
76
+ font-variant-numeric: tabular-nums;
67
77
  }
68
78
 
69
79
  /*
70
80
  * Syntax colors, for code only: the source viewer and search's code lines (VISUAL_REFRESH.md §2). They're VS Code's
71
- * Dark+ palette, so code reads the way it does in the editor (owner review). Inside code they mean token kinds and
72
- * nothing else; nothing on the Map uses them.
81
+ * Dark+ palette, so code reads the way it does in the editor (owner review), and its Light+ palette under a light VS
82
+ * Code theme. Inside code they mean token kinds and nothing else; nothing on the Map uses them.
73
83
  */
74
84
  :root {
75
85
  --syn-text: #D4D4D4;
@@ -85,6 +95,20 @@ body {
85
95
  --syn-regexp: #D16969;
86
96
  }
87
97
 
98
+ :root[data-kind="light"], :root[data-kind="hc-light"] {
99
+ --syn-text: #000000;
100
+ --syn-keyword: #0000FF;
101
+ --syn-control: #AF00DB;
102
+ --syn-string: #A31515;
103
+ --syn-number: #098658;
104
+ --syn-comment: #008000;
105
+ --syn-type: #267F99;
106
+ --syn-function: #795E26;
107
+ --syn-variable: #001080;
108
+ --syn-constant: #0070C1;
109
+ --syn-regexp: #811F3F;
110
+ }
111
+
88
112
  .syntax { color: var(--syn-text); }
89
113
  .syntax .hljs-keyword, .syntax .hljs-literal, .syntax .hljs-variable.language_ { color: var(--syn-keyword); }
90
114
  .syntax .hljs-control { color: var(--syn-control); }
@@ -117,20 +141,25 @@ body {
117
141
  scrollbar-width: thin;
118
142
  scrollbar-color: var(--border) transparent;
119
143
  }
144
+
145
+ /* a visible ring for the keyboard only, in the theme's focus color */
146
+ :focus-visible {
147
+ outline: 2px solid var(--focus);
148
+ outline-offset: 2px;
149
+ }
120
150
  }
121
151
 
122
152
  /* React Flow's own parts (controls, edge labels) take the same tokens */
123
153
  .react-flow {
124
154
  --xy-background-color: var(--canvas);
125
- --xy-edge-stroke: var(--neutral-edge);
126
- --xy-edge-label-background-color: var(--surface);
155
+ --xy-edge-stroke: var(--edge-dim);
156
+ --xy-edge-label-background-color: var(--node);
127
157
  --xy-edge-label-color: var(--text);
128
- /* the zoom controls share the one control style: raised night violet, cyan icons (owner review) */
129
- --xy-controls-button-background-color: var(--overlay);
130
- --xy-controls-button-background-color-hover: var(--overlay-line);
131
- --xy-controls-button-color: var(--control);
132
- --xy-controls-button-color-hover: var(--control);
133
- --xy-controls-button-border-color: var(--overlay-line);
158
+ --xy-controls-button-background-color: var(--panel);
159
+ --xy-controls-button-background-color-hover: var(--node);
160
+ --xy-controls-button-color: var(--text-2);
161
+ --xy-controls-button-color-hover: var(--text);
162
+ --xy-controls-button-border-color: var(--divider);
134
163
  --xy-controls-box-shadow: none;
135
164
  }
136
165
 
@@ -156,3 +185,11 @@ body {
156
185
  transition: none;
157
186
  }
158
187
  }
188
+
189
+ /*
190
+ * React Flow paints its viewport's own layer (ViewportPortal) above the boxes. The Map's holds what belongs under the
191
+ * lines, the folders' back cards and the loose boxes' divider (MapCanvas), so it goes beneath every line and box.
192
+ */
193
+ .react-flow__viewport-portal {
194
+ z-index: -1;
195
+ }
package/app/layout.tsx CHANGED
@@ -1,16 +1,19 @@
1
1
  import type { Metadata } from "next";
2
- import { IBM_Plex_Mono, IBM_Plex_Sans } from "next/font/google";
2
+ import { Archivo, JetBrains_Mono } from "next/font/google";
3
+ import Script from "next/script";
3
4
  import "./globals.css";
5
+ import { earlyThemeScript } from "./map/theme";
4
6
 
5
- // IBM Plex, the owner's pick (2026-10-12): the two weights the type scale uses (VISUAL_REFRESH.md §7)
6
- const plexSans = IBM_Plex_Sans({
7
- variable: "--font-plex-sans",
7
+ // Archivo for the text and JetBrains Mono for names, paths and code, the Workbench mockups' fonts and the owner's pick of
8
+ // 2026-10-27 (ADR-070). next/font serves them from the Map's own server, so they work offline and inside VS Code's panel
9
+ const archivo = Archivo({
10
+ variable: "--font-archivo",
8
11
  subsets: ["latin"],
9
- weight: ["400", "500"],
12
+ weight: ["400", "500", "600"],
10
13
  });
11
14
 
12
- const plexMono = IBM_Plex_Mono({
13
- variable: "--font-plex-mono",
15
+ const jetbrainsMono = JetBrains_Mono({
16
+ variable: "--font-jetbrains-mono",
14
17
  subsets: ["latin"],
15
18
  weight: ["400", "500"],
16
19
  });
@@ -26,14 +29,20 @@ export default function RootLayout({
26
29
  children: React.ReactNode;
27
30
  }>) {
28
31
  return (
29
- // suppressHydrationWarning: browser extensions (QuillBot, say) add attributes to <html> before React loads; this
30
- // ignores attribute differences on this one tag only, never in the page below it
32
+ // suppressHydrationWarning: browser extensions (QuillBot, say) add attributes to <html> before React loads, and inside
33
+ // VS Code's panel the theme's kind and colors are set on it before the first paint; this ignores attribute
34
+ // differences on this one tag only, never in the page below it
31
35
  <html
32
36
  lang="en"
33
- className={`${plexSans.variable} ${plexMono.variable} h-full antialiased`}
37
+ className={`${archivo.variable} ${jetbrainsMono.variable} h-full antialiased`}
34
38
  suppressHydrationWarning
35
39
  >
36
- <body className="min-h-full flex flex-col">{children}</body>
40
+ <body className="min-h-full flex flex-col">
41
+ {/* inside VS Code's panel, a light or high contrast theme's colors from the first paint (theme.ts); Next puts
42
+ a beforeInteractive script in the head, ahead of the page's own */}
43
+ <Script id="nebulosity-theme" strategy="beforeInteractive">{earlyThemeScript()}</Script>
44
+ {children}
45
+ </body>
37
46
  </html>
38
47
  );
39
48
  }
@@ -3,10 +3,10 @@
3
3
  import { IconArrowLeft } from "@tabler/icons-react";
4
4
 
5
5
  /**
6
- * Back, inside VS Code's panel (owner review, 2026-10-25). The webview has no browser Back, though the Map's moves go
7
- * into its history as in a browser tab (history.ts), so this goes back one of them. It's disabled at the Map's first
8
- * entry (historyDepth 0), where going back would take the webview off the Map. A browser tab keeps its own Back, so the
9
- * Map shows no button there.
6
+ * Back, first inside VS Code's panel (owner review, 2026-10-25), whose webview has no browser Back, and since
7
+ * 2026-10-29 in the browser and the demo too, so the Map has one Back everywhere (the owner). The Map's moves go into
8
+ * the history (history.ts), so this goes back one of them. It's disabled at the Map's first entry (historyDepth 0),
9
+ * where going back would take the webview off the Map, or a browser tab to the page before it.
10
10
  */
11
11
  export default function BackButton({ enabled }: { enabled: boolean }){
12
12
  return (
@@ -17,7 +17,7 @@ export default function BackButton({ enabled }: { enabled: boolean }){
17
17
  onClick={() => window.history.back()}
18
18
  aria-label="Back"
19
19
  title={enabled ? "Back to where you were" : "Back (nothing to go back to yet)"}
20
- className="grid h-7 w-7 shrink-0 place-items-center rounded-md text-control hover:bg-surface disabled:opacity-35 disabled:hover:bg-transparent"
20
+ className="grid h-7 w-7 shrink-0 place-items-center rounded-md text-text hover:bg-node max-[360px]:w-6 disabled:opacity-35 disabled:hover:bg-transparent"
21
21
  >
22
22
  <IconArrowLeft aria-hidden size={18} stroke={2} />
23
23
  </button>
@@ -4,26 +4,30 @@ import { useStore } from "@xyflow/react";
4
4
  import type { MapNode } from "@/lib/contracts";
5
5
  import { BOX_HEIGHT, BOX_WIDTH } from "./levelLayout";
6
6
  import { actionsPlace } from "./narrow";
7
+ import { openingOf } from "./opening";
7
8
  import { useSize } from "./useSize";
8
9
 
9
- const BUTTON = "rounded-md px-2.5 py-1 text-[14px] text-control hover:bg-overlay-line";
10
+ const BUTTON = "rounded-md px-2.5 py-1 text-[14px] text-text hover:bg-node";
10
11
 
11
12
  /**
12
13
  * A selected box's actions while the panel would cover the canvas (owner review, 2026-10-25). In a narrow window, VS
13
14
  * Code's panel above all, the panel over the whole canvas hid the box a double click was aimed at, and every editor
14
- * follow covered the Map. So a click there only selects, and the box offers what the panel would have: Open (a folder),
15
- * the page (a doorway) and Details, at screen size whatever the zoom. narrow.ts's actionsPlace puts them beside the box
16
- * and keeps them inside the canvas (React Flow's NodeToolbar can't be kept in: a box hanging off an edge took its
15
+ * follow covered the Map. So a click there only selects, and the box offers what the panel would have: Open (a folder,
16
+ * or inside VS Code's panel a file, which opens in the editor), the page (a doorway) and Details, at screen size whatever
17
+ * the zoom. Each opens the box as a double-click on it would (opening.ts). narrow.ts's actionsPlace puts them beside the
18
+ * box and keeps them inside the canvas (React Flow's NodeToolbar can't be kept in: a box hanging off an edge took its
17
19
  * toolbar past it). Details opens the panel over the canvas; its × comes back to the Map with the box still selected.
18
20
  * A component of its own, so following the view as the canvas pans re-renders only this.
19
21
  */
20
- export default function BoxActions({ box, position, onOpen, onTurnPage, onDetails }: {
22
+ export default function BoxActions({ box, position, onOpen, onTurnPage, onDetails, onOpenFile }: {
21
23
  box: MapNode;
22
24
  /** The box's top-left corner in the level's own coordinates, its layout position. */
23
25
  position: { x: number; y: number };
24
26
  onOpen: (folder: string) => void;
25
27
  onTurnPage: (page: number) => void;
26
28
  onDetails: (path: string) => void;
29
+ /** Inside VS Code's panel only: opens a file in the editor. */
30
+ onOpenFile?: (path: string) => void;
27
31
  }){
28
32
  const [sizeRef, size] = useSize<HTMLDivElement>();
29
33
  // the transform is [x, y, zoom]: the box on screen, in the canvas's own px
@@ -33,20 +37,24 @@ export default function BoxActions({ box, position, onOpen, onTurnPage, onDetail
33
37
  const onScreen = { left: position.x * zoom + x, top: position.y * zoom + y, width: BOX_WIDTH * zoom, height: BOX_HEIGHT * zoom };
34
38
  // until it's measured it's laid out unseen, so its first frame is already in place
35
39
  const place = actionsPlace(onScreen, size ?? { width: 0, height: 0 }, canvasWidth, canvasHeight);
36
- const page = box.kind === "portal" ? box.page : undefined;
40
+ const opening = openingOf(box, onOpenFile !== undefined);
37
41
  return (
38
42
  <div
39
43
  ref={sizeRef}
40
44
  data-box-actions={box.path}
45
+ data-keep-clear
41
46
  style={{ left: place.left, top: place.top, visibility: size === null ? "hidden" : undefined }}
42
- className="absolute z-[6] flex items-center gap-1 rounded-lg bg-overlay p-1"
47
+ className="absolute z-[6] flex items-center gap-1 rounded-lg bg-panel p-1"
43
48
  >
44
- {box.kind === "folder" && (
45
- <button type="button" onClick={() => onOpen(box.path)} title="Open this folder (or double-click it)" className={BUTTON}>Open</button>
49
+ {opening?.type === "folder" && (
50
+ <button type="button" onClick={() => onOpen(opening.path)} title="Open this folder (or double-click it)" className={BUTTON}>Open</button>
46
51
  )}
47
- {page !== undefined && (
48
- <button type="button" onClick={() => onTurnPage(page)} title={`Go to page ${page + 1} (or double-click the doorway)`} className={BUTTON}>
49
- Go to page {page + 1}
52
+ {opening?.type === "editor" && (
53
+ <button type="button" onClick={() => onOpenFile?.(opening.path)} title="Open in VS Code (or double-click it)" className={BUTTON}>Open</button>
54
+ )}
55
+ {opening?.type === "page" && (
56
+ <button type="button" onClick={() => onTurnPage(opening.page)} title={`Go to page ${opening.page + 1} (or double-click the doorway)`} className={BUTTON}>
57
+ Go to page {opening.page + 1}
50
58
  </button>
51
59
  )}
52
60
  <button type="button" onClick={() => onDetails(box.path)} title="Show its details over the Map" className={BUTTON}>Details</button>