@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
@@ -1,9 +1,10 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useState } from "react";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useEffect, useState } from "react";
3
3
  import { useActionMutation, useActionQuery } from "@agent-native/core/client";
4
4
  import { toast } from "sonner";
5
- import { IconBook, IconChevronDown, IconChevronRight, IconCode, IconFileText, IconPlus, IconRefresh, IconTrash, IconUser, IconX, } from "@tabler/icons-react";
5
+ import { IconAlertCircle, IconBook, IconChevronDown, IconChevronRight, IconCircleCheck, IconCode, IconEdit, IconFileText, IconPlus, IconTrash, IconUser, IconX, } from "@tabler/icons-react";
6
6
  import { DispatchShell } from "../../components/dispatch-shell.js";
7
+ import { ImpactPreview, workspaceResourceMutationMessage, } from "../../components/workspace-resource-impact-preview.js";
7
8
  import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger, } from "../../components/ui/alert-dialog.js";
8
9
  import { Badge } from "../../components/ui/badge.js";
9
10
  import { Button } from "../../components/ui/button.js";
@@ -22,27 +23,150 @@ const KIND_CONFIG = {
22
23
  label: "Skill",
23
24
  icon: IconCode,
24
25
  pathPrefix: "skills/",
25
- description: "Agent skills detailed guidance for patterns and workflows",
26
+ description: "Agent skills - on-demand guidance available across workspace apps",
26
27
  },
27
28
  instruction: {
28
29
  label: "Instruction",
29
30
  icon: IconBook,
30
- pathPrefix: "",
31
- description: "Agent instructions operational rules and behavioral guidance",
31
+ pathPrefix: "instructions/",
32
+ description: "Global instructions - guardrails loaded by every app agent",
32
33
  },
33
34
  agent: {
34
35
  label: "Agent",
35
36
  icon: IconUser,
36
37
  pathPrefix: "agents/",
37
- description: "Reusable agent profiles specialist agents shared across apps",
38
+ description: "Reusable agent profiles - specialist agents shared across apps",
38
39
  },
39
40
  knowledge: {
40
41
  label: "Knowledge",
41
42
  icon: IconFileText,
42
43
  pathPrefix: "context/",
43
- description: "Knowledge packs reusable GTM, product, and domain context for apps",
44
+ description: "Reference resources - brand, positioning, persona, and domain context",
44
45
  },
45
46
  };
