gsd-pi 2.64.0-dev.9c14bd0 → 2.64.0-dev.cbb05a1

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 (223) hide show
  1. package/dist/headless.js +3 -1
  2. package/dist/resources/extensions/bg-shell/bg-shell-lifecycle.js +22 -7
  3. package/dist/resources/extensions/bg-shell/process-manager.js +6 -1
  4. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +24 -13
  5. package/dist/resources/extensions/gsd/bootstrap/notify-interceptor.js +28 -0
  6. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +8 -0
  7. package/dist/resources/extensions/gsd/bootstrap/register-shortcuts.js +16 -0
  8. package/dist/resources/extensions/gsd/bootstrap/system-context.js +20 -0
  9. package/dist/resources/extensions/gsd/commands/catalog.js +7 -1
  10. package/dist/resources/extensions/gsd/commands/handlers/core.js +1 -0
  11. package/dist/resources/extensions/gsd/commands/handlers/notifications-handler.js +104 -0
  12. package/dist/resources/extensions/gsd/commands/handlers/ops.js +5 -0
  13. package/dist/resources/extensions/gsd/notification-overlay.js +228 -0
  14. package/dist/resources/extensions/gsd/notification-store.js +273 -0
  15. package/dist/resources/extensions/gsd/notification-widget.js +56 -0
  16. package/dist/resources/extensions/gsd/workflow-logger.js +8 -0
  17. package/dist/web/standalone/.next/BUILD_ID +1 -1
  18. package/dist/web/standalone/.next/app-path-routes-manifest.json +22 -21
  19. package/dist/web/standalone/.next/build-manifest.json +2 -2
  20. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  21. package/dist/web/standalone/.next/routes-manifest.json +6 -0
  22. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  23. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  24. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  25. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  26. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  27. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  28. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  29. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  30. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  31. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  32. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  33. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  34. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  35. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  36. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  37. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  38. package/dist/web/standalone/.next/server/app/api/notifications/route.js +3 -0
  39. package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -0
  40. package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -0
  41. package/dist/web/standalone/.next/server/app/index.html +1 -1
  42. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  43. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  44. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  45. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  46. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  47. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  48. package/dist/web/standalone/.next/server/app-paths-manifest.json +22 -21
  49. package/dist/web/standalone/.next/server/functions-config-manifest.json +1 -0
  50. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  51. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  52. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  53. package/dist/web/standalone/.next/static/6VY044iEgB5gScn5oawg3/_buildManifest.js +1 -0
  54. package/dist/web/standalone/.next/static/chunks/app/_global-error/page-8805a20e15762c3c.js +1 -0
  55. package/dist/web/standalone/.next/static/chunks/app/api/boot/route-8805a20e15762c3c.js +1 -0
  56. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/input/route-8805a20e15762c3c.js +1 -0
  57. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/resize/route-8805a20e15762c3c.js +1 -0
  58. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/stream/route-8805a20e15762c3c.js +1 -0
  59. package/dist/web/standalone/.next/static/chunks/app/api/browse-directories/route-8805a20e15762c3c.js +1 -0
  60. package/dist/web/standalone/.next/static/chunks/app/api/captures/route-8805a20e15762c3c.js +1 -0
  61. package/dist/web/standalone/.next/static/chunks/app/api/cleanup/route-8805a20e15762c3c.js +1 -0
  62. package/dist/web/standalone/.next/static/chunks/app/api/dev-mode/route-8805a20e15762c3c.js +1 -0
  63. package/dist/web/standalone/.next/static/chunks/app/api/doctor/route-8805a20e15762c3c.js +1 -0
  64. package/dist/web/standalone/.next/static/chunks/app/api/experimental/route-8805a20e15762c3c.js +1 -0
  65. package/dist/web/standalone/.next/static/chunks/app/api/export-data/route-8805a20e15762c3c.js +1 -0
  66. package/dist/web/standalone/.next/static/chunks/app/api/files/route-8805a20e15762c3c.js +1 -0
  67. package/dist/web/standalone/.next/static/chunks/app/api/forensics/route-8805a20e15762c3c.js +1 -0
  68. package/dist/web/standalone/.next/static/chunks/app/api/git/route-8805a20e15762c3c.js +1 -0
  69. package/dist/web/standalone/.next/static/chunks/app/api/history/route-8805a20e15762c3c.js +1 -0
  70. package/dist/web/standalone/.next/static/chunks/app/api/hooks/route-8805a20e15762c3c.js +1 -0
  71. package/dist/web/standalone/.next/static/chunks/app/api/inspect/route-8805a20e15762c3c.js +1 -0
  72. package/dist/web/standalone/.next/static/chunks/app/api/knowledge/route-8805a20e15762c3c.js +1 -0
  73. package/dist/web/standalone/.next/static/chunks/app/api/live-state/route-8805a20e15762c3c.js +1 -0
  74. package/dist/web/standalone/.next/static/chunks/app/api/notifications/route-8805a20e15762c3c.js +1 -0
  75. package/dist/web/standalone/.next/static/chunks/app/api/onboarding/route-8805a20e15762c3c.js +1 -0
  76. package/dist/web/standalone/.next/static/chunks/app/api/preferences/route-8805a20e15762c3c.js +1 -0
  77. package/dist/web/standalone/.next/static/chunks/app/api/projects/route-8805a20e15762c3c.js +1 -0
  78. package/dist/web/standalone/.next/static/chunks/app/api/recovery/route-8805a20e15762c3c.js +1 -0
  79. package/dist/web/standalone/.next/static/chunks/app/api/remote-questions/route-8805a20e15762c3c.js +1 -0
  80. package/dist/web/standalone/.next/static/chunks/app/api/session/browser/route-8805a20e15762c3c.js +1 -0
  81. package/dist/web/standalone/.next/static/chunks/app/api/session/command/route-8805a20e15762c3c.js +1 -0
  82. package/dist/web/standalone/.next/static/chunks/app/api/session/events/route-8805a20e15762c3c.js +1 -0
  83. package/dist/web/standalone/.next/static/chunks/app/api/session/manage/route-8805a20e15762c3c.js +1 -0
  84. package/dist/web/standalone/.next/static/chunks/app/api/settings-data/route-8805a20e15762c3c.js +1 -0
  85. package/dist/web/standalone/.next/static/chunks/app/api/shutdown/route-8805a20e15762c3c.js +1 -0
  86. package/dist/web/standalone/.next/static/chunks/app/api/skill-health/route-8805a20e15762c3c.js +1 -0
  87. package/dist/web/standalone/.next/static/chunks/app/api/steer/route-8805a20e15762c3c.js +1 -0
  88. package/dist/web/standalone/.next/static/chunks/app/api/switch-root/route-8805a20e15762c3c.js +1 -0
  89. package/dist/web/standalone/.next/static/chunks/app/api/terminal/input/route-8805a20e15762c3c.js +1 -0
  90. package/dist/web/standalone/.next/static/chunks/app/api/terminal/resize/route-8805a20e15762c3c.js +1 -0
  91. package/dist/web/standalone/.next/static/chunks/app/api/terminal/sessions/route-8805a20e15762c3c.js +1 -0
  92. package/dist/web/standalone/.next/static/chunks/app/api/terminal/stream/route-8805a20e15762c3c.js +1 -0
  93. package/dist/web/standalone/.next/static/chunks/app/api/terminal/upload/route-8805a20e15762c3c.js +1 -0
  94. package/dist/web/standalone/.next/static/chunks/app/api/undo/route-8805a20e15762c3c.js +1 -0
  95. package/dist/web/standalone/.next/static/chunks/app/api/update/route-8805a20e15762c3c.js +1 -0
  96. package/dist/web/standalone/.next/static/chunks/app/api/visualizer/route-8805a20e15762c3c.js +1 -0
  97. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-8805a20e15762c3c.js +1 -0
  98. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-8805a20e15762c3c.js +1 -0
  99. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-8805a20e15762c3c.js +1 -0
  100. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-8805a20e15762c3c.js +1 -0
  101. package/package.json +1 -1
  102. package/packages/pi-agent-core/dist/agent-loop.js +26 -9
  103. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  104. package/packages/pi-agent-core/src/agent-loop.test.ts +100 -4
  105. package/packages/pi-agent-core/src/agent-loop.ts +43 -12
  106. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.d.ts +2 -0
  107. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.d.ts.map +1 -0
  108. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js +38 -0
  109. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js.map +1 -0
  110. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  111. package/packages/pi-coding-agent/dist/core/agent-session.js +11 -0
  112. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  113. package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.d.ts +2 -0
  114. package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.d.ts.map +1 -0
  115. package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.js +24 -0
  116. package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.js.map +1 -0
  117. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
  118. package/packages/pi-coding-agent/dist/core/resource-loader.js +4 -1
  119. package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
  120. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +1 -0
  121. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  122. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +8 -0
  123. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  124. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +6 -0
  125. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  126. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +36 -0
  127. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  128. package/packages/pi-coding-agent/src/core/agent-session-tool-refresh.test.ts +64 -0
  129. package/packages/pi-coding-agent/src/core/agent-session.ts +10 -0
  130. package/packages/pi-coding-agent/src/core/resource-loader-cache-reset.test.ts +42 -0
  131. package/packages/pi-coding-agent/src/core/resource-loader.ts +5 -1
  132. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +9 -0
  133. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +33 -0
  134. package/packages/pi-tui/dist/__tests__/overlay-layout.test.d.ts +2 -0
  135. package/packages/pi-tui/dist/__tests__/overlay-layout.test.d.ts.map +1 -0
  136. package/packages/pi-tui/dist/__tests__/overlay-layout.test.js +52 -0
  137. package/packages/pi-tui/dist/__tests__/overlay-layout.test.js.map +1 -0
  138. package/packages/pi-tui/dist/components/loader.d.ts +4 -2
  139. package/packages/pi-tui/dist/components/loader.d.ts.map +1 -1
  140. package/packages/pi-tui/dist/components/loader.js +27 -9
  141. package/packages/pi-tui/dist/components/loader.js.map +1 -1
  142. package/packages/pi-tui/dist/components/text.d.ts.map +1 -1
  143. package/packages/pi-tui/dist/components/text.js +2 -0
  144. package/packages/pi-tui/dist/components/text.js.map +1 -1
  145. package/packages/pi-tui/dist/overlay-layout.d.ts.map +1 -1
  146. package/packages/pi-tui/dist/overlay-layout.js +11 -1
  147. package/packages/pi-tui/dist/overlay-layout.js.map +1 -1
  148. package/packages/pi-tui/dist/tui.d.ts +4 -0
  149. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  150. package/packages/pi-tui/dist/tui.js +35 -0
  151. package/packages/pi-tui/dist/tui.js.map +1 -1
  152. package/packages/pi-tui/src/__tests__/overlay-layout.test.ts +65 -0
  153. package/packages/pi-tui/src/components/loader.ts +27 -10
  154. package/packages/pi-tui/src/components/text.ts +1 -0
  155. package/packages/pi-tui/src/overlay-layout.ts +12 -1
  156. package/packages/pi-tui/src/tui.ts +34 -0
  157. package/src/resources/extensions/bg-shell/bg-shell-lifecycle.ts +19 -7
  158. package/src/resources/extensions/bg-shell/process-manager.ts +8 -2
  159. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +25 -13
  160. package/src/resources/extensions/gsd/bootstrap/notify-interceptor.ts +34 -0
  161. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +8 -0
  162. package/src/resources/extensions/gsd/bootstrap/register-shortcuts.ts +20 -0
  163. package/src/resources/extensions/gsd/bootstrap/system-context.ts +28 -0
  164. package/src/resources/extensions/gsd/commands/catalog.ts +7 -1
  165. package/src/resources/extensions/gsd/commands/handlers/core.ts +1 -0
  166. package/src/resources/extensions/gsd/commands/handlers/notifications-handler.ts +140 -0
  167. package/src/resources/extensions/gsd/commands/handlers/ops.ts +5 -0
  168. package/src/resources/extensions/gsd/notification-overlay.ts +272 -0
  169. package/src/resources/extensions/gsd/notification-store.ts +293 -0
  170. package/src/resources/extensions/gsd/notification-widget.ts +68 -0
  171. package/src/resources/extensions/gsd/tests/complete-slice-string-coercion.test.ts +36 -0
  172. package/src/resources/extensions/gsd/tests/discuss-tool-scope-leak.test.ts +76 -0
  173. package/src/resources/extensions/gsd/tests/notification-store.test.ts +282 -0
  174. package/src/resources/extensions/gsd/tests/unstructured-continue-context-injection.test.ts +163 -0
  175. package/src/resources/extensions/gsd/workflow-logger.ts +13 -0
  176. package/dist/web/standalone/.next/static/SoxM61WC_ia7R2gk4VMpJ/_buildManifest.js +0 -1
  177. package/dist/web/standalone/.next/static/chunks/app/_global-error/page-c4cc189e7b117ea2.js +0 -1
  178. package/dist/web/standalone/.next/static/chunks/app/api/boot/route-c4cc189e7b117ea2.js +0 -1
  179. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/input/route-c4cc189e7b117ea2.js +0 -1
  180. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/resize/route-c4cc189e7b117ea2.js +0 -1
  181. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/stream/route-c4cc189e7b117ea2.js +0 -1
  182. package/dist/web/standalone/.next/static/chunks/app/api/browse-directories/route-c4cc189e7b117ea2.js +0 -1
  183. package/dist/web/standalone/.next/static/chunks/app/api/captures/route-c4cc189e7b117ea2.js +0 -1
  184. package/dist/web/standalone/.next/static/chunks/app/api/cleanup/route-c4cc189e7b117ea2.js +0 -1
  185. package/dist/web/standalone/.next/static/chunks/app/api/dev-mode/route-c4cc189e7b117ea2.js +0 -1
  186. package/dist/web/standalone/.next/static/chunks/app/api/doctor/route-c4cc189e7b117ea2.js +0 -1
  187. package/dist/web/standalone/.next/static/chunks/app/api/experimental/route-c4cc189e7b117ea2.js +0 -1
  188. package/dist/web/standalone/.next/static/chunks/app/api/export-data/route-c4cc189e7b117ea2.js +0 -1
  189. package/dist/web/standalone/.next/static/chunks/app/api/files/route-c4cc189e7b117ea2.js +0 -1
  190. package/dist/web/standalone/.next/static/chunks/app/api/forensics/route-c4cc189e7b117ea2.js +0 -1
  191. package/dist/web/standalone/.next/static/chunks/app/api/git/route-c4cc189e7b117ea2.js +0 -1
  192. package/dist/web/standalone/.next/static/chunks/app/api/history/route-c4cc189e7b117ea2.js +0 -1
  193. package/dist/web/standalone/.next/static/chunks/app/api/hooks/route-c4cc189e7b117ea2.js +0 -1
  194. package/dist/web/standalone/.next/static/chunks/app/api/inspect/route-c4cc189e7b117ea2.js +0 -1
  195. package/dist/web/standalone/.next/static/chunks/app/api/knowledge/route-c4cc189e7b117ea2.js +0 -1
  196. package/dist/web/standalone/.next/static/chunks/app/api/live-state/route-c4cc189e7b117ea2.js +0 -1
  197. package/dist/web/standalone/.next/static/chunks/app/api/onboarding/route-c4cc189e7b117ea2.js +0 -1
  198. package/dist/web/standalone/.next/static/chunks/app/api/preferences/route-c4cc189e7b117ea2.js +0 -1
  199. package/dist/web/standalone/.next/static/chunks/app/api/projects/route-c4cc189e7b117ea2.js +0 -1
  200. package/dist/web/standalone/.next/static/chunks/app/api/recovery/route-c4cc189e7b117ea2.js +0 -1
  201. package/dist/web/standalone/.next/static/chunks/app/api/remote-questions/route-c4cc189e7b117ea2.js +0 -1
  202. package/dist/web/standalone/.next/static/chunks/app/api/session/browser/route-c4cc189e7b117ea2.js +0 -1
  203. package/dist/web/standalone/.next/static/chunks/app/api/session/command/route-c4cc189e7b117ea2.js +0 -1
  204. package/dist/web/standalone/.next/static/chunks/app/api/session/events/route-c4cc189e7b117ea2.js +0 -1
  205. package/dist/web/standalone/.next/static/chunks/app/api/session/manage/route-c4cc189e7b117ea2.js +0 -1
  206. package/dist/web/standalone/.next/static/chunks/app/api/settings-data/route-c4cc189e7b117ea2.js +0 -1
  207. package/dist/web/standalone/.next/static/chunks/app/api/shutdown/route-c4cc189e7b117ea2.js +0 -1
  208. package/dist/web/standalone/.next/static/chunks/app/api/skill-health/route-c4cc189e7b117ea2.js +0 -1
  209. package/dist/web/standalone/.next/static/chunks/app/api/steer/route-c4cc189e7b117ea2.js +0 -1
  210. package/dist/web/standalone/.next/static/chunks/app/api/switch-root/route-c4cc189e7b117ea2.js +0 -1
  211. package/dist/web/standalone/.next/static/chunks/app/api/terminal/input/route-c4cc189e7b117ea2.js +0 -1
  212. package/dist/web/standalone/.next/static/chunks/app/api/terminal/resize/route-c4cc189e7b117ea2.js +0 -1
  213. package/dist/web/standalone/.next/static/chunks/app/api/terminal/sessions/route-c4cc189e7b117ea2.js +0 -1
  214. package/dist/web/standalone/.next/static/chunks/app/api/terminal/stream/route-c4cc189e7b117ea2.js +0 -1
  215. package/dist/web/standalone/.next/static/chunks/app/api/terminal/upload/route-c4cc189e7b117ea2.js +0 -1
  216. package/dist/web/standalone/.next/static/chunks/app/api/undo/route-c4cc189e7b117ea2.js +0 -1
  217. package/dist/web/standalone/.next/static/chunks/app/api/update/route-c4cc189e7b117ea2.js +0 -1
  218. package/dist/web/standalone/.next/static/chunks/app/api/visualizer/route-c4cc189e7b117ea2.js +0 -1
  219. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-c4cc189e7b117ea2.js +0 -1
  220. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-c4cc189e7b117ea2.js +0 -1
  221. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-c4cc189e7b117ea2.js +0 -1
  222. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-c4cc189e7b117ea2.js +0 -1
  223. /package/dist/web/standalone/.next/static/{SoxM61WC_ia7R2gk4VMpJ → 6VY044iEgB5gScn5oawg3}/_ssgManifest.js +0 -0
@@ -0,0 +1,228 @@
1
+ // GSD Extension — Notification History Overlay
2
+ // Scrollable panel showing all persisted notifications with severity filtering.
3
+ // Toggled with Ctrl+Alt+N or opened from /gsd notifications.
4
+ import { truncateToWidth, visibleWidth, matchesKey, Key } from "@gsd/pi-tui";
5
+ import { readNotifications, markAllRead, clearNotifications, } from "./notification-store.js";
6
+ import { padRight, joinColumns } from "../shared/mod.js";
7
+ const FILTER_CYCLE = ["all", "error", "warning", "info"];
8
+ function severityIcon(severity) {
9
+ switch (severity) {
10
+ case "error": return "✗";
11
+ case "warning": return "⚠";
12
+ case "success": return "✓";
13
+ case "info":
14
+ default: return "●";
15
+ }
16
+ }
17
+ function formatTimestamp(ts) {
18
+ try {
19
+ const d = new Date(ts);
20
+ const now = Date.now();
21
+ const diffMs = now - d.getTime();
22
+ if (diffMs < 60_000)
23
+ return "just now";
24
+ if (diffMs < 3600_000)
25
+ return `${Math.floor(diffMs / 60_000)}m ago`;
26
+ if (diffMs < 86400_000)
27
+ return `${Math.floor(diffMs / 3600_000)}h ago`;
28
+ return `${Math.floor(diffMs / 86400_000)}d ago`;
29
+ }
30
+ catch {
31
+ return ts.slice(11, 19); // fallback: HH:MM:SS
32
+ }
33
+ }
34
+ export class GSDNotificationOverlay {
35
+ tui;
36
+ theme;
37
+ onClose;
38
+ cachedWidth;
39
+ cachedLines;
40
+ scrollOffset = 0;
41
+ filterIndex = 0;
42
+ entries = [];
43
+ refreshTimer;
44
+ disposed = false;
45
+ resizeHandler = null;
46
+ constructor(tui, theme, onClose) {
47
+ this.tui = tui;
48
+ this.theme = theme;
49
+ this.onClose = onClose;
50
+ // Mark all as read on open
51
+ markAllRead();
52
+ this.entries = readNotifications();
53
+ // Resize handler
54
+ this.resizeHandler = () => {
55
+ if (this.disposed)
56
+ return;
57
+ this.invalidate();
58
+ this.tui.requestRender();
59
+ };
60
+ process.stdout.on("resize", this.resizeHandler);
61
+ // Refresh every 3s for new notifications
62
+ this.refreshTimer = setInterval(() => {
63
+ if (this.disposed)
64
+ return;
65
+ const fresh = readNotifications();
66
+ if (fresh.length !== this.entries.length) {
67
+ this.entries = fresh;
68
+ markAllRead();
69
+ this.invalidate();
70
+ this.tui.requestRender();
71
+ }
72
+ }, 3000);
73
+ }
74
+ get filter() {
75
+ return FILTER_CYCLE[this.filterIndex];
76
+ }
77
+ get filteredEntries() {
78
+ if (this.filter === "all")
79
+ return this.entries;
80
+ return this.entries.filter((e) => e.severity === this.filter);
81
+ }
82
+ handleInput(data) {
83
+ if (matchesKey(data, Key.escape) || matchesKey(data, Key.ctrl("c")) || matchesKey(data, Key.ctrlAlt("n"))) {
84
+ this.dispose();
85
+ this.onClose();
86
+ return;
87
+ }
88
+ // Scroll
89
+ if (matchesKey(data, Key.down) || matchesKey(data, "j")) {
90
+ this.scrollOffset++;
91
+ this.invalidate();
92
+ this.tui.requestRender();
93
+ return;
94
+ }
95
+ if (matchesKey(data, Key.up) || matchesKey(data, "k")) {
96
+ this.scrollOffset = Math.max(0, this.scrollOffset - 1);
97
+ this.invalidate();
98
+ this.tui.requestRender();
99
+ return;
100
+ }
101
+ if (data === "g") {
102
+ this.scrollOffset = 0;
103
+ this.invalidate();
104
+ this.tui.requestRender();
105
+ return;
106
+ }
107
+ if (data === "G") {
108
+ this.scrollOffset = 999;
109
+ this.invalidate();
110
+ this.tui.requestRender();
111
+ return;
112
+ }
113
+ // Filter cycle
114
+ if (data === "f") {
115
+ this.filterIndex = (this.filterIndex + 1) % FILTER_CYCLE.length;
116
+ this.scrollOffset = 0;
117
+ this.invalidate();
118
+ this.tui.requestRender();
119
+ return;
120
+ }
121
+ // Clear all
122
+ if (data === "c") {
123
+ clearNotifications();
124
+ this.entries = [];
125
+ this.scrollOffset = 0;
126
+ this.invalidate();
127
+ this.tui.requestRender();
128
+ return;
129
+ }
130
+ }
131
+ render(width) {
132
+ if (this.cachedLines && this.cachedWidth === width) {
133
+ return this.cachedLines;
134
+ }
135
+ const content = this.buildContentLines(width);
136
+ const viewportHeight = Math.max(5, process.stdout.rows ? process.stdout.rows - 8 : 24);
137
+ const chromeHeight = 2; // top + bottom border
138
+ const visibleContentRows = Math.max(1, viewportHeight - chromeHeight);
139
+ const maxScroll = Math.max(0, content.length - visibleContentRows);
140
+ this.scrollOffset = Math.min(this.scrollOffset, maxScroll);
141
+ const visibleContent = content.slice(this.scrollOffset, this.scrollOffset + visibleContentRows);
142
+ // Pad to fill viewport so the overlay covers underlying content
143
+ while (visibleContent.length < visibleContentRows) {
144
+ visibleContent.push("");
145
+ }
146
+ const lines = this.wrapInBox(visibleContent, width);
147
+ this.cachedWidth = width;
148
+ this.cachedLines = lines;
149
+ return lines;
150
+ }
151
+ invalidate() {
152
+ this.cachedLines = undefined;
153
+ this.cachedWidth = undefined;
154
+ }
155
+ dispose() {
156
+ this.disposed = true;
157
+ clearInterval(this.refreshTimer);
158
+ if (this.resizeHandler) {
159
+ process.stdout.removeListener("resize", this.resizeHandler);
160
+ this.resizeHandler = null;
161
+ }
162
+ }
163
+ wrapInBox(inner, width) {
164
+ const th = this.theme;
165
+ const border = (s) => th.fg("borderAccent", s);
166
+ const innerWidth = width - 4;
167
+ const lines = [];
168
+ lines.push(border("╭" + "─".repeat(width - 2) + "╮"));
169
+ for (const line of inner) {
170
+ const truncated = truncateToWidth(line, innerWidth);
171
+ const padWidth = Math.max(0, innerWidth - visibleWidth(truncated));
172
+ lines.push(border("│") + " " + truncated + " ".repeat(padWidth) + " " + border("│"));
173
+ }
174
+ lines.push(border("╰" + "─".repeat(width - 2) + "╯"));
175
+ return lines;
176
+ }
177
+ buildContentLines(width) {
178
+ const th = this.theme;
179
+ const shellWidth = width - 4;
180
+ const contentWidth = Math.min(shellWidth, 128);
181
+ const sidePad = Math.max(0, Math.floor((shellWidth - contentWidth) / 2));
182
+ const leftMargin = " ".repeat(sidePad);
183
+ const lines = [];
184
+ const row = (content = "") => {
185
+ const truncated = truncateToWidth(content, contentWidth);
186
+ return leftMargin + padRight(truncated, contentWidth);
187
+ };
188
+ const blank = () => row("");
189
+ const hr = () => row(th.fg("dim", "─".repeat(contentWidth)));
190
+ // Header
191
+ const title = th.fg("accent", th.bold("Notifications"));
192
+ const filterLabel = this.filter === "all"
193
+ ? th.fg("dim", "all")
194
+ : th.fg(this.filter === "error" ? "error" : this.filter === "warning" ? "warning" : "dim", this.filter);
195
+ const count = `${this.filteredEntries.length} entries`;
196
+ lines.push(row(joinColumns(`${title} ${th.fg("dim", "filter:")} ${filterLabel}`, th.fg("dim", count), contentWidth)));
197
+ lines.push(hr());
198
+ // Controls
199
+ lines.push(row(th.fg("dim", "↑/↓ scroll f filter c clear Esc close")));
200
+ lines.push(blank());
201
+ // Entries
202
+ const filtered = this.filteredEntries;
203
+ if (filtered.length === 0) {
204
+ lines.push(blank());
205
+ lines.push(row(th.fg("dim", this.entries.length === 0
206
+ ? "No notifications yet."
207
+ : `No ${this.filter} notifications.`)));
208
+ lines.push(blank());
209
+ return lines;
210
+ }
211
+ for (const entry of filtered) {
212
+ const icon = severityIcon(entry.severity);
213
+ const coloredIcon = entry.severity === "error" ? th.fg("error", icon)
214
+ : entry.severity === "warning" ? th.fg("warning", icon)
215
+ : entry.severity === "success" ? th.fg("success", icon)
216
+ : th.fg("dim", icon);
217
+ const time = th.fg("dim", formatTimestamp(entry.ts));
218
+ const source = entry.source === "workflow-logger" ? th.fg("dim", " [engine]") : "";
219
+ // First line: icon + timestamp + source
220
+ const msgMaxWidth = contentWidth - 20;
221
+ const msg = entry.message.length > msgMaxWidth
222
+ ? entry.message.slice(0, msgMaxWidth - 1) + "…"
223
+ : entry.message;
224
+ lines.push(row(`${coloredIcon} ${time}${source} ${msg}`));
225
+ }
226
+ return lines;
227
+ }
228
+ }
@@ -0,0 +1,273 @@
1
+ // GSD Extension — Persistent Notification Store
2
+ // Captures all ctx.ui.notify() calls and workflow-logger warnings to
3
+ // .gsd/notifications.jsonl so they survive context resets and session restarts.
4
+ // Rotates at MAX_ENTRIES to prevent unbounded growth.
5
+ import { appendFileSync, existsSync, mkdirSync, openSync, closeSync, readFileSync, renameSync, unlinkSync, writeFileSync } from "node:fs";
6
+ import { join } from "node:path";
7
+ import { randomUUID } from "node:crypto";
8
+ // ─── Constants ──────────────────────────────────────────────────────────
9
+ const MAX_ENTRIES = 500;
10
+ const FILENAME = "notifications.jsonl";
11
+ const LOCKFILE = "notifications.lock";
12
+ // ─── Module State ───────────────────────────────────────────────────────
13
+ let _basePath = null;
14
+ let _lineCount = 0; // Hint for rotation — not authoritative for public API
15
+ let _suppressCount = 0;
16
+ // ─── Public API ─────────────────────────────────────────────────────────
17
+ /**
18
+ * Initialize the notification store. Call once at session start with the
19
+ * project root. Seeds in-memory counters from the existing file on disk.
20
+ */
21
+ export function initNotificationStore(basePath) {
22
+ _basePath = basePath;
23
+ // Seed line count hint for rotation — public counters read from disk
24
+ _lineCount = _readEntriesFromDisk(basePath).length;
25
+ }
26
+ /**
27
+ * Append a notification entry to the store. Synchronous — safe to call
28
+ * from the notify() shim which is declared void (not async).
29
+ */
30
+ export function appendNotification(message, severity, source = "notify") {
31
+ if (!_basePath)
32
+ return;
33
+ if (_suppressCount > 0)
34
+ return;
35
+ const entry = {
36
+ id: randomUUID(),
37
+ ts: new Date().toISOString(),
38
+ severity,
39
+ message: message.length > 500 ? message.slice(0, 500) + "…" : message,
40
+ source,
41
+ read: false,
42
+ };
43
+ try {
44
+ const dir = join(_basePath, ".gsd");
45
+ mkdirSync(dir, { recursive: true });
46
+ appendFileSync(join(dir, FILENAME), JSON.stringify(entry) + "\n", "utf-8");
47
+ _lineCount++;
48
+ // Rotate if hint suggests we're over limit
49
+ if (_lineCount > MAX_ENTRIES) {
50
+ _rotate();
51
+ }
52
+ }
53
+ catch {
54
+ // Non-fatal — never let persistence break the caller
55
+ }
56
+ }
57
+ /**
58
+ * Read all notification entries from disk. Returns newest-first.
59
+ */
60
+ export function readNotifications(basePath) {
61
+ const bp = basePath ?? _basePath;
62
+ if (!bp)
63
+ return [];
64
+ return _readEntriesFromDisk(bp).reverse();
65
+ }
66
+ /**
67
+ * Mark all notifications as read. Atomic rewrite via temp-file + rename.
68
+ * Resyncs in-memory counters from disk after mutation.
69
+ */
70
+ export function markAllRead(basePath) {
71
+ const bp = basePath ?? _basePath;
72
+ if (!bp)
73
+ return;
74
+ const entries = _readEntriesFromDisk(bp);
75
+ if (entries.length === 0)
76
+ return;
77
+ const hasUnread = entries.some((e) => !e.read);
78
+ if (!hasUnread)
79
+ return;
80
+ try {
81
+ _withLock(bp, () => {
82
+ // Re-read inside lock to get freshest state
83
+ const fresh = _readEntriesFromDisk(bp);
84
+ if (fresh.length === 0 || !fresh.some((e) => !e.read))
85
+ return;
86
+ const lines = fresh.map((e) => JSON.stringify({ ...e, read: true }));
87
+ _atomicWrite(bp, lines.join("\n") + "\n");
88
+ });
89
+ }
90
+ catch {
91
+ // Non-fatal
92
+ }
93
+ }
94
+ /**
95
+ * Clear all notifications. Atomic write of empty content under lock.
96
+ */
97
+ export function clearNotifications(basePath) {
98
+ const bp = basePath ?? _basePath;
99
+ if (!bp)
100
+ return;
101
+ try {
102
+ _withLock(bp, () => {
103
+ _atomicWrite(bp, "");
104
+ });
105
+ }
106
+ catch {
107
+ // Non-fatal
108
+ }
109
+ }
110
+ /**
111
+ * Get the current unread count. Reads from disk to stay accurate across
112
+ * processes (web subprocess can clear/modify the file independently).
113
+ */
114
+ export function getUnreadCount() {
115
+ if (!_basePath)
116
+ return 0;
117
+ try {
118
+ const entries = _readEntriesFromDisk(_basePath);
119
+ return entries.filter((e) => !e.read).length;
120
+ }
121
+ catch {
122
+ return 0;
123
+ }
124
+ }
125
+ /**
126
+ * Get the total notification count. Reads from disk for cross-process accuracy.
127
+ */
128
+ export function getLineCount() {
129
+ if (!_basePath)
130
+ return 0;
131
+ try {
132
+ return _readEntriesFromDisk(_basePath).length;
133
+ }
134
+ catch {
135
+ return 0;
136
+ }
137
+ }
138
+ /**
139
+ * Temporarily suppress persistence. Use around ctx.ui.notify calls that
140
+ * should NOT be persisted (e.g., confirmation toasts after clear).
141
+ * Calls are ref-counted — nest safely.
142
+ */
143
+ export function suppressPersistence() {
144
+ _suppressCount++;
145
+ }
146
+ export function unsuppressPersistence() {
147
+ _suppressCount = Math.max(0, _suppressCount - 1);
148
+ }
149
+ // ─── Test Helpers ───────────────────────────────────────────────────────
150
+ /**
151
+ * Reset module state. Only for use in tests.
152
+ */
153
+ export function _resetNotificationStore() {
154
+ _basePath = null;
155
+ _lineCount = 0;
156
+ _suppressCount = 0;
157
+ }
158
+ // ─── Internal ───────────────────────────────────────────────────────────
159
+ function _readEntriesFromDisk(basePath) {
160
+ const filePath = join(basePath, ".gsd", FILENAME);
161
+ if (!existsSync(filePath))
162
+ return [];
163
+ try {
164
+ const content = readFileSync(filePath, "utf-8");
165
+ return content
166
+ .split("\n")
167
+ .filter((l) => l.length > 0)
168
+ .map((l) => {
169
+ try {
170
+ return JSON.parse(l);
171
+ }
172
+ catch {
173
+ return null;
174
+ }
175
+ })
176
+ .filter((e) => e !== null);
177
+ }
178
+ catch {
179
+ return [];
180
+ }
181
+ }
182
+ function _rotate() {
183
+ if (!_basePath)
184
+ return;
185
+ try {
186
+ _withLock(_basePath, () => {
187
+ // Re-read inside lock to get freshest state
188
+ const entries = _readEntriesFromDisk(_basePath);
189
+ if (entries.length <= MAX_ENTRIES)
190
+ return;
191
+ const trimmed = entries.slice(entries.length - MAX_ENTRIES);
192
+ const lines = trimmed.map((e) => JSON.stringify(e));
193
+ _atomicWrite(_basePath, lines.join("\n") + "\n");
194
+ });
195
+ }
196
+ catch {
197
+ // Non-fatal
198
+ }
199
+ }
200
+ /**
201
+ * Atomic file rewrite via temp-file + rename. Prevents partial reads
202
+ * by other processes (web API subprocess, parallel workers).
203
+ * Must be called inside _withLock for cross-process safety.
204
+ */
205
+ function _atomicWrite(basePath, content) {
206
+ const dir = join(basePath, ".gsd");
207
+ mkdirSync(dir, { recursive: true });
208
+ const target = join(dir, FILENAME);
209
+ const tmp = target + ".tmp." + process.pid;
210
+ writeFileSync(tmp, content, "utf-8");
211
+ renameSync(tmp, target);
212
+ }
213
+ /**
214
+ * Acquire an exclusive lockfile for rewrite operations.
215
+ * Uses O_CREAT|O_EXCL for atomic creation — if the file exists, another
216
+ * process holds the lock. Retries briefly, then proceeds anyway (best-effort)
217
+ * to avoid deadlocking the UI on a stale lock.
218
+ */
219
+ function _withLock(basePath, fn) {
220
+ const lockPath = join(basePath, ".gsd", LOCKFILE);
221
+ let fd = null;
222
+ const maxAttempts = 5;
223
+ const retryMs = 20;
224
+ for (let i = 0; i < maxAttempts; i++) {
225
+ try {
226
+ mkdirSync(join(basePath, ".gsd"), { recursive: true });
227
+ fd = openSync(lockPath, "wx");
228
+ break;
229
+ }
230
+ catch (err) {
231
+ if (err?.code === "EEXIST") {
232
+ // Check if lock is stale (older than 5s)
233
+ try {
234
+ const stat = readFileSync(lockPath, "utf-8");
235
+ const lockTime = parseInt(stat, 10);
236
+ if (Date.now() - lockTime > 5000) {
237
+ try {
238
+ unlinkSync(lockPath);
239
+ }
240
+ catch { /* race ok */ }
241
+ continue;
242
+ }
243
+ }
244
+ catch { /* can't read lock, retry */ }
245
+ // Wait and retry
246
+ const start = Date.now();
247
+ while (Date.now() - start < retryMs) { /* spin */ }
248
+ continue;
249
+ }
250
+ // Other error — proceed without lock
251
+ break;
252
+ }
253
+ }
254
+ // Only run the mutation if we actually own the lock
255
+ const ownsLock = fd !== null;
256
+ try {
257
+ if (ownsLock && fd !== null) {
258
+ // Write our PID timestamp into the lock for stale detection
259
+ writeFileSync(lockPath, String(Date.now()), "utf-8");
260
+ closeSync(fd);
261
+ }
262
+ return fn();
263
+ }
264
+ finally {
265
+ // Only delete the lock if we created it — never remove another process's lock
266
+ if (ownsLock) {
267
+ try {
268
+ unlinkSync(lockPath);
269
+ }
270
+ catch { /* best-effort cleanup */ }
271
+ }
272
+ }
273
+ }
@@ -0,0 +1,56 @@
1
+ // GSD Extension — Notification Widget
2
+ // Always-on ambient widget rendered belowEditor showing unread count and
3
+ // the most recent notification message. Refreshes every 5 seconds.
4
+ // Widget key: "gsd-notifications", placement: "belowEditor"
5
+ import { getUnreadCount, readNotifications } from "./notification-store.js";
6
+ // ─── Pure rendering ──���────────────────────────���─────────────────────────
7
+ export function buildNotificationWidgetLines() {
8
+ const unread = getUnreadCount();
9
+ if (unread === 0)
10
+ return [];
11
+ const entries = readNotifications();
12
+ const latest = entries[0]; // newest-first
13
+ if (!latest)
14
+ return [];
15
+ const icon = latest.severity === "error" ? "✗" : latest.severity === "warning" ? "⚠" : "●";
16
+ const badge = `${unread} unread`;
17
+ const msgMax = 80;
18
+ const truncated = latest.message.length > msgMax
19
+ ? latest.message.slice(0, msgMax - 1) + "…"
20
+ : latest.message;
21
+ return [` ${icon} [${badge}] ${truncated} (Ctrl+Alt+N to view)`];
22
+ }
23
+ // ─── Widget init ────────────────────────────────────────────────────────
24
+ const REFRESH_INTERVAL_MS = 5_000;
25
+ /**
26
+ * Initialize the always-on notification widget (belowEditor).
27
+ * Call once from session_start after the notification store is initialized.
28
+ */
29
+ export function initNotificationWidget(ctx) {
30
+ if (!ctx.hasUI)
31
+ return;
32
+ // String-array fallback for RPC mode
33
+ ctx.ui.setWidget("gsd-notifications", buildNotificationWidgetLines(), { placement: "belowEditor" });
34
+ // Factory-based widget for TUI mode
35
+ ctx.ui.setWidget("gsd-notifications", (_tui, _theme) => {
36
+ let cachedLines;
37
+ const refresh = () => {
38
+ cachedLines = undefined;
39
+ _tui.requestRender();
40
+ };
41
+ const refreshTimer = setInterval(refresh, REFRESH_INTERVAL_MS);
42
+ return {
43
+ render(_width) {
44
+ if (!cachedLines)
45
+ cachedLines = buildNotificationWidgetLines();
46
+ return cachedLines;
47
+ },
48
+ invalidate() {
49
+ cachedLines = undefined;
50
+ },
51
+ dispose() {
52
+ clearInterval(refreshTimer);
53
+ },
54
+ };
55
+ }, { placement: "belowEditor" });
56
+ }
@@ -17,6 +17,7 @@
17
17
  // Node process.
18
18
  import { appendFileSync, readFileSync, existsSync, mkdirSync } from "node:fs";
19
19
  import { join } from "node:path";
20
+ import { appendNotification } from "./notification-store.js";
20
21
  // ─── Buffer & Persistent Audit ──────────────────────────────────────────
21
22
  const MAX_BUFFER = 100;
22
23
  let _buffer = [];
@@ -179,6 +180,13 @@ function _push(severity, component, message, context) {
179
180
  const prefix = severity === "error" ? "ERROR" : "WARN";
180
181
  const ctxStr = context ? ` ${JSON.stringify(context)}` : "";
181
182
  process.stderr.write(`[gsd:${component}] ${prefix}: ${message}${ctxStr}\n`);
183
+ // Persist to notification store (both warnings and errors)
184
+ try {
185
+ appendNotification(`[${component}] ${message}`, severity === "error" ? "error" : "warning", "workflow-logger");
186
+ }
187
+ catch (notifErr) {
188
+ process.stderr.write(`[gsd:workflow-logger] notification-store append failed: ${notifErr.message}\n`);
189
+ }
182
190
  // Buffer for auto-loop to drain
183
191
  _buffer.push(entry);
184
192
  if (_buffer.length > MAX_BUFFER) {
@@ -1 +1 @@
1
- SoxM61WC_ia7R2gk4VMpJ
1
+ 6VY044iEgB5gScn5oawg3
@@ -1,46 +1,47 @@
1
1
  {
2
2
  "/_not-found/page": "/_not-found",
3
3
  "/_global-error/page": "/_global-error",
4
- "/api/bridge-terminal/input/route": "/api/bridge-terminal/input",
5
4
  "/api/boot/route": "/api/boot",
5
+ "/api/bridge-terminal/input/route": "/api/bridge-terminal/input",
6
6
  "/api/bridge-terminal/resize/route": "/api/bridge-terminal/resize",
7
7
  "/api/dev-mode/route": "/api/dev-mode",
8
8
  "/api/cleanup/route": "/api/cleanup",
9
+ "/api/bridge-terminal/stream/route": "/api/bridge-terminal/stream",
9
10
  "/api/doctor/route": "/api/doctor",
10
- "/api/export-data/route": "/api/export-data",
11
- "/api/browse-directories/route": "/api/browse-directories",
12
- "/api/captures/route": "/api/captures",
13
11
  "/api/forensics/route": "/api/forensics",
14
12
  "/api/git/route": "/api/git",
15
- "/api/hooks/route": "/api/hooks",
13
+ "/api/captures/route": "/api/captures",
16
14
  "/api/history/route": "/api/history",
17
- "/api/experimental/route": "/api/experimental",
18
- "/api/bridge-terminal/stream/route": "/api/bridge-terminal/stream",
19
- "/api/knowledge/route": "/api/knowledge",
15
+ "/api/hooks/route": "/api/hooks",
20
16
  "/api/inspect/route": "/api/inspect",
21
- "/api/preferences/route": "/api/preferences",
17
+ "/api/browse-directories/route": "/api/browse-directories",
18
+ "/api/knowledge/route": "/api/knowledge",
19
+ "/api/notifications/route": "/api/notifications",
20
+ "/api/live-state/route": "/api/live-state",
21
+ "/api/export-data/route": "/api/export-data",
22
+ "/api/experimental/route": "/api/experimental",
22
23
  "/api/recovery/route": "/api/recovery",
23
- "/api/onboarding/route": "/api/onboarding",
24
+ "/api/preferences/route": "/api/preferences",
24
25
  "/api/projects/route": "/api/projects",
25
- "/api/live-state/route": "/api/live-state",
26
26
  "/api/session/browser/route": "/api/session/browser",
27
- "/api/settings-data/route": "/api/settings-data",
27
+ "/api/onboarding/route": "/api/onboarding",
28
28
  "/api/session/command/route": "/api/session/command",
29
- "/api/session/manage/route": "/api/session/manage",
30
- "/api/session/events/route": "/api/session/events",
29
+ "/api/files/route": "/api/files",
31
30
  "/api/shutdown/route": "/api/shutdown",
31
+ "/api/settings-data/route": "/api/settings-data",
32
+ "/api/session/manage/route": "/api/session/manage",
32
33
  "/api/skill-health/route": "/api/skill-health",
34
+ "/api/session/events/route": "/api/session/events",
33
35
  "/api/steer/route": "/api/steer",
34
- "/api/terminal/input/route": "/api/terminal/input",
35
- "/api/terminal/resize/route": "/api/terminal/resize",
36
- "/api/files/route": "/api/files",
37
36
  "/api/switch-root/route": "/api/switch-root",
38
37
  "/api/terminal/sessions/route": "/api/terminal/sessions",
39
- "/api/terminal/upload/route": "/api/terminal/upload",
40
- "/api/terminal/stream/route": "/api/terminal/stream",
41
- "/api/visualizer/route": "/api/visualizer",
38
+ "/api/terminal/input/route": "/api/terminal/input",
39
+ "/api/terminal/resize/route": "/api/terminal/resize",
42
40
  "/api/undo/route": "/api/undo",
43
- "/api/remote-questions/route": "/api/remote-questions",
41
+ "/api/visualizer/route": "/api/visualizer",
42
+ "/api/terminal/stream/route": "/api/terminal/stream",
44
43
  "/api/update/route": "/api/update",
44
+ "/api/remote-questions/route": "/api/remote-questions",
45
+ "/api/terminal/upload/route": "/api/terminal/upload",
45
46
  "/page": "/"
46
47
  }
@@ -4,8 +4,8 @@
4
4
  ],
5
5
  "devFiles": [],
6
6
  "lowPriorityFiles": [
7
- "static/SoxM61WC_ia7R2gk4VMpJ/_buildManifest.js",
8
- "static/SoxM61WC_ia7R2gk4VMpJ/_ssgManifest.js"
7
+ "static/6VY044iEgB5gScn5oawg3/_buildManifest.js",
8
+ "static/6VY044iEgB5gScn5oawg3/_ssgManifest.js"
9
9
  ],
10
10
  "rootMainFiles": [
11
11
  "static/chunks/webpack-a1c1e452c6b32d04.js",
@@ -78,8 +78,8 @@
78
78
  "dynamicRoutes": {},
79
79
  "notFoundRoutes": [],
80
80
  "preview": {
81
- "previewModeId": "ee9af2f03bc28cb3403d45b01c1d6ccb",
82
- "previewModeSigningKey": "51aeb7c3d4ffdae159801b84a3838f9c0056202c24c796b44db7f0546c7ee43b",
83
- "previewModeEncryptionKey": "c86b89a986a6c080d0e25305f8a4c2ec0328cbae2c6a720ea6b989e7d371bc6f"
81
+ "previewModeId": "535ad28764c56c6ce9a7ceaea0176e2f",
82
+ "previewModeSigningKey": "3c9f365ce853d9fb7c07f5c3ed55af0c76bec4a091f194c899888ea5dc154928",
83
+ "previewModeEncryptionKey": "12ff786f663e70988a24094e5fafdd88f34b6ee19e7617f8b370ecb7d683d98e"
84
84
  }
85
85
  }