@agent-native/dispatch 0.6.1 → 0.8.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 (341) hide show
  1. package/README.md +38 -1
  2. package/dist/actions/apply-dream-proposal.d.ts +3 -0
  3. package/dist/actions/apply-dream-proposal.d.ts.map +1 -0
  4. package/dist/actions/apply-dream-proposal.js +11 -0
  5. package/dist/actions/apply-dream-proposal.js.map +1 -0
  6. package/dist/actions/create-dream-report.d.ts +3 -0
  7. package/dist/actions/create-dream-report.d.ts.map +1 -0
  8. package/dist/actions/create-dream-report.js +67 -0
  9. package/dist/actions/create-dream-report.js.map +1 -0
  10. package/dist/actions/create-pylon-ticket.d.ts +3 -0
  11. package/dist/actions/create-pylon-ticket.d.ts.map +1 -0
  12. package/dist/actions/create-pylon-ticket.js +94 -0
  13. package/dist/actions/create-pylon-ticket.js.map +1 -0
  14. package/dist/actions/create-vault-grant.js +1 -1
  15. package/dist/actions/create-vault-grant.js.map +1 -1
  16. package/dist/actions/create-vault-secret.d.ts.map +1 -1
  17. package/dist/actions/create-vault-secret.js +4 -3
  18. package/dist/actions/create-vault-secret.js.map +1 -1
  19. package/dist/actions/create-workspace-resource.js +3 -3
  20. package/dist/actions/create-workspace-resource.js.map +1 -1
  21. package/dist/actions/delete-workspace-resource.js +1 -1
  22. package/dist/actions/delete-workspace-resource.js.map +1 -1
  23. package/dist/actions/ensure-dream-job.d.ts +3 -0
  24. package/dist/actions/ensure-dream-job.d.ts.map +1 -0
  25. package/dist/actions/ensure-dream-job.js +73 -0
  26. package/dist/actions/ensure-dream-job.js.map +1 -0
  27. package/dist/actions/get-dream-settings.d.ts +3 -0
  28. package/dist/actions/get-dream-settings.d.ts.map +1 -0
  29. package/dist/actions/get-dream-settings.js +11 -0
  30. package/dist/actions/get-dream-settings.js.map +1 -0
  31. package/dist/actions/get-dream.d.ts +3 -0
  32. package/dist/actions/get-dream.d.ts.map +1 -0
  33. package/dist/actions/get-dream.js +13 -0
  34. package/dist/actions/get-dream.js.map +1 -0
  35. package/dist/actions/get-vault-access-settings.d.ts +3 -0
  36. package/dist/actions/get-vault-access-settings.d.ts.map +1 -0
  37. package/dist/actions/get-vault-access-settings.js +10 -0
  38. package/dist/actions/get-vault-access-settings.js.map +1 -0
  39. package/dist/actions/get-workspace-resource-effective-context.d.ts +3 -0
  40. package/dist/actions/get-workspace-resource-effective-context.d.ts.map +1 -0
  41. package/dist/actions/get-workspace-resource-effective-context.js +27 -0
  42. package/dist/actions/get-workspace-resource-effective-context.js.map +1 -0
  43. package/dist/actions/grant-vault-secrets-to-app.js +1 -1
  44. package/dist/actions/grant-vault-secrets-to-app.js.map +1 -1
  45. package/dist/actions/index.d.ts.map +1 -1
  46. package/dist/actions/index.js +38 -4
  47. package/dist/actions/index.js.map +1 -1
  48. package/dist/actions/list-dream-candidates.d.ts +3 -0
  49. package/dist/actions/list-dream-candidates.d.ts.map +1 -0
  50. package/dist/actions/list-dream-candidates.js +68 -0
  51. package/dist/actions/list-dream-candidates.js.map +1 -0
  52. package/dist/actions/list-dreams.d.ts +3 -0
  53. package/dist/actions/list-dreams.d.ts.map +1 -0
  54. package/dist/actions/list-dreams.js +17 -0
  55. package/dist/actions/list-dreams.js.map +1 -0
  56. package/dist/actions/list-integrations-catalog.js +1 -1
  57. package/dist/actions/list-integrations-catalog.js.map +1 -1
  58. package/dist/actions/list-vault-grants.js +1 -1
  59. package/dist/actions/list-vault-grants.js.map +1 -1
  60. package/dist/actions/list-workspace-apps.d.ts.map +1 -1
  61. package/dist/actions/list-workspace-apps.js +5 -1
  62. package/dist/actions/list-workspace-apps.js.map +1 -1
  63. package/dist/actions/list-workspace-resources-for-app.d.ts +3 -0
  64. package/dist/actions/list-workspace-resources-for-app.d.ts.map +1 -0
  65. package/dist/actions/list-workspace-resources-for-app.js +12 -0
  66. package/dist/actions/list-workspace-resources-for-app.js.map +1 -0
  67. package/dist/actions/list-workspace-resources.js +1 -1
  68. package/dist/actions/list-workspace-resources.js.map +1 -1
  69. package/dist/actions/navigate.d.ts +1 -0
  70. package/dist/actions/navigate.d.ts.map +1 -1
  71. package/dist/actions/navigate.js +2 -1
  72. package/dist/actions/navigate.js.map +1 -1
  73. package/dist/actions/preview-dream-proposal.d.ts +3 -0
  74. package/dist/actions/preview-dream-proposal.d.ts.map +1 -0
  75. package/dist/actions/preview-dream-proposal.js +13 -0
  76. package/dist/actions/preview-dream-proposal.js.map +1 -0
  77. package/dist/actions/preview-workspace-resource-change.d.ts +3 -0
  78. package/dist/actions/preview-workspace-resource-change.d.ts.map +1 -0
  79. package/dist/actions/preview-workspace-resource-change.js +24 -0
  80. package/dist/actions/preview-workspace-resource-change.js.map +1 -0
  81. package/dist/actions/reject-dream-proposal.d.ts +3 -0
  82. package/dist/actions/reject-dream-proposal.d.ts.map +1 -0
  83. package/dist/actions/reject-dream-proposal.js +12 -0
  84. package/dist/actions/reject-dream-proposal.js.map +1 -0
  85. package/dist/actions/restore-starter-workspace-resources.d.ts +3 -0
  86. package/dist/actions/restore-starter-workspace-resources.d.ts.map +1 -0
  87. package/dist/actions/restore-starter-workspace-resources.js +14 -0
  88. package/dist/actions/restore-starter-workspace-resources.js.map +1 -0
  89. package/dist/actions/send-code-agent-remote-command.d.ts +3 -0
  90. package/dist/actions/send-code-agent-remote-command.d.ts.map +1 -0
  91. package/dist/actions/send-code-agent-remote-command.js +53 -0
  92. package/dist/actions/send-code-agent-remote-command.js.map +1 -0
  93. package/dist/actions/set-dream-settings.d.ts +3 -0
  94. package/dist/actions/set-dream-settings.d.ts.map +1 -0
  95. package/dist/actions/set-dream-settings.js +41 -0
  96. package/dist/actions/set-dream-settings.js.map +1 -0
  97. package/dist/actions/set-vault-access-settings.d.ts +3 -0
  98. package/dist/actions/set-vault-access-settings.d.ts.map +1 -0
  99. package/dist/actions/set-vault-access-settings.js +13 -0
  100. package/dist/actions/set-vault-access-settings.js.map +1 -0
  101. package/dist/actions/start-workspace-app-creation.d.ts.map +1 -1
  102. package/dist/actions/start-workspace-app-creation.js +6 -0
  103. package/dist/actions/start-workspace-app-creation.js.map +1 -1
  104. package/dist/actions/sync-vault-to-app.js +1 -1
  105. package/dist/actions/sync-vault-to-app.js.map +1 -1
  106. package/dist/actions/update-workspace-app-metadata.d.ts +3 -0
  107. package/dist/actions/update-workspace-app-metadata.d.ts.map +1 -0
  108. package/dist/actions/update-workspace-app-metadata.js +30 -0
  109. package/dist/actions/update-workspace-app-metadata.js.map +1 -0
  110. package/dist/actions/update-workspace-resource.js +1 -1
  111. package/dist/actions/update-workspace-resource.js.map +1 -1
  112. package/dist/actions/view-screen.d.ts.map +1 -1
  113. package/dist/actions/view-screen.js +77 -4
  114. package/dist/actions/view-screen.js.map +1 -1
  115. package/dist/components/app-keys-popover.js +16 -5
  116. package/dist/components/app-keys-popover.js.map +1 -1
  117. package/dist/components/approval-value-block.d.ts +7 -0
  118. package/dist/components/approval-value-block.d.ts.map +1 -0
  119. package/dist/components/approval-value-block.js +22 -0
  120. package/dist/components/approval-value-block.js.map +1 -0
  121. package/dist/components/create-app-popover.d.ts.map +1 -1
  122. package/dist/components/create-app-popover.js +41 -16
  123. package/dist/components/create-app-popover.js.map +1 -1
  124. package/dist/components/dispatch-shell.d.ts +4 -4
  125. package/dist/components/dispatch-shell.d.ts.map +1 -1
  126. package/dist/components/dispatch-shell.js +6 -6
  127. package/dist/components/dispatch-shell.js.map +1 -1
  128. package/dist/components/layout/Layout.d.ts.map +1 -1
  129. package/dist/components/layout/Layout.js +18 -4
  130. package/dist/components/layout/Layout.js.map +1 -1
  131. package/dist/components/messaging-setup-panel.d.ts.map +1 -1
  132. package/dist/components/messaging-setup-panel.js +2 -2
  133. package/dist/components/messaging-setup-panel.js.map +1 -1
  134. package/dist/components/ui/chart.d.ts +1 -1
  135. package/dist/components/workspace-app-card.d.ts.map +1 -1
  136. package/dist/components/workspace-app-card.js +63 -3
  137. package/dist/components/workspace-app-card.js.map +1 -1
  138. package/dist/components/workspace-resource-effective-stack.d.ts +11 -0
  139. package/dist/components/workspace-resource-effective-stack.d.ts.map +1 -0
  140. package/dist/components/workspace-resource-effective-stack.js +59 -0
  141. package/dist/components/workspace-resource-effective-stack.js.map +1 -0
  142. package/dist/components/workspace-resource-impact-preview.d.ts +9 -0
  143. package/dist/components/workspace-resource-impact-preview.d.ts.map +1 -0
  144. package/dist/components/workspace-resource-impact-preview.js +39 -0
  145. package/dist/components/workspace-resource-impact-preview.js.map +1 -0
  146. package/dist/db/migrations.d.ts.map +1 -1
  147. package/dist/db/migrations.js +59 -0
  148. package/dist/db/migrations.js.map +1 -1
  149. package/dist/db/schema.d.ts +714 -0
  150. package/dist/db/schema.d.ts.map +1 -1
  151. package/dist/db/schema.js +44 -2
  152. package/dist/db/schema.js.map +1 -1
  153. package/dist/hooks/use-navigation-state.d.ts +3 -0
  154. package/dist/hooks/use-navigation-state.d.ts.map +1 -1
  155. package/dist/hooks/use-navigation-state.js +35 -8
  156. package/dist/hooks/use-navigation-state.js.map +1 -1
  157. package/dist/lib/catch-all-target.d.ts +2 -0
  158. package/dist/lib/catch-all-target.d.ts.map +1 -0
  159. package/dist/lib/catch-all-target.js +95 -0
  160. package/dist/lib/catch-all-target.js.map +1 -0
  161. package/dist/lib/utils.d.ts +2 -1
  162. package/dist/lib/utils.d.ts.map +1 -1
  163. package/dist/lib/utils.js +5 -1
  164. package/dist/lib/utils.js.map +1 -1
  165. package/dist/lib/workspace-apps.d.ts +9 -0
  166. package/dist/lib/workspace-apps.d.ts.map +1 -1
  167. package/dist/lib/workspace-apps.js.map +1 -1
  168. package/dist/routes/index.d.ts.map +1 -1
  169. package/dist/routes/index.js +1 -0
  170. package/dist/routes/index.js.map +1 -1
  171. package/dist/routes/pages/$appId.d.ts +2 -2
  172. package/dist/routes/pages/$appId.d.ts.map +1 -1
  173. package/dist/routes/pages/$appId.js +17 -8
  174. package/dist/routes/pages/$appId.js.map +1 -1
  175. package/dist/routes/pages/approval.d.ts.map +1 -1
  176. package/dist/routes/pages/approval.js +4 -1
  177. package/dist/routes/pages/approval.js.map +1 -1
  178. package/dist/routes/pages/approvals.js +1 -1
  179. package/dist/routes/pages/approvals.js.map +1 -1
  180. package/dist/routes/pages/dream-settings.d.ts +34 -0
  181. package/dist/routes/pages/dream-settings.d.ts.map +1 -0
  182. package/dist/routes/pages/dream-settings.js +68 -0
  183. package/dist/routes/pages/dream-settings.js.map +1 -0
  184. package/dist/routes/pages/dreams.d.ts +5 -0
  185. package/dist/routes/pages/dreams.d.ts.map +1 -0
  186. package/dist/routes/pages/dreams.js +435 -0
  187. package/dist/routes/pages/dreams.js.map +1 -0
  188. package/dist/routes/pages/integrations.d.ts.map +1 -1
  189. package/dist/routes/pages/integrations.js +20 -15
  190. package/dist/routes/pages/integrations.js.map +1 -1
  191. package/dist/routes/pages/new-app.js +1 -1
  192. package/dist/routes/pages/new-app.js.map +1 -1
  193. package/dist/routes/pages/overview.d.ts.map +1 -1
  194. package/dist/routes/pages/overview.js +5 -1
  195. package/dist/routes/pages/overview.js.map +1 -1
  196. package/dist/routes/pages/vault.d.ts.map +1 -1
  197. package/dist/routes/pages/vault.js +23 -5
  198. package/dist/routes/pages/vault.js.map +1 -1
  199. package/dist/routes/pages/workspace.d.ts.map +1 -1
  200. package/dist/routes/pages/workspace.js +187 -35
  201. package/dist/routes/pages/workspace.js.map +1 -1
  202. package/dist/server/lib/app-creation-store.d.ts +13 -0
  203. package/dist/server/lib/app-creation-store.d.ts.map +1 -1
  204. package/dist/server/lib/app-creation-store.js +298 -11
  205. package/dist/server/lib/app-creation-store.js.map +1 -1
  206. package/dist/server/lib/dispatch-integrations.d.ts +1 -1
  207. package/dist/server/lib/dispatch-integrations.d.ts.map +1 -1
  208. package/dist/server/lib/dispatch-integrations.js +9 -4
  209. package/dist/server/lib/dispatch-integrations.js.map +1 -1
  210. package/dist/server/lib/dispatch-remote-commands.d.ts +83 -0
  211. package/dist/server/lib/dispatch-remote-commands.d.ts.map +1 -0
  212. package/dist/server/lib/dispatch-remote-commands.js +256 -0
  213. package/dist/server/lib/dispatch-remote-commands.js.map +1 -0
  214. package/dist/server/lib/dispatch-store.d.ts +26 -0
  215. package/dist/server/lib/dispatch-store.d.ts.map +1 -1
  216. package/dist/server/lib/dispatch-store.js +17 -1
  217. package/dist/server/lib/dispatch-store.js.map +1 -1
  218. package/dist/server/lib/dreams-store.d.ts +398 -0
  219. package/dist/server/lib/dreams-store.d.ts.map +1 -0
  220. package/dist/server/lib/dreams-store.js +2330 -0
  221. package/dist/server/lib/dreams-store.js.map +1 -0
  222. package/dist/server/lib/env-config.d.ts.map +1 -1
  223. package/dist/server/lib/env-config.js +5 -0
  224. package/dist/server/lib/env-config.js.map +1 -1
  225. package/dist/server/lib/onboarding-steps.d.ts +12 -0
  226. package/dist/server/lib/onboarding-steps.d.ts.map +1 -0
  227. package/dist/server/lib/onboarding-steps.js +47 -0
  228. package/dist/server/lib/onboarding-steps.js.map +1 -0
  229. package/dist/server/lib/thread-debug-store.d.ts +2 -2
  230. package/dist/server/lib/vault-store.d.ts +55 -0
  231. package/dist/server/lib/vault-store.d.ts.map +1 -1
  232. package/dist/server/lib/vault-store.js +210 -41
  233. package/dist/server/lib/vault-store.js.map +1 -1
  234. package/dist/server/lib/workspace-resources-store.d.ts +181 -17
  235. package/dist/server/lib/workspace-resources-store.d.ts.map +1 -1
  236. package/dist/server/lib/workspace-resources-store.js +737 -108
  237. package/dist/server/lib/workspace-resources-store.js.map +1 -1
  238. package/dist/server/plugins/agent-chat.d.ts.map +1 -1
  239. package/dist/server/plugins/agent-chat.js +2 -1
  240. package/dist/server/plugins/agent-chat.js.map +1 -1
  241. package/dist/server/plugins/core-routes.d.ts.map +1 -1
  242. package/dist/server/plugins/core-routes.js +4 -0
  243. package/dist/server/plugins/core-routes.js.map +1 -1
  244. package/dist/server/plugins/integrations.js +2 -2
  245. package/dist/server/plugins/integrations.js.map +1 -1
  246. package/package.json +15 -11
  247. package/src/actions/apply-dream-proposal.ts +12 -0
  248. package/src/actions/create-dream-report.ts +76 -0
  249. package/src/actions/create-pylon-ticket.ts +109 -0
  250. package/src/actions/create-vault-grant.ts +1 -1
  251. package/src/actions/create-vault-secret.ts +4 -3
  252. package/src/actions/create-workspace-resource.ts +3 -3
  253. package/src/actions/delete-workspace-resource.ts +1 -1
  254. package/src/actions/ensure-dream-job.ts +76 -0
  255. package/src/actions/get-dream-settings.ts +12 -0
  256. package/src/actions/get-dream.ts +14 -0
  257. package/src/actions/get-vault-access-settings.ts +11 -0
  258. package/src/actions/get-workspace-resource-effective-context.ts +34 -0
  259. package/src/actions/grant-vault-secrets-to-app.ts +1 -1
  260. package/src/actions/index.spec.ts +26 -0
  261. package/src/actions/index.ts +39 -4
  262. package/src/actions/list-dream-candidates.ts +77 -0
  263. package/src/actions/list-dreams.ts +17 -0
  264. package/src/actions/list-integrations-catalog.ts +1 -1
  265. package/src/actions/list-vault-grants.ts +1 -1
  266. package/src/actions/list-workspace-apps.ts +5 -1
  267. package/src/actions/list-workspace-resources-for-app.ts +13 -0
  268. package/src/actions/list-workspace-resources.ts +1 -1
  269. package/src/actions/navigate.ts +2 -1
  270. package/src/actions/preview-dream-proposal.ts +14 -0
  271. package/src/actions/preview-workspace-resource-change.ts +25 -0
  272. package/src/actions/reject-dream-proposal.ts +12 -0
  273. package/src/actions/restore-starter-workspace-resources.ts +17 -0
  274. package/src/actions/send-code-agent-remote-command.ts +59 -0
  275. package/src/actions/set-dream-settings.spec.ts +81 -0
  276. package/src/actions/set-dream-settings.ts +44 -0
  277. package/src/actions/set-vault-access-settings.ts +16 -0
  278. package/src/actions/start-workspace-app-creation.ts +8 -0
  279. package/src/actions/sync-vault-to-app.ts +1 -1
  280. package/src/actions/update-workspace-app-metadata.ts +32 -0
  281. package/src/actions/update-workspace-resource.ts +1 -1
  282. package/src/actions/view-screen.ts +94 -3
  283. package/src/components/app-keys-popover.tsx +23 -7
  284. package/src/components/approval-value-block.spec.tsx +59 -0
  285. package/src/components/approval-value-block.tsx +33 -0
  286. package/src/components/create-app-popover.tsx +50 -16
  287. package/src/components/dispatch-shell.tsx +16 -15
  288. package/src/components/layout/Layout.tsx +19 -5
  289. package/src/components/messaging-setup-panel.tsx +54 -39
  290. package/src/components/workspace-app-card.tsx +268 -1
  291. package/src/components/workspace-resource-effective-stack.spec.tsx +125 -0
  292. package/src/components/workspace-resource-effective-stack.tsx +141 -0
  293. package/src/components/workspace-resource-impact-preview.spec.tsx +147 -0
  294. package/src/components/workspace-resource-impact-preview.tsx +116 -0
  295. package/src/db/migrations.ts +59 -0
  296. package/src/db/schema.ts +46 -2
  297. package/src/hooks/use-navigation-state.ts +34 -9
  298. package/src/lib/catch-all-target.spec.ts +218 -0
  299. package/src/lib/catch-all-target.ts +99 -0
  300. package/src/lib/utils.ts +6 -1
  301. package/src/lib/workspace-apps.ts +9 -0
  302. package/src/routes/index.ts +1 -0
  303. package/src/routes/pages/$appId.tsx +21 -8
  304. package/src/routes/pages/approval.tsx +14 -1
  305. package/src/routes/pages/approvals.tsx +1 -1
  306. package/src/routes/pages/dream-settings.spec.ts +130 -0
  307. package/src/routes/pages/dream-settings.ts +103 -0
  308. package/src/routes/pages/dreams.tsx +1828 -0
  309. package/src/routes/pages/integrations.tsx +57 -18
  310. package/src/routes/pages/new-app.tsx +1 -1
  311. package/src/routes/pages/overview.tsx +11 -3
  312. package/src/routes/pages/vault.tsx +76 -9
  313. package/src/routes/pages/workspace.tsx +577 -97
  314. package/src/server/lib/app-creation-store.spec.ts +61 -2
  315. package/src/server/lib/app-creation-store.ts +389 -13
  316. package/src/server/lib/dispatch-integrations.ts +10 -3
  317. package/src/server/lib/dispatch-remote-commands.spec.ts +167 -0
  318. package/src/server/lib/dispatch-remote-commands.ts +375 -0
  319. package/src/server/lib/dispatch-store.ts +37 -1
  320. package/src/server/lib/dreams-store.spec.ts +1492 -0
  321. package/src/server/lib/dreams-store.ts +3168 -0
  322. package/src/server/lib/env-config.ts +5 -0
  323. package/src/server/lib/onboarding-steps.ts +49 -0
  324. package/src/server/lib/vault-store.spec.ts +69 -0
  325. package/src/server/lib/vault-store.ts +266 -49
  326. package/src/server/lib/workspace-resource-approval-lifecycle.spec.ts +236 -0
  327. package/src/server/lib/workspace-resources-store.spec.ts +1106 -0
  328. package/src/server/lib/workspace-resources-store.ts +1001 -134
  329. package/src/server/plugins/agent-chat.ts +2 -1
  330. package/src/server/plugins/core-routes.ts +5 -0
  331. package/src/server/plugins/integrations.ts +2 -2
  332. package/dist/actions/sync-workspace-resources-to-all.d.ts +0 -3
  333. package/dist/actions/sync-workspace-resources-to-all.d.ts.map +0 -1
  334. package/dist/actions/sync-workspace-resources-to-all.js +0 -9
  335. package/dist/actions/sync-workspace-resources-to-all.js.map +0 -1
  336. package/dist/actions/sync-workspace-resources-to-app.d.ts +0 -3
  337. package/dist/actions/sync-workspace-resources-to-app.d.ts.map +0 -1
  338. package/dist/actions/sync-workspace-resources-to-app.js +0 -11
  339. package/dist/actions/sync-workspace-resources-to-app.js.map +0 -1
  340. package/src/actions/sync-workspace-resources-to-all.ts +0 -10
  341. package/src/actions/sync-workspace-resources-to-app.ts +0 -12
@@ -0,0 +1,147 @@
1
+ // @vitest-environment happy-dom
2
+ import React, { act } from "react";
3
+ import { createRoot, type Root } from "react-dom/client";
4
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
5
+ import {
6
+ ImpactPreview,
7
+ workspaceResourceMutationMessage,
8
+ } from "./workspace-resource-impact-preview";
9
+
10
+ const queryState = vi.hoisted(() => ({
11
+ result: { data: null as any, isLoading: false },
12
+ calls: [] as any[],
13
+ }));
14
+
15
+ vi.mock("@agent-native/core/client", () => ({
16
+ useActionQuery: (...args: any[]) => {
17
+ queryState.calls.push(args);
18
+ return queryState.result;
19
+ },
20
+ }));
21
+
22
+ describe("ImpactPreview", () => {
23
+ let container: HTMLDivElement;
24
+ let root: Root;
25
+
26
+ beforeEach(() => {
27
+ vi.stubGlobal("IS_REACT_ACT_ENVIRONMENT", true);
28
+ queryState.calls = [];
29
+ queryState.result = { data: null, isLoading: false };
30
+ container = document.createElement("div");
31
+ document.body.appendChild(container);
32
+ root = createRoot(container);
33
+ });
34
+
35
+ afterEach(() => {
36
+ act(() => root.unmount());
37
+ container.remove();
38
+ vi.unstubAllGlobals();
39
+ });
40
+
41
+ it("renders All-app approval impact and override details", () => {
42
+ queryState.result = {
43
+ isLoading: false,
44
+ data: {
45
+ affectsAllApps: true,
46
+ affectedApps: { count: 4 },
47
+ approval: { willRequestApproval: true },
48
+ overrides: {
49
+ count: 2,
50
+ items: [
51
+ {
52
+ scope: "shared",
53
+ owner: "__shared__",
54
+ label: "Organization/app override",
55
+ updatedAt: 1,
56
+ },
57
+ {
58
+ scope: "personal",
59
+ owner: "person@example.test",
60
+ label: "Personal override (person@example.test)",
61
+ updatedAt: 2,
62
+ },
63
+ ],
64
+ },
65
+ },
66
+ };
67
+
68
+ act(() => {
69
+ root.render(
70
+ <ImpactPreview
71
+ operation="update"
72
+ resourceId="resource_1"
73
+ scope="all"
74
+ />,
75
+ );
76
+ });
77
+
78
+ expect(queryState.calls[0]).toEqual([
79
+ "preview-workspace-resource-change",
80
+ {
81
+ operation: "update",
82
+ resourceId: "resource_1",
83
+ path: undefined,
84
+ scope: "all",
85
+ },
86
+ { enabled: true },
87
+ ]);
88
+ expect(container.textContent).toContain("All apps impact");
89
+ expect(container.textContent).toContain("Approval required");
90
+ expect(container.textContent).toContain("2 overrides");
91
+ expect(container.textContent).toContain(
92
+ "This change applies to every workspace app (4 discovered).",
93
+ );
94
+ expect(container.textContent).toContain(
95
+ "It will be queued for approval before it takes effect.",
96
+ );
97
+ expect(container.textContent).toContain("Organization/app override");
98
+ expect(container.textContent).toContain(
99
+ "Personal override (person@example.test)",
100
+ );
101
+ });
102
+
103
+ it("renders selected-only changes as immediate", () => {
104
+ queryState.result = {
105
+ isLoading: false,
106
+ data: {
107
+ affectsAllApps: false,
108
+ affectedApps: { count: null },
109
+ approval: { willRequestApproval: false },
110
+ overrides: { count: 0, items: [] },
111
+ },
112
+ };
113
+
114
+ act(() => {
115
+ root.render(
116
+ <ImpactPreview
117
+ operation="create"
118
+ path="context/private-launch.md"
119
+ scope="selected"
120
+ />,
121
+ );
122
+ });
123
+
124
+ expect(container.textContent).toContain("Selected only");
125
+ expect(container.textContent).toContain(
126
+ "This change only applies to explicitly granted apps.",
127
+ );
128
+ expect(container.textContent).toContain(
129
+ "It will take effect immediately when saved.",
130
+ );
131
+ });
132
+
133
+ it("uses approval-request mutation copy only for workspace resource approvals", () => {
134
+ expect(
135
+ workspaceResourceMutationMessage(
136
+ { status: "pending", changeType: "workspace-resource.update" },
137
+ "Resource updated",
138
+ ),
139
+ ).toBe("Approval requested");
140
+ expect(
141
+ workspaceResourceMutationMessage(
142
+ { status: "pending", changeType: "dream-proposal.apply" },
143
+ "Resource updated",
144
+ ),
145
+ ).toBe("Resource updated");
146
+ });
147
+ });
@@ -0,0 +1,116 @@
1
+ import { useActionQuery } from "@agent-native/core/client";
2
+ import { Badge } from "@/components/ui/badge";
3
+ import { Skeleton } from "@/components/ui/skeleton";
4
+ import { formatResourceTimestamp } from "./workspace-resource-effective-stack";
5
+
6
+ function isApprovalRequest(result: any): boolean {
7
+ return (
8
+ result?.status === "pending" &&
9
+ typeof result?.changeType === "string" &&
10
+ result.changeType.startsWith("workspace-resource.")
11
+ );
12
+ }
13
+
14
+ export function workspaceResourceMutationMessage(
15
+ result: any,
16
+ fallback: string,
17
+ ): string {
18
+ return isApprovalRequest(result) ? "Approval requested" : fallback;
19
+ }
20
+
21
+ export function ImpactPreview({
22
+ operation,
23
+ resourceId,
24
+ path,
25
+ scope,
26
+ enabled = true,
27
+ }: {
28
+ operation: "create" | "update" | "delete";
29
+ resourceId?: string;
30
+ path?: string;
31
+ scope?: "all" | "selected";
32
+ enabled?: boolean;
33
+ }) {
34
+ const { data: impact, isLoading } = useActionQuery(
35
+ "preview-workspace-resource-change",
36
+ {
37
+ operation,
38
+ resourceId,
39
+ path,
40
+ scope,
41
+ },
42
+ { enabled: enabled && Boolean(resourceId || path) },
43
+ );
44
+
45
+ if (!enabled || (!resourceId && !path)) return null;
46
+
47
+ if (isLoading) {
48
+ return (
49
+ <div className="rounded-lg border bg-muted/30 p-3">
50
+ <Skeleton className="h-4 w-40" />
51
+ <Skeleton className="mt-2 h-3 w-72" />
52
+ </div>
53
+ );
54
+ }
55
+
56
+ const data = impact as any;
57
+ if (!data) return null;
58
+ const affectsAllApps = data.affectsAllApps === true;
59
+ const appCount = data.affectedApps?.count;
60
+ const overrides = data.overrides ?? { count: 0, items: [] };
61
+ const willRequestApproval = data.approval?.willRequestApproval === true;
62
+
63
+ return (
64
+ <div className="rounded-lg border bg-muted/30 p-3 text-xs">
65
+ <div className="flex flex-wrap items-center gap-2">
66
+ <Badge variant={affectsAllApps ? "secondary" : "outline"}>
67
+ {affectsAllApps ? "All apps impact" : "Selected only"}
68
+ </Badge>
69
+ {willRequestApproval ? (
70
+ <Badge
71
+ variant="outline"
72
+ className="border-amber-500/30 bg-amber-500/10 text-amber-700 dark:text-amber-300"
73
+ >
74
+ Approval required
75
+ </Badge>
76
+ ) : null}
77
+ {overrides.count > 0 ? (
78
+ <Badge variant="outline">
79
+ {overrides.count} override{overrides.count === 1 ? "" : "s"}
80
+ </Badge>
81
+ ) : null}
82
+ </div>
83
+ <p className="mt-2 leading-relaxed text-muted-foreground">
84
+ {affectsAllApps
85
+ ? `This change applies to every workspace app${typeof appCount === "number" ? ` (${appCount} discovered)` : ""}.`
86
+ : "This change only applies to explicitly granted apps."}{" "}
87
+ {willRequestApproval
88
+ ? "It will be queued for approval before it takes effect."
89
+ : "It will take effect immediately when saved."}
90
+ </p>
91
+ {overrides.count > 0 ? (
92
+ <div className="mt-2 space-y-1">
93
+ {overrides.items.slice(0, 4).map((override: any) => (
94
+ <div
95
+ key={`${override.scope}:${override.owner}`}
96
+ className="flex items-center justify-between gap-3 rounded-md border bg-background px-2 py-1.5"
97
+ >
98
+ <span className="min-w-0 truncate text-muted-foreground">
99
+ {override.label}
100
+ </span>
101
+ <span className="shrink-0 font-mono text-[11px] text-muted-foreground">
102
+ {formatResourceTimestamp(override.updatedAt)}
103
+ </span>
104
+ </div>
105
+ ))}
106
+ {overrides.count > 4 ? (
107
+ <div className="text-muted-foreground">
108
+ +{overrides.count - 4} more override
109
+ {overrides.count - 4 === 1 ? "" : "s"}
110
+ </div>
111
+ ) : null}
112
+ </div>
113
+ ) : null}
114
+ </div>
115
+ );
116
+ }
@@ -162,4 +162,63 @@ export const dispatchMigrations: Array<{ version: number; sql: string }> = [
162
162
  );
163
163
  `,
164
164
  },
165
+ {
166
+ version: 3,
167
+ sql: `
168
+ CREATE TABLE IF NOT EXISTS dispatch_dreams (
169
+ id TEXT PRIMARY KEY,
170
+ owner_email TEXT NOT NULL,
171
+ org_id TEXT,
172
+ source_id TEXT NOT NULL,
173
+ title TEXT NOT NULL,
174
+ status TEXT NOT NULL,
175
+ query TEXT,
176
+ report TEXT,
177
+ summary TEXT,
178
+ candidate_count INTEGER NOT NULL,
179
+ inspected_thread_count INTEGER NOT NULL,
180
+ created_by TEXT NOT NULL,
181
+ error TEXT,
182
+ started_at INTEGER NOT NULL,
183
+ completed_at INTEGER,
184
+ created_at INTEGER NOT NULL,
185
+ updated_at INTEGER NOT NULL
186
+ );
187
+
188
+ CREATE TABLE IF NOT EXISTS dispatch_dream_proposals (
189
+ id TEXT PRIMARY KEY,
190
+ dream_id TEXT NOT NULL,
191
+ owner_email TEXT NOT NULL,
192
+ org_id TEXT,
193
+ target_type TEXT NOT NULL,
194
+ target_path TEXT NOT NULL,
195
+ title TEXT NOT NULL,
196
+ summary TEXT NOT NULL,
197
+ rationale TEXT NOT NULL,
198
+ content TEXT NOT NULL,
199
+ evidence TEXT NOT NULL,
200
+ confidence INTEGER NOT NULL,
201
+ risk TEXT NOT NULL,
202
+ status TEXT NOT NULL,
203
+ applied_by TEXT,
204
+ applied_at INTEGER,
205
+ rejected_by TEXT,
206
+ rejected_at INTEGER,
207
+ created_at INTEGER NOT NULL,
208
+ updated_at INTEGER NOT NULL
209
+ );
210
+
211
+ CREATE INDEX IF NOT EXISTS dispatch_dreams_owner_updated_idx
212
+ ON dispatch_dreams (owner_email, org_id, updated_at);
213
+
214
+ CREATE INDEX IF NOT EXISTS dispatch_dream_proposals_dream_status_idx
215
+ ON dispatch_dream_proposals (dream_id, status);
216
+ `,
217
+ },
218
+ {
219
+ version: 4,
220
+ sql: `
221
+ ALTER TABLE dispatch_dreams ADD COLUMN source_health TEXT;
222
+ `,
223
+ },
165
224
  ];
package/src/db/schema.ts CHANGED
@@ -73,6 +73,50 @@ export const dispatchAuditEvents = table("dispatch_audit_events", {
73
73
  createdAt: integer("created_at").notNull(),
74
74
  });
75
75
 
76
+ export const dispatchDreams = table("dispatch_dreams", {
77
+ id: text("id").primaryKey(),
78
+ ownerEmail: text("owner_email").notNull(),
79
+ orgId: text("org_id"),
80
+ sourceId: text("source_id").notNull(),
81
+ title: text("title").notNull(),
82
+ status: text("status").notNull(),
83
+ query: text("query"),
84
+ report: text("report"),
85
+ summary: text("summary"),
86
+ sourceHealth: text("source_health"),
87
+ candidateCount: integer("candidate_count").notNull(),
88
+ inspectedThreadCount: integer("inspected_thread_count").notNull(),
89
+ createdBy: text("created_by").notNull(),
90
+ error: text("error"),
91
+ startedAt: integer("started_at").notNull(),
92
+ completedAt: integer("completed_at"),
93
+ createdAt: integer("created_at").notNull(),
94
+ updatedAt: integer("updated_at").notNull(),
95
+ });
96
+
97
+ export const dispatchDreamProposals = table("dispatch_dream_proposals", {
98
+ id: text("id").primaryKey(),
99
+ dreamId: text("dream_id").notNull(),
100
+ ownerEmail: text("owner_email").notNull(),
101
+ orgId: text("org_id"),
102
+ targetType: text("target_type").notNull(),
103
+ targetPath: text("target_path").notNull(),
104
+ title: text("title").notNull(),
105
+ summary: text("summary").notNull(),
106
+ rationale: text("rationale").notNull(),
107
+ content: text("content").notNull(),
108
+ evidence: text("evidence").notNull(),
109
+ confidence: integer("confidence").notNull(),
110
+ risk: text("risk").notNull(),
111
+ status: text("status").notNull(),
112
+ appliedBy: text("applied_by"),
113
+ appliedAt: integer("applied_at"),
114
+ rejectedBy: text("rejected_by"),
115
+ rejectedAt: integer("rejected_at"),
116
+ createdAt: integer("created_at").notNull(),
117
+ updatedAt: integer("updated_at").notNull(),
118
+ });
119
+
76
120
  // ─── Vault: workspace-wide secret management ───────────────────────
77
121
 
78
122
  export const vaultSecrets = table("vault_secrets", {
@@ -141,7 +185,7 @@ export const workspaceResources = table("workspace_resources", {
141
185
  description: text("description"),
142
186
  path: text("path").notNull(), // resource path, e.g. "skills/designer.md"
143
187
  content: text("content").notNull(),
144
- scope: text("scope").notNull(), // "all" (push to all apps) | "selected" (grant per-app)
188
+ scope: text("scope").notNull(), // "all" (runtime inherited) | "selected" (grant per-app)
145
189
  createdBy: text("created_by").notNull(),
146
190
  createdAt: integer("created_at").notNull(),
147
191
  updatedAt: integer("updated_at").notNull(),
@@ -154,7 +198,7 @@ export const workspaceResourceGrants = table("workspace_resource_grants", {
154
198
  resourceId: text("resource_id").notNull(),
155
199
  appId: text("app_id").notNull(),
156
200
  status: text("status").notNull(), // "active" | "revoked"
157
- syncedAt: integer("synced_at"),
201
+ syncedAt: integer("synced_at"), // legacy column retained for older rows
158
202
  createdAt: integer("created_at").notNull(),
159
203
  updatedAt: integer("updated_at").notNull(),
160
204
  });
@@ -14,6 +14,9 @@ import type {
14
14
  export interface NavigationState {
15
15
  view: string;
16
16
  path?: string;
17
+ dreamId?: string;
18
+ sourceId?: string;
19
+ query?: string;
17
20
  }
18
21
 
19
22
  export function useNavigationState(extensions?: DispatchExtensionConfig) {
@@ -24,10 +27,19 @@ export function useNavigationState(extensions?: DispatchExtensionConfig) {
24
27
  // Sync current route to application state
25
28
  useEffect(() => {
26
29
  const localPathname = routerPath(location.pathname);
30
+ const params = new URLSearchParams(location.search);
27
31
  const state: NavigationState = {
28
32
  view: resolveView(localPathname, extensions),
29
33
  path: appPath(localPathname),
30
34
  };
35
+ if (state.view === "dreams") {
36
+ const dreamId = params.get("dreamId");
37
+ const sourceId = params.get("sourceId");
38
+ const query = params.get("query");
39
+ if (dreamId) state.dreamId = dreamId;
40
+ if (sourceId) state.sourceId = sourceId;
41
+ if (query) state.query = query;
42
+ }
31
43
 
32
44
  fetch(agentNativePath("/_agent-native/application-state/navigation"), {
33
45
  method: "PUT",
@@ -35,7 +47,7 @@ export function useNavigationState(extensions?: DispatchExtensionConfig) {
35
47
  headers: { "Content-Type": "application/json" },
36
48
  body: JSON.stringify(state),
37
49
  }).catch(() => {});
38
- }, [extensions, location.pathname]);
50
+ }, [extensions, location.pathname, location.search]);
39
51
 
40
52
  // Listen for navigate commands from agent
41
53
  const { data: navCommand } = useQuery({
@@ -66,10 +78,14 @@ export function useNavigationState(extensions?: DispatchExtensionConfig) {
66
78
  const cmd = navCommand as NavigationState;
67
79
 
68
80
  // Navigate to a specific path or resolve view name to path
69
- const path = routerPath(
70
- cmd.path || resolvePath(cmd.view, extensions) || "/overview",
71
- );
72
- navigate(path);
81
+ const resolvedPath =
82
+ cmd.path || resolvePath(cmd.view, extensions) || "/overview";
83
+ const path =
84
+ cmd.view === "dreams" && cmd.dreamId && !resolvedPath.includes("?")
85
+ ? `${resolvedPath}?dreamId=${encodeURIComponent(cmd.dreamId)}`
86
+ : resolvedPath;
87
+ const nextPath = routerPath(path);
88
+ navigate(nextPath);
73
89
  qc.setQueryData(["navigate-command"], null);
74
90
  }, [extensions, navCommand, navigate, qc]);
75
91
  }
@@ -77,11 +93,17 @@ export function useNavigationState(extensions?: DispatchExtensionConfig) {
77
93
  function routerPath(path: string): string {
78
94
  const basePath = appBasePath();
79
95
  if (!basePath) return path;
80
- if (path === basePath) return "/";
81
- if (path.startsWith(`${basePath}/`)) {
82
- return path.slice(basePath.length) || "/";
96
+ let result = path;
97
+ // Iteratively strip basename. A path that arrives doubly-prefixed
98
+ // (e.g. "/dispatch/dispatch/overview", possibly from a stale link or a
99
+ // prior bug) would otherwise get partially stripped here and then
100
+ // re-prefixed by react-router's basename, restoring the bad URL.
101
+ for (let i = 0; i < 4; i += 1) {
102
+ if (result === basePath) return "/";
103
+ if (!result.startsWith(`${basePath}/`)) break;
104
+ result = result.slice(basePath.length) || "/";
83
105
  }
84
- return path;
106
+ return result;
85
107
  }
86
108
 
87
109
  function extensionItemMatchesPath(
@@ -133,6 +155,7 @@ function resolveView(
133
155
  if (pathname.startsWith("/identities")) return "identities";
134
156
  if (pathname.startsWith("/approvals")) return "approvals";
135
157
  if (pathname.startsWith("/audit")) return "audit";
158
+ if (pathname.startsWith("/dreams")) return "dreams";
136
159
  if (pathname.startsWith("/thread-debug")) return "thread-debug";
137
160
  if (pathname.startsWith("/team")) return "team";
138
161
  return "overview";
@@ -174,6 +197,8 @@ function resolvePath(
174
197
  return "/approvals";
175
198
  case "audit":
176
199
  return "/audit";
200
+ case "dreams":
201
+ return "/dreams";
177
202
  case "thread-debug":
178
203
  case "threads":
179
204
  return "/thread-debug";