47
+ const STARTER_GLOBAL_CONTEXT = [
48
+ {
49
+ path: "context/company.md",
50
+ label: "Company",
51
+ kind: "knowledge",
52
+ description: "Company facts, ICP, products, and canonical links",
53
+ },
54
+ {
55
+ path: "context/brand.md",
56
+ label: "Brand",
57
+ kind: "knowledge",
58
+ description: "Voice, visual identity, naming, and style rules",
59
+ },
60
+ {
61
+ path: "context/messaging.md",
62
+ label: "Messaging",
63
+ kind: "knowledge",
64
+ description: "Positioning, value props, proof points, and objections",
65
+ },
66
+ {
67
+ path: "instructions/guardrails.md",
68
+ label: "Guardrails",
69
+ kind: "instruction",
70
+ description: "Always-on rules loaded by every app agent",
71
+ },
72
+ {
73
+ path: "skills/company-voice/SKILL.md",
74
+ label: "Company Voice",
75
+ kind: "skill",
76
+ description: "On-demand guidance for customer-facing writing",
77
+ },
78
+ ];
79
+ function resourceSlug(value) {
80
+ return value
81
+ .toLowerCase()
82
+ .replace(/[^a-z0-9]+/g, "-")
83
+ .replace(/^-+|-+$/g, "");
84
+ }
85
+ function defaultResourcePath(kind, name) {
86
+ const slug = resourceSlug(name) || "example";
87
+ if (kind === "skill")
88
+ return `skills/${slug}/SKILL.md`;
89
+ if (kind === "instruction")
90
+ return `instructions/${slug}.md`;
91
+ if (kind === "agent")
92
+ return `agents/${slug}.md`;
93
+ if (kind === "knowledge")
94
+ return `context/${slug}.md`;
95
+ return `${slug}.md`;
96
+ }
97
+ function isAutoLoadedInstruction(resource) {
98
+ return (resource.kind === "instruction" &&
99
+ (resource.path === "AGENTS.md" ||
100
+ String(resource.path).startsWith("instructions/")));
101
+ }
102
+ function formatTimestamp(value) {
103
+ if (!value)
104
+ return "Not present";
105
+ return new Date(value).toLocaleString();
106
+ }
107
+ function availabilityLabel(value) {
108
+ switch (value) {
109
+ case "all-apps":
110
+ return "Inherited by all apps";
111
+ case "selected-granted":
112
+ return "Granted to selected app";
113
+ case "selected-not-granted":
114
+ return "Not granted to this app";
115
+ case "selected-no-app":
116
+ return "Select an app to check grant";
117
+ case "path-not-managed":
118
+ return "Path is not a Dispatch resource";
119
+ default:
120
+ return "Checking availability";
121
+ }
122
+ }
123
+ function layerState(layer) {
124
+ if (layer.effective) {
125
+ return {
126
+ label: "Active",
127
+ className: "border-green-500/30 bg-green-500/10 text-green-700",
128
+ };
129
+ }
130
+ if (layer.overridden) {
131
+ return {
132
+ label: "Overridden",
133
+ className: "border-amber-500/30 bg-amber-500/10 text-amber-700",
134
+ };
135
+ }
136
+ return {
137
+ label: "Missing",
138
+ className: "text-muted-foreground",
139
+ };
140
+ }
141
+ function EditResourceDialog({ resource, trigger, }) {
142
+ const [open, setOpen] = useState(false);
143
+ const [name, setName] = useState(resource.name || "");
144
+ const [description, setDescription] = useState(resource.description || "");
145
+ const [content, setContent] = useState(resource.content || "");
146
+ const [scope, setScope] = useState(resource.scope || "all");
147
+ useEffect(() => {
148
+ if (!open)
149
+ return;
150
+ setName(resource.name || "");
151
+ setDescription(resource.description || "");
152
+ setContent(resource.content || "");
153
+ setScope(resource.scope || "all");
154
+ }, [open, resource]);
155
+ const update = useActionMutation("update-workspace-resource", {
156
+ onSuccess: (result) => {
157
+ toast.success(workspaceResourceMutationMessage(result, "Resource updated"));
158
+ setOpen(false);
159
+ },
160
+ onError: (err) => toast.error(String(err)),
161
+ });
162
+ return (_jsxs(Dialog, { open: open, onOpenChange: setOpen, children: [_jsx(DialogTrigger, { asChild: true, children: trigger || (_jsxs(Button, { variant: "outline", size: "sm", children: [_jsx(IconEdit, { size: 14, className: "mr-1.5" }), "Edit"] })) }), _jsxs(DialogContent, { className: "max-w-2xl", children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: "Edit workspace resource" }), _jsx(DialogDescription, { children: "Updates apply immediately anywhere this workspace resource is inherited. App shared or personal resources can override it locally." })] }), _jsxs("div", { className: "space-y-4 py-2", children: [_jsxs("div", { className: "grid grid-cols-2 gap-4", children: [_jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Name" }), _jsx(Input, { value: name, onChange: (e) => setName(e.target.value) })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Scope" }), _jsxs(Select, { value: scope, onValueChange: setScope, children: [_jsx(SelectTrigger, { children: _jsx(SelectValue, {}) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "all", children: "All apps" }), _jsx(SelectItem, { value: "selected", children: "Selected apps only" })] })] })] })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Path" }), _jsx(Input, { value: resource.path, disabled: true, className: "font-mono text-sm" })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Description" }), _jsx(Input, { value: description, onChange: (e) => setDescription(e.target.value) })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Content" }), _jsx(Textarea, { value: content, onChange: (e) => setContent(e.target.value), rows: 14, className: "font-mono text-sm" })] }), _jsx(ImpactPreview, { operation: "update", resourceId: resource.id, scope: scope, enabled: open })] }), _jsx(DialogFooter, { children: _jsx(Button, { onClick: () => update.mutate({
163
+ id: resource.id,
164
+ name,
165
+ description,
166
+ content,
167
+ scope: scope,
168
+ }), disabled: !name.trim() || update.isPending, children: update.isPending ? "Saving..." : "Save changes" }) })] })] }));
169
+ }
46
170
  function AddResourceDialog() {
47
171
  const [open, setOpen] = useState(false);
48
172
  const [kind, setKind] = useState("skill");
@@ -52,8 +176,8 @@ function AddResourceDialog() {
52
176
  const [content, setContent] = useState("");
53
177
  const [scope, setScope] = useState("all");
54
178
  const create = useActionMutation("create-workspace-resource", {
55
- onSuccess: () => {
56
- toast.success("Resource created");
179
+ onSuccess: (result) => {
180
+ toast.success(workspaceResourceMutationMessage(result, "Resource created"));
57
181
  setOpen(false);
58
182
  setKind("skill");
59
183
  setName("");
@@ -64,25 +188,23 @@ function AddResourceDialog() {
64
188
  },
65
189
  onError: (err) => toast.error(String(err)),
66
190
  });
67
- const kindInfo = KIND_CONFIG[kind];
68
- return (_jsxs(Dialog, { open: open, onOpenChange: setOpen, children: [_jsx(DialogTrigger, { asChild: true, children: _jsxs(Button, { children: [_jsx(IconPlus, { size: 16, className: "mr-1.5" }), "Add resource"] }) }), _jsxs(DialogContent, { className: "max-w-2xl", children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: "Add workspace resource" }), _jsx(DialogDescription, { children: "Create a skill, instruction, or agent profile that can be shared across workspace apps." })] }), _jsxs("div", { className: "space-y-4 py-2", children: [_jsxs("div", { className: "grid grid-cols-2 gap-4", children: [_jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Kind" }), _jsxs(Select, { value: kind, onValueChange: setKind, children: [_jsx(SelectTrigger, { children: _jsx(SelectValue, {}) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "skill", children: "Skill" }), _jsx(SelectItem, { value: "instruction", children: "Instruction" }), _jsx(SelectItem, { value: "agent", children: "Agent" }), _jsx(SelectItem, { value: "knowledge", children: "Knowledge pack" })] })] })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Scope" }), _jsxs(Select, { value: scope, onValueChange: setScope, children: [_jsx(SelectTrigger, { children: _jsx(SelectValue, {}) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "all", children: "All apps" }), _jsx(SelectItem, { value: "selected", children: "Selected apps only" })] })] })] })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Name" }), _jsx(Input, { placeholder: kind === "skill"
191
+ return (_jsxs(Dialog, { open: open, onOpenChange: setOpen, children: [_jsx(DialogTrigger, { asChild: true, children: _jsxs(Button, { children: [_jsx(IconPlus, { size: 16, className: "mr-1.5" }), "Add resource"] }) }), _jsxs(DialogContent, { className: "max-w-2xl", children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: "Add workspace resource" }), _jsx(DialogDescription, { children: "Create a skill, instruction, agent profile, or reference resource that can be shared across workspace apps." })] }), _jsxs("div", { className: "space-y-4 py-2", children: [_jsxs("div", { className: "grid grid-cols-2 gap-4", children: [_jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Kind" }), _jsxs(Select, { value: kind, onValueChange: setKind, children: [_jsx(SelectTrigger, { children: _jsx(SelectValue, {}) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "skill", children: "Skill" }), _jsx(SelectItem, { value: "instruction", children: "Instruction" }), _jsx(SelectItem, { value: "agent", children: "Agent" }), _jsx(SelectItem, { value: "knowledge", children: "Knowledge pack" })] })] })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Scope" }), _jsxs(Select, { value: scope, onValueChange: setScope, children: [_jsx(SelectTrigger, { children: _jsx(SelectValue, {}) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "all", children: "All apps" }), _jsx(SelectItem, { value: "selected", children: "Selected apps only" })] })] })] })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Name" }), _jsx(Input, { placeholder: kind === "skill"
69
192
  ? "Frontend Designer"
70
193
  : kind === "agent"
71
194
  ? "Research Specialist"
72
195
  : kind === "knowledge"
73
196
  ? "Core GTM Messaging"
74
- : "Code Style Guide", value: name, onChange: (e) => setName(e.target.value) })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Path" }), _jsx(Input, { placeholder: `${kindInfo?.pathPrefix || ""}${name.toLowerCase().replace(/\s+/g, "-") || "example"}.md`, value: path, onChange: (e) => setPath(e.target.value), className: "font-mono text-sm" }), _jsx("p", { className: "text-xs text-muted-foreground", children: "Resource path in target apps. Skills go in skills/, agents in agents/, knowledge packs in context/." })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Description (optional)" }), _jsx(Input, { placeholder: "Short description of what this resource does", value: description, onChange: (e) => setDescription(e.target.value) })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Content" }), _jsx(Textarea, { placeholder: kind === "skill"
197
+ : "Code Style Guide", value: name, onChange: (e) => setName(e.target.value) })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Path" }), _jsx(Input, { placeholder: defaultResourcePath(kind, name), value: path, onChange: (e) => setPath(e.target.value), className: "font-mono text-sm" }), _jsx("p", { className: "text-xs text-muted-foreground", children: "Skills use skills/name/SKILL.md. Guardrails in AGENTS.md or instructions/ auto-load in app chat. Reference resources in context/ are indexed so agents can read them when relevant." })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Description (optional)" }), _jsx(Input, { placeholder: "Short description of what this resource does", value: description, onChange: (e) => setDescription(e.target.value) })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Content" }), _jsx(Textarea, { placeholder: kind === "skill"
75
198
  ? "---\nname: my-skill\ndescription: What this skill teaches\n---\n\n# My Skill\n\n..."
76
199
  : kind === "agent"
77
200
  ? "---\nname: Research Specialist\ndescription: Handles research tasks\n---\n\n# Instructions\n\n..."
78
201
  : kind === "knowledge"
79
202
  ? "# Core GTM Messaging\n\n## Positioning\n\n## ICP\n\n## Proof points\n\n## Source\n\n"
80
- : "# Instructions\n\nBehavioral rules and guidance for agents across apps...", value: content, onChange: (e) => setContent(e.target.value), rows: 12, className: "font-mono text-sm" })] })] }), _jsx(DialogFooter, { children: _jsx(Button, { onClick: () => create.mutate({
203
+ : "# Instructions\n\nAlways-on guardrails for agents across apps...", value: content, onChange: (e) => setContent(e.target.value), rows: 12, className: "font-mono text-sm" })] }), _jsx(ImpactPreview, { operation: "create", path: path || defaultResourcePath(kind, name), scope: scope, enabled: open && Boolean(name.trim()) })] }), _jsx(DialogFooter, { children: _jsx(Button, { onClick: () => create.mutate({
81
204
  kind: kind,
82
205
  name,
83
206
  description: description || undefined,
84
- path: path ||
85
- `${kindInfo?.pathPrefix || ""}${name.toLowerCase().replace(/\s+/g, "-")}.md`,
207
+ path: path || defaultResourcePath(kind, name),
86
208
  content,
87
209
  scope: scope,
88
210
  }), disabled: !name || !content || create.isPending, children: create.isPending ? "Creating..." : "Create resource" }) })] })] }));
@@ -105,39 +227,69 @@ function GrantDialog({ resourceId, resourceName, }) {
105
227
  }));
106
228
  return (_jsxs(Dialog, { open: open, onOpenChange: setOpen, children: [_jsx(DialogTrigger, { asChild: true, children: _jsxs(Button, { variant: "outline", size: "sm", children: [_jsx(IconPlus, { size: 14, className: "mr-1" }), "Grant"] }) }), _jsxs(DialogContent, { children: [_jsxs(DialogHeader, { children: [_jsxs(DialogTitle, { children: ["Grant \"", resourceName, "\" to an app"] }), _jsx(DialogDescription, { children: "Choose which app should receive this resource." })] }), _jsx("div", { className: "py-2", children: _jsxs(Select, { value: appId, onValueChange: setAppId, children: [_jsx(SelectTrigger, { children: _jsx(SelectValue, { placeholder: "Select an app..." }) }), _jsx(SelectContent, { children: apps.map((app) => (_jsx(SelectItem, { value: app.id, children: app.name }, app.id))) })] }) }), _jsx(DialogFooter, { children: _jsx(Button, { onClick: () => grant.mutate({ resourceId, appId }), disabled: !appId || grant.isPending, children: grant.isPending ? "Granting..." : "Grant access" }) })] })] }));
107
229
  }
230
+ function EffectiveContextPreview({ resource }) {
231
+ const [appId, setAppId] = useState("__any__");
232
+ const [userEmail, setUserEmail] = useState("");
233
+ const selectedAppId = appId === "__any__" ? undefined : appId;
234
+ const normalizedUserEmail = userEmail.trim() || undefined;
235
+ const { data: apps } = useActionQuery("list-workspace-apps", {
236
+ includeAgentCards: false,
237
+ });
238
+ const { data: context, isLoading } = useActionQuery("get-workspace-resource-effective-context", {
239
+ resourceId: resource.id,
240
+ appId: selectedAppId,
241
+ userEmail: normalizedUserEmail,
242
+ });
243
+ const visibleApps = (apps || []).filter((app) => !app.isDispatch && app.status !== "pending");
244
+ const layers = (context?.layers || []);
245
+ const active = context?.effectiveResource;
246
+ const availability = context?.availability;
247
+ return (_jsxs("div", { className: "rounded-lg border bg-background p-3", children: [_jsxs("div", { className: "flex flex-wrap items-start justify-between gap-3", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("h4", { className: "text-xs font-semibold uppercase text-muted-foreground", children: "Effective in app" }), _jsx("p", { className: "mt-1 text-xs leading-relaxed text-muted-foreground", children: "Preview the runtime stack for this path: workspace default, organization/app override, then personal override." })] }), _jsx(Badge, { variant: "outline", children: availabilityLabel(availability) })] }), _jsxs("div", { className: "mt-3 grid gap-3 md:grid-cols-2", children: [_jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: `resource-app-${resource.id}`, children: "App" }), _jsxs(Select, { value: appId, onValueChange: setAppId, children: [_jsx(SelectTrigger, { id: `resource-app-${resource.id}`, children: _jsx(SelectValue, {}) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "__any__", children: "Any app" }), visibleApps.map((app) => (_jsx(SelectItem, { value: app.id, children: app.name }, app.id)))] })] })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: `resource-user-${resource.id}`, children: "User email" }), _jsx(Input, { id: `resource-user-${resource.id}`, value: userEmail, onChange: (event) => setUserEmail(event.target.value), placeholder: "Current Dispatch user" })] })] }), resource.scope === "selected" ? (_jsx("div", { className: "mt-3 rounded-md border border-amber-500/30 bg-amber-500/10 px-3 py-2 text-xs leading-relaxed text-amber-800 dark:text-amber-200", children: "Selected resources are app-specific exceptions. Use All apps for company-wide context that should be inherited everywhere without copy or sync." })) : null, isLoading ? (_jsx("div", { className: "mt-3 grid gap-2 md:grid-cols-3", children: Array.from({ length: 3 }).map((_, index) => (_jsx(Skeleton, { className: "h-28 rounded-lg" }, index))) })) : (_jsx("div", { className: "mt-3 grid gap-2 md:grid-cols-3", children: layers.map((layer) => {
248
+ const state = layerState(layer);
249
+ return (_jsxs("div", { className: "rounded-lg border p-3", children: [_jsxs("div", { className: "flex items-start justify-between gap-2", children: [_jsx("span", { className: "text-sm font-medium text-foreground", children: layer.label }), _jsx(Badge, { variant: "outline", className: state.className, children: state.label })] }), _jsx("div", { className: "mt-2 truncate font-mono text-[11px] text-muted-foreground", children: layer.owner }), layer.resource ? (_jsxs("div", { className: "mt-2 space-y-1 text-xs text-muted-foreground", children: [_jsx("div", { className: "truncate font-mono", children: layer.resource.path }), _jsx("div", { children: formatTimestamp(layer.resource.updatedAt) })] })) : (_jsx("p", { className: "mt-2 text-xs text-muted-foreground", children: "No resource exists at this layer." }))] }, layer.scope));
250
+ }) })), _jsx("div", { className: "mt-3 rounded-md bg-muted/40 px-3 py-2 text-xs text-muted-foreground", children: active ? (_jsxs(_Fragment, { children: ["Active file:", " ", _jsxs("span", { className: "font-mono text-foreground", children: [active.owner, "/", active.path] })] })) : ("No active resource exists for this path yet.") })] }));
251
+ }
108
252
  function ResourceRow({ resource, grants }) {
109
253
  const [expanded, setExpanded] = useState(false);
110
254
  const deleteResource = useActionMutation("delete-workspace-resource", {
111
- onSuccess: () => toast.success("Resource deleted"),
255
+ onSuccess: (result) => toast.success(workspaceResourceMutationMessage(result, "Resource deleted")),
112
256
  onError: (err) => toast.error(String(err)),
113
257
  });
114
258
  const revokeGrant = useActionMutation("revoke-workspace-resource-grant", {
115
259
  onSuccess: () => toast.success("Grant revoked"),
116
260
  onError: (err) => toast.error(String(err)),
117
261
  });
118
- const syncToApp = useActionMutation("sync-workspace-resources-to-app", {
119
- onSuccess: (data) => toast.success(`Synced ${data.synced} resource(s) to ${data.appId}`),
120
- onError: (err) => toast.error(String(err)),
121
- });
122
262
  const kindInfo = KIND_CONFIG[resource.kind];
123
263
  const KindIcon = kindInfo?.icon || IconCode;
124
264
  const activeGrants = grants.filter((g) => g.status === "active");
125
- return (_jsxs("div", { className: "rounded-xl border bg-card", children: [_jsxs("button", { type: "button", className: "flex w-full items-center gap-3 px-4 py-3 text-left cursor-pointer", onClick: () => setExpanded(!expanded), children: [expanded ? (_jsx(IconChevronDown, { size: 16, className: "text-muted-foreground" })) : (_jsx(IconChevronRight, { size: 16, className: "text-muted-foreground" })), _jsx(KindIcon, { size: 16, className: "text-muted-foreground" }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-sm font-medium text-foreground", children: resource.name }), _jsx(Badge, { variant: "secondary", className: "text-xs", children: kindInfo?.label || resource.kind }), _jsx(Badge, { variant: "outline", className: resource.scope === "all"
265
+ return (_jsxs("div", { className: "rounded-lg border bg-card", children: [_jsxs("button", { type: "button", className: "flex w-full items-center gap-3 px-4 py-3 text-left cursor-pointer", onClick: () => setExpanded(!expanded), children: [expanded ? (_jsx(IconChevronDown, { size: 16, className: "text-muted-foreground" })) : (_jsx(IconChevronRight, { size: 16, className: "text-muted-foreground" })), _jsx(KindIcon, { size: 16, className: "text-muted-foreground" }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-sm font-medium text-foreground", children: resource.name }), _jsx(Badge, { variant: "secondary", className: "text-xs", children: kindInfo?.label || resource.kind }), _jsx(Badge, { variant: "outline", className: resource.scope === "all"
126
266
  ? "text-xs bg-green-500/10 text-green-700 dark:text-green-400"
127
- : "text-xs", children: resource.scope === "all" ? "All apps" : "Selected" })] }), _jsx("div", { className: "mt-0.5 font-mono text-xs text-muted-foreground", children: resource.path })] }), _jsx("div", { className: "flex items-center gap-2", children: resource.scope === "selected" && (_jsxs(Badge, { variant: "outline", className: "text-xs", children: [activeGrants.length, " grant", activeGrants.length !== 1 ? "s" : ""] })) })] }), expanded && (_jsxs("div", { className: "border-t px-4 py-3 space-y-3", children: [resource.description && (_jsx("p", { className: "text-sm text-muted-foreground", children: resource.description })), _jsx("div", { className: "rounded-lg border bg-muted/30 p-3", children: _jsx("pre", { className: "whitespace-pre-wrap text-xs font-mono text-foreground max-h-64 overflow-y-auto", children: resource.content }) }), resource.scope === "selected" && (_jsxs("div", { className: "space-y-2", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: "text-xs font-medium text-foreground", children: "Grants" }), _jsx(GrantDialog, { resourceId: resource.id, resourceName: resource.name })] }), activeGrants.length > 0 ? (_jsx("div", { className: "space-y-1.5", children: activeGrants.map((grant) => (_jsxs("div", { className: "flex items-center justify-between rounded-lg border px-3 py-2", children: [_jsxs("div", { children: [_jsx("span", { className: "text-sm font-medium text-foreground", children: grant.appId }), _jsx("span", { className: "ml-2 text-xs text-muted-foreground", children: grant.syncedAt
128
- ? `synced ${new Date(grant.syncedAt).toLocaleString()}`
129
- : "not synced" })] }), _jsxs("div", { className: "flex gap-1.5", children: [_jsx(Button, { variant: "ghost", size: "sm", onClick: () => syncToApp.mutate({ appId: grant.appId }), disabled: syncToApp.isPending, children: _jsx(IconRefresh, { size: 14 }) }), _jsx(Button, { variant: "ghost", size: "sm", onClick: () => revokeGrant.mutate({ grantId: grant.id }), disabled: revokeGrant.isPending, children: _jsx(IconX, { size: 14 }) })] })] }, grant.id))) })) : (_jsx("div", { className: "rounded-lg border border-dashed px-3 py-4 text-center text-xs text-muted-foreground", children: "No grants yet. Grant this resource to specific apps." }))] })), _jsxs("div", { className: "flex justify-between border-t pt-3", children: [_jsxs("div", { className: "text-xs text-muted-foreground", children: ["Created by ", resource.createdBy, " \u00B7", " ", new Date(resource.createdAt).toLocaleString()] }), _jsxs(AlertDialog, { children: [_jsx(AlertDialogTrigger, { asChild: true, children: _jsxs(Button, { variant: "destructive", size: "sm", disabled: deleteResource.isPending, children: [_jsx(IconTrash, { size: 14, className: "mr-1" }), "Delete"] }) }), _jsxs(AlertDialogContent, { children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { children: "Delete this resource?" }), _jsxs(AlertDialogDescription, { children: ["Removing \"", resource.name, "\" revokes all of its grants. Apps that depended on this resource will lose access on the next sync. This cannot be undone."] })] }), _jsxs(AlertDialogFooter, { children: [_jsx(AlertDialogCancel, { children: "Cancel" }), _jsx(AlertDialogAction, { onClick: () => deleteResource.mutate({ id: resource.id }), children: "Delete resource" })] })] })] })] })] }))] }));
267
+ : "text-xs", children: resource.scope === "all" ? "All apps" : "Selected" }), isAutoLoadedInstruction(resource) && (_jsx(Badge, { variant: "outline", className: "text-xs", children: "Auto-loaded" }))] }), _jsx("div", { className: "mt-0.5 font-mono text-xs text-muted-foreground", children: resource.path })] }), _jsx("div", { className: "flex items-center gap-2", children: resource.scope === "selected" && (_jsxs(Badge, { variant: "outline", className: "text-xs", children: [activeGrants.length, " grant", activeGrants.length !== 1 ? "s" : ""] })) })] }), expanded && (_jsxs("div", { className: "border-t px-4 py-3 space-y-3", children: [resource.description && (_jsx("p", { className: "text-sm text-muted-foreground", children: resource.description })), _jsx("div", { className: "rounded-lg border bg-muted/30 p-3", children: _jsx("pre", { className: "whitespace-pre-wrap text-xs font-mono text-foreground max-h-64 overflow-y-auto", children: resource.content }) }), _jsx(EffectiveContextPreview, { resource: resource }), resource.scope === "selected" && (_jsxs("div", { className: "space-y-2", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: "text-xs font-medium text-foreground", children: "Grants" }), _jsx(GrantDialog, { resourceId: resource.id, resourceName: resource.name })] }), activeGrants.length > 0 ? (_jsx("div", { className: "space-y-1.5", children: activeGrants.map((grant) => (_jsxs("div", { className: "flex items-center justify-between rounded-lg border px-3 py-2", children: [_jsxs("div", { children: [_jsx("span", { className: "text-sm font-medium text-foreground", children: grant.appId }), _jsx("span", { className: "ml-2 text-xs text-muted-foreground", children: "selected grant" })] }), _jsx("div", { className: "flex gap-1.5", children: _jsx(Button, { variant: "ghost", size: "sm", onClick: () => revokeGrant.mutate({ grantId: grant.id }), disabled: revokeGrant.isPending, children: _jsx(IconX, { size: 14 }) }) })] }, grant.id))) })) : (_jsx("div", { className: "rounded-lg border border-dashed px-3 py-4 text-center text-xs text-muted-foreground", children: "No grants yet. Grant this resource to specific apps." }))] })), _jsxs("div", { className: "flex justify-between border-t pt-3", children: [_jsxs("div", { className: "text-xs text-muted-foreground", children: ["Created by ", resource.createdBy, " \u00B7", " ", new Date(resource.createdAt).toLocaleString()] }), _jsxs("div", { className: "flex gap-2", children: [_jsx(EditResourceDialog, { resource: resource }), _jsxs(AlertDialog, { children: [_jsx(AlertDialogTrigger, { asChild: true, children: _jsxs(Button, { variant: "destructive", size: "sm", disabled: deleteResource.isPending, children: [_jsx(IconTrash, { size: 14, className: "mr-1" }), "Delete"] }) }), _jsxs(AlertDialogContent, { children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { children: "Delete this resource?" }), _jsxs(AlertDialogDescription, { children: ["Removing \"", resource.name, "\" revokes all of its grants and removes inherited workspace access immediately. This cannot be undone."] })] }), _jsx(ImpactPreview, { operation: "delete", resourceId: resource.id, enabled: true }), _jsxs(AlertDialogFooter, { children: [_jsx(AlertDialogCancel, { children: "Cancel" }), _jsx(AlertDialogAction, { onClick: () => deleteResource.mutate({ id: resource.id }), children: "Delete resource" })] })] })] })] })] })] }))] }));
130
268
  }
131
- export default function WorkspaceRoute() {
132
- const { data: resources, isLoading } = useActionQuery("list-workspace-resources", {});
133
- const { data: grants } = useActionQuery("list-workspace-resource-grants", {});
134
- const syncAll = useActionMutation("sync-workspace-resources-to-all", {
135
- onSuccess: (data) => {
136
- const total = (data || []).reduce((sum, r) => sum + r.synced, 0);
137
- toast.success(`Synced resources to ${data?.length || 0} apps (${total} total pushes)`);
269
+ function GlobalContextSection({ resources }) {
270
+ const byPath = new Map(resources.map((resource) => [resource.path, resource]));
271
+ const missingPaths = STARTER_GLOBAL_CONTEXT.filter((item) => !byPath.has(item.path)).map((item) => item.path);
272
+ const presentCount = STARTER_GLOBAL_CONTEXT.length - missingPaths.length;
273
+ const restoreStarter = useActionMutation("restore-starter-workspace-resources", {
274
+ onSuccess: (result) => {
275
+ const restored = result?.restored?.length ?? 0;
276
+ const existing = result?.existing?.length ?? 0;
277
+ toast.success(restored > 0
278
+ ? `Restored ${restored} starter resource${restored === 1 ? "" : "s"}`
279
+ : `Starter resources already present (${existing})`);
138
280
  },
139
281
  onError: (err) => toast.error(String(err)),
140
282
  });
283
+ return (_jsxs("section", { className: "space-y-3", children: [_jsxs("div", { className: "flex items-center justify-between gap-3", children: [_jsxs("div", { children: [_jsx("h2", { className: "text-sm font-semibold text-foreground", children: "Global context" }), _jsx("p", { className: "mt-1 text-xs text-muted-foreground", children: "Starter resources every workspace can use for company facts, brand, messaging, guardrails, and voice." }), _jsx("p", { className: "mt-1 text-xs text-muted-foreground", children: "All-app resources live once at workspace scope and are inherited by every app agent at runtime." })] }), _jsxs("div", { className: "flex shrink-0 items-center gap-2", children: [missingPaths.length > 0 ? (_jsxs(Button, { size: "sm", variant: "outline", onClick: () => restoreStarter.mutate({ paths: missingPaths }), disabled: restoreStarter.isPending, children: [_jsx(IconPlus, { size: 14, className: "mr-1.5" }), restoreStarter.isPending ? "Restoring..." : "Restore missing"] })) : null, _jsxs(Badge, { variant: "outline", children: [presentCount, "/", STARTER_GLOBAL_CONTEXT.length, " ready"] })] })] }), _jsx("div", { className: "grid gap-3 md:grid-cols-2 xl:grid-cols-5", children: STARTER_GLOBAL_CONTEXT.map((item) => {
284
+ const resource = byPath.get(item.path);
285
+ const exists = !!resource;
286
+ const global = resource?.scope === "all";
287
+ return (_jsxs("div", { className: "rounded-lg border bg-card p-4", children: [_jsxs("div", { className: "flex items-start justify-between gap-3", children: [_jsxs("div", { className: "min-w-0", children: [_jsxs("div", { className: "flex items-center gap-2", children: [exists ? (_jsx(IconCircleCheck, { size: 15, className: "shrink-0 text-green-600 dark:text-green-400" })) : (_jsx(IconAlertCircle, { size: 15, className: "shrink-0 text-amber-600 dark:text-amber-400" })), _jsx("h3", { className: "truncate text-sm font-medium text-foreground", children: item.label })] }), _jsx("p", { className: "mt-1 line-clamp-2 text-xs text-muted-foreground", children: item.description })] }), resource ? (_jsx(EditResourceDialog, { resource: resource, trigger: _jsxs(Button, { variant: "ghost", size: "sm", className: "h-7 px-2", children: [_jsxs("span", { className: "sr-only", children: ["Edit ", item.label] }), _jsx(IconEdit, { size: 14 })] }) })) : (_jsx(Button, { variant: "ghost", size: "sm", className: "h-7 px-2", onClick: () => restoreStarter.mutate({ paths: [item.path] }), disabled: restoreStarter.isPending, "aria-label": `Restore ${item.label}`, children: _jsx(IconPlus, { size: 14 }) }))] }), _jsxs("div", { className: "mt-3 space-y-2", children: [_jsx("div", { className: "truncate font-mono text-[11px] text-muted-foreground", children: item.path }), _jsxs("div", { className: "flex flex-wrap gap-1.5", children: [_jsx(Badge, { variant: exists ? "secondary" : "outline", children: exists ? "Present" : "Missing" }), exists ? (_jsx(Badge, { variant: "outline", children: global ? "All apps" : "Selected" })) : null, resource && isAutoLoadedInstruction(resource) ? (_jsx(Badge, { variant: "outline", children: "Auto-loaded" })) : null] })] })] }, item.path));
288
+ }) })] }));
289
+ }
290
+ export default function WorkspaceRoute() {
291
+ const { data: resources, isLoading } = useActionQuery("list-workspace-resources", {});
292
+ const { data: grants } = useActionQuery("list-workspace-resource-grants", {});
141
293
  const grantsByResource = (grants || []).reduce((acc, g) => {
142
294
  if (!acc[g.resourceId])
143
295
  acc[g.resourceId] = [];
@@ -150,13 +302,13 @@ export default function WorkspaceRoute() {
150
302
  const knowledge = (resources || []).filter((r) => r.kind === "knowledge");
151
303
  function ResourceList({ items, emptyText, }) {
152
304
  if (isLoading && (resources ?? []).length === 0) {
153
- return (_jsx("div", { className: "space-y-3", children: Array.from({ length: 3 }).map((_, index) => (_jsxs("div", { className: "rounded-2xl border bg-card px-5 py-4 space-y-2", children: [_jsx(Skeleton, { className: "h-4 w-1/3" }), _jsx(Skeleton, { className: "h-3 w-2/3" })] }, index))) }));
305
+ return (_jsx("div", { className: "space-y-3", children: Array.from({ length: 3 }).map((_, index) => (_jsxs("div", { className: "rounded-lg border bg-card px-5 py-4 space-y-2", children: [_jsx(Skeleton, { className: "h-4 w-1/3" }), _jsx(Skeleton, { className: "h-3 w-2/3" })] }, index))) }));
154
306
  }
155
307
  if (items.length === 0) {
156
- return (_jsx("div", { className: "rounded-2xl border border-dashed px-6 py-12 text-center text-sm text-muted-foreground", children: emptyText }));
308
+ return (_jsx("div", { className: "rounded-lg border border-dashed px-6 py-12 text-center text-sm text-muted-foreground", children: emptyText }));
157
309
  }
158
310
  return (_jsx("div", { className: "space-y-3", children: items.map((resource) => (_jsx(ResourceRow, { resource: resource, grants: grantsByResource[resource.id] || [] }, resource.id))) }));
159
311
  }
160
- return (_jsxs(DispatchShell, { title: "Workspace Resources", description: "Share skills, instructions, agent profiles, and knowledge packs across workspace apps. Scope to all apps or grant per-app.", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("div", { className: "text-sm text-muted-foreground", children: isLoading ? (_jsx(Skeleton, { className: "h-4 w-24" })) : (`${resources?.length || 0} resource${(resources?.length || 0) !== 1 ? "s" : ""}`) }), _jsxs("div", { className: "flex gap-2", children: [_jsxs(Button, { variant: "outline", onClick: () => syncAll.mutate({}), disabled: syncAll.isPending || (resources?.length || 0) === 0, children: [_jsx(IconRefresh, { size: 16, className: syncAll.isPending ? "mr-1.5 animate-spin" : "mr-1.5" }), "Sync all"] }), _jsx(AddResourceDialog, {})] })] }), _jsxs(Tabs, { defaultValue: "skills", children: [_jsxs(TabsList, { children: [_jsxs(TabsTrigger, { value: "skills", children: ["Skills ", skills.length > 0 && `(${skills.length})`] }), _jsxs(TabsTrigger, { value: "instructions", children: ["Instructions ", instructions.length > 0 && `(${instructions.length})`] }), _jsxs(TabsTrigger, { value: "agents", children: ["Agents ", agents.length > 0 && `(${agents.length})`] }), _jsxs(TabsTrigger, { value: "knowledge", children: ["Knowledge ", knowledge.length > 0 && `(${knowledge.length})`] })] }), _jsx(TabsContent, { value: "skills", className: "mt-4", children: _jsx(ResourceList, { items: skills, emptyText: "No workspace skills yet. Add a skill to share agent guidance across apps." }) }), _jsx(TabsContent, { value: "instructions", className: "mt-4", children: _jsx(ResourceList, { items: instructions, emptyText: "No workspace instructions yet. Add instructions to set behavioral rules across apps." }) }), _jsx(TabsContent, { value: "agents", className: "mt-4", children: _jsx(ResourceList, { items: agents, emptyText: "No workspace agents yet. Add a reusable agent profile to share specialist agents across apps." }) }), _jsx(TabsContent, { value: "knowledge", className: "mt-4", children: _jsx(ResourceList, { items: knowledge, emptyText: "No knowledge packs yet. Add GTM, product, or domain context that apps can reuse." }) })] })] }));
312
+ return (_jsxs(DispatchShell, { title: "Workspace Resources", description: "Manage inherited workspace skills, guardrail instructions, agent profiles, and reference resources. All-app resources are available to every app without syncing.", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("div", { className: "text-sm text-muted-foreground", children: isLoading ? (_jsx(Skeleton, { className: "h-4 w-24" })) : (`${resources?.length || 0} resource${(resources?.length || 0) !== 1 ? "s" : ""}`) }), _jsx("div", { className: "flex gap-2", children: _jsx(AddResourceDialog, {}) })] }), _jsx(GlobalContextSection, { resources: resources || [] }), _jsxs(Tabs, { defaultValue: "skills", children: [_jsxs(TabsList, { children: [_jsxs(TabsTrigger, { value: "skills", children: ["Skills ", skills.length > 0 && `(${skills.length})`] }), _jsxs(TabsTrigger, { value: "instructions", children: ["Instructions ", instructions.length > 0 && `(${instructions.length})`] }), _jsxs(TabsTrigger, { value: "agents", children: ["Agents ", agents.length > 0 && `(${agents.length})`] }), _jsxs(TabsTrigger, { value: "knowledge", children: ["Knowledge ", knowledge.length > 0 && `(${knowledge.length})`] })] }), _jsx(TabsContent, { value: "skills", className: "mt-4", children: _jsx(ResourceList, { items: skills, emptyText: "No workspace skills yet. Add a skill to share agent guidance across apps." }) }), _jsx(TabsContent, { value: "instructions", className: "mt-4", children: _jsx(ResourceList, { items: instructions, emptyText: "No workspace instructions yet. Add instructions to set behavioral rules across apps." }) }), _jsx(TabsContent, { value: "agents", className: "mt-4", children: _jsx(ResourceList, { items: agents, emptyText: "No workspace agents yet. Add a reusable agent profile to share specialist agents across apps." }) }), _jsx(TabsContent, { value: "knowledge", className: "mt-4", children: _jsx(ResourceList, { items: knowledge, emptyText: "No knowledge packs yet. Add GTM, product, or domain context that apps can reuse." }) })] })] }));
161
313
  }
162
314
  //# sourceMappingURL=workspace.js.map