@jini-ai/admin 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (235) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +138 -0
  3. package/dist/browser/index.d.ts +8 -0
  4. package/dist/browser/index.d.ts.map +1 -0
  5. package/dist/browser/index.js +8 -0
  6. package/dist/browser/index.js.map +1 -0
  7. package/dist/browser/navigation.d.ts +39 -0
  8. package/dist/browser/navigation.d.ts.map +1 -0
  9. package/dist/browser/navigation.js +113 -0
  10. package/dist/browser/navigation.js.map +1 -0
  11. package/dist/core/gated/types.d.ts +87 -0
  12. package/dist/core/gated/types.d.ts.map +1 -0
  13. package/dist/core/gated/types.js +37 -0
  14. package/dist/core/gated/types.js.map +1 -0
  15. package/dist/core/index.d.ts +20 -0
  16. package/dist/core/index.d.ts.map +1 -0
  17. package/dist/core/index.js +15 -0
  18. package/dist/core/index.js.map +1 -0
  19. package/dist/core/manifest/rules.d.ts +84 -0
  20. package/dist/core/manifest/rules.d.ts.map +1 -0
  21. package/dist/core/manifest/rules.js +130 -0
  22. package/dist/core/manifest/rules.js.map +1 -0
  23. package/dist/core/manifest/types.d.ts +154 -0
  24. package/dist/core/manifest/types.d.ts.map +1 -0
  25. package/dist/core/manifest/types.js +31 -0
  26. package/dist/core/manifest/types.js.map +1 -0
  27. package/dist/core/permissions/rules.d.ts +32 -0
  28. package/dist/core/permissions/rules.d.ts.map +1 -0
  29. package/dist/core/permissions/rules.js +34 -0
  30. package/dist/core/permissions/rules.js.map +1 -0
  31. package/dist/core/ports/analytics.d.ts +35 -0
  32. package/dist/core/ports/analytics.d.ts.map +1 -0
  33. package/dist/core/ports/analytics.js +14 -0
  34. package/dist/core/ports/analytics.js.map +1 -0
  35. package/dist/core/ports/auth.d.ts +49 -0
  36. package/dist/core/ports/auth.d.ts.map +1 -0
  37. package/dist/core/ports/auth.js +19 -0
  38. package/dist/core/ports/auth.js.map +1 -0
  39. package/dist/core/ports/comments.d.ts +90 -0
  40. package/dist/core/ports/comments.d.ts.map +1 -0
  41. package/dist/core/ports/comments.js +24 -0
  42. package/dist/core/ports/comments.js.map +1 -0
  43. package/dist/core/ports/database.d.ts +101 -0
  44. package/dist/core/ports/database.d.ts.map +1 -0
  45. package/dist/core/ports/database.js +2 -0
  46. package/dist/core/ports/database.js.map +1 -0
  47. package/dist/core/ports/forms.d.ts +130 -0
  48. package/dist/core/ports/forms.d.ts.map +1 -0
  49. package/dist/core/ports/forms.js +62 -0
  50. package/dist/core/ports/forms.js.map +1 -0
  51. package/dist/core/ports/identity.d.ts +114 -0
  52. package/dist/core/ports/identity.d.ts.map +1 -0
  53. package/dist/core/ports/identity.js +28 -0
  54. package/dist/core/ports/identity.js.map +1 -0
  55. package/dist/core/ports/index.d.ts +21 -0
  56. package/dist/core/ports/index.d.ts.map +1 -0
  57. package/dist/core/ports/index.js +6 -0
  58. package/dist/core/ports/index.js.map +1 -0
  59. package/dist/core/ports/integrations.d.ts +81 -0
  60. package/dist/core/ports/integrations.d.ts.map +1 -0
  61. package/dist/core/ports/integrations.js +21 -0
  62. package/dist/core/ports/integrations.js.map +1 -0
  63. package/dist/core/ports/media.d.ts +74 -0
  64. package/dist/core/ports/media.d.ts.map +1 -0
  65. package/dist/core/ports/media.js +28 -0
  66. package/dist/core/ports/media.js.map +1 -0
  67. package/dist/core/ports/members.d.ts +50 -0
  68. package/dist/core/ports/members.d.ts.map +1 -0
  69. package/dist/core/ports/members.js +17 -0
  70. package/dist/core/ports/members.js.map +1 -0
  71. package/dist/core/ports/menus.d.ts +179 -0
  72. package/dist/core/ports/menus.d.ts.map +1 -0
  73. package/dist/core/ports/menus.js +70 -0
  74. package/dist/core/ports/menus.js.map +1 -0
  75. package/dist/core/ports/plugins.d.ts +68 -0
  76. package/dist/core/ports/plugins.d.ts.map +1 -0
  77. package/dist/core/ports/plugins.js +27 -0
  78. package/dist/core/ports/plugins.js.map +1 -0
  79. package/dist/core/ports/recovery.d.ts +171 -0
  80. package/dist/core/ports/recovery.d.ts.map +1 -0
  81. package/dist/core/ports/recovery.js +2 -0
  82. package/dist/core/ports/recovery.js.map +1 -0
  83. package/dist/core/ports/redirects.d.ts +139 -0
  84. package/dist/core/ports/redirects.d.ts.map +1 -0
  85. package/dist/core/ports/redirects.js +55 -0
  86. package/dist/core/ports/redirects.js.map +1 -0
  87. package/dist/core/ports/seo.d.ts +147 -0
  88. package/dist/core/ports/seo.d.ts.map +1 -0
  89. package/dist/core/ports/seo.js +39 -0
  90. package/dist/core/ports/seo.js.map +1 -0
  91. package/dist/core/ports/settings.d.ts +87 -0
  92. package/dist/core/ports/settings.d.ts.map +1 -0
  93. package/dist/core/ports/settings.js +23 -0
  94. package/dist/core/ports/settings.js.map +1 -0
  95. package/dist/core/ports/workspace.d.ts +44 -0
  96. package/dist/core/ports/workspace.d.ts.map +1 -0
  97. package/dist/core/ports/workspace.js +29 -0
  98. package/dist/core/ports/workspace.js.map +1 -0
  99. package/dist/core/routing/rules.d.ts +54 -0
  100. package/dist/core/routing/rules.d.ts.map +1 -0
  101. package/dist/core/routing/rules.js +113 -0
  102. package/dist/core/routing/rules.js.map +1 -0
  103. package/dist/core/routing/types.d.ts +36 -0
  104. package/dist/core/routing/types.d.ts.map +1 -0
  105. package/dist/core/routing/types.js +17 -0
  106. package/dist/core/routing/types.js.map +1 -0
  107. package/dist/core/transport/errors.d.ts +53 -0
  108. package/dist/core/transport/errors.d.ts.map +1 -0
  109. package/dist/core/transport/errors.js +63 -0
  110. package/dist/core/transport/errors.js.map +1 -0
  111. package/dist/core/transport/http.d.ts +63 -0
  112. package/dist/core/transport/http.d.ts.map +1 -0
  113. package/dist/core/transport/http.js +63 -0
  114. package/dist/core/transport/http.js.map +1 -0
  115. package/dist/core/transport/index.d.ts +5 -0
  116. package/dist/core/transport/index.d.ts.map +1 -0
  117. package/dist/core/transport/index.js +3 -0
  118. package/dist/core/transport/index.js.map +1 -0
  119. package/dist/core/transport/types.d.ts +81 -0
  120. package/dist/core/transport/types.d.ts.map +1 -0
  121. package/dist/core/transport/types.js +43 -0
  122. package/dist/core/transport/types.js.map +1 -0
  123. package/dist/react/components/ConfirmButton/ConfirmButton.d.ts +40 -0
  124. package/dist/react/components/ConfirmButton/ConfirmButton.d.ts.map +1 -0
  125. package/dist/react/components/ConfirmButton/ConfirmButton.hooks.d.ts +22 -0
  126. package/dist/react/components/ConfirmButton/ConfirmButton.hooks.d.ts.map +1 -0
  127. package/dist/react/components/ConfirmButton/ConfirmButton.hooks.js +59 -0
  128. package/dist/react/components/ConfirmButton/ConfirmButton.hooks.js.map +1 -0
  129. package/dist/react/components/ConfirmButton/ConfirmButton.js +40 -0
  130. package/dist/react/components/ConfirmButton/ConfirmButton.js.map +1 -0
  131. package/dist/react/components/ConfirmButton.d.ts +39 -0
  132. package/dist/react/components/ConfirmButton.d.ts.map +1 -0
  133. package/dist/react/components/ConfirmButton.js +79 -0
  134. package/dist/react/components/ConfirmButton.js.map +1 -0
  135. package/dist/react/components/ConfirmDialog/ConfirmDialog.d.ts +90 -0
  136. package/dist/react/components/ConfirmDialog/ConfirmDialog.d.ts.map +1 -0
  137. package/dist/react/components/ConfirmDialog/ConfirmDialog.hooks.d.ts +49 -0
  138. package/dist/react/components/ConfirmDialog/ConfirmDialog.hooks.d.ts.map +1 -0
  139. package/dist/react/components/ConfirmDialog/ConfirmDialog.hooks.js +81 -0
  140. package/dist/react/components/ConfirmDialog/ConfirmDialog.hooks.js.map +1 -0
  141. package/dist/react/components/ConfirmDialog/ConfirmDialog.js +92 -0
  142. package/dist/react/components/ConfirmDialog/ConfirmDialog.js.map +1 -0
  143. package/dist/react/components/ConfirmDialog.d.ts +57 -0
  144. package/dist/react/components/ConfirmDialog.d.ts.map +1 -0
  145. package/dist/react/components/ConfirmDialog.js +85 -0
  146. package/dist/react/components/ConfirmDialog.js.map +1 -0
  147. package/dist/react/components/DataTable.d.ts +97 -0
  148. package/dist/react/components/DataTable.d.ts.map +1 -0
  149. package/dist/react/components/DataTable.js +20 -0
  150. package/dist/react/components/DataTable.js.map +1 -0
  151. package/dist/react/components/InteractiveHtmlEditor/InteractiveHtmlEditor.d.ts +25 -0
  152. package/dist/react/components/InteractiveHtmlEditor/InteractiveHtmlEditor.d.ts.map +1 -0
  153. package/dist/react/components/InteractiveHtmlEditor/InteractiveHtmlEditor.js +148 -0
  154. package/dist/react/components/InteractiveHtmlEditor/InteractiveHtmlEditor.js.map +1 -0
  155. package/dist/react/components/RowMenu/RowMenu.d.ts +77 -0
  156. package/dist/react/components/RowMenu/RowMenu.d.ts.map +1 -0
  157. package/dist/react/components/RowMenu/RowMenu.hooks.d.ts +30 -0
  158. package/dist/react/components/RowMenu/RowMenu.hooks.d.ts.map +1 -0
  159. package/dist/react/components/RowMenu/RowMenu.hooks.js +154 -0
  160. package/dist/react/components/RowMenu/RowMenu.hooks.js.map +1 -0
  161. package/dist/react/components/RowMenu/RowMenu.js +46 -0
  162. package/dist/react/components/RowMenu/RowMenu.js.map +1 -0
  163. package/dist/react/components/RowMenu.d.ts +44 -0
  164. package/dist/react/components/RowMenu.d.ts.map +1 -0
  165. package/dist/react/components/RowMenu.js +149 -0
  166. package/dist/react/components/RowMenu.js.map +1 -0
  167. package/dist/react/components/Sidebar.d.ts +128 -0
  168. package/dist/react/components/Sidebar.d.ts.map +1 -0
  169. package/dist/react/components/Sidebar.js +168 -0
  170. package/dist/react/components/Sidebar.js.map +1 -0
  171. package/dist/react/hooks/use-nav-sections.d.ts +50 -0
  172. package/dist/react/hooks/use-nav-sections.d.ts.map +1 -0
  173. package/dist/react/hooks/use-nav-sections.js +112 -0
  174. package/dist/react/hooks/use-nav-sections.js.map +1 -0
  175. package/dist/react/hooks/use-sidebar-rail.d.ts +39 -0
  176. package/dist/react/hooks/use-sidebar-rail.d.ts.map +1 -0
  177. package/dist/react/hooks/use-sidebar-rail.js +93 -0
  178. package/dist/react/hooks/use-sidebar-rail.js.map +1 -0
  179. package/dist/react/index.d.ts +53 -0
  180. package/dist/react/index.d.ts.map +1 -0
  181. package/dist/react/index.js +53 -0
  182. package/dist/react/index.js.map +1 -0
  183. package/dist/react/types.d.ts +28 -0
  184. package/dist/react/types.d.ts.map +1 -0
  185. package/dist/react/types.js +23 -0
  186. package/dist/react/types.js.map +1 -0
  187. package/dist/server/composio/bounded-data.d.ts +36 -0
  188. package/dist/server/composio/bounded-data.d.ts.map +1 -0
  189. package/dist/server/composio/bounded-data.js +181 -0
  190. package/dist/server/composio/bounded-data.js.map +1 -0
  191. package/dist/server/composio/catalog.d.ts +147 -0
  192. package/dist/server/composio/catalog.d.ts.map +1 -0
  193. package/dist/server/composio/catalog.js +126 -0
  194. package/dist/server/composio/catalog.js.map +1 -0
  195. package/dist/server/composio/composio-config.d.ts +42 -0
  196. package/dist/server/composio/composio-config.d.ts.map +1 -0
  197. package/dist/server/composio/composio-config.js +145 -0
  198. package/dist/server/composio/composio-config.js.map +1 -0
  199. package/dist/server/composio/composio-descriptions.d.ts +16 -0
  200. package/dist/server/composio/composio-descriptions.d.ts.map +1 -0
  201. package/dist/server/composio/composio-descriptions.js +766 -0
  202. package/dist/server/composio/composio-descriptions.js.map +1 -0
  203. package/dist/server/composio/composio.d.ts +364 -0
  204. package/dist/server/composio/composio.d.ts.map +1 -0
  205. package/dist/server/composio/composio.js +1902 -0
  206. package/dist/server/composio/composio.js.map +1 -0
  207. package/dist/server/composio/errors.d.ts +15 -0
  208. package/dist/server/composio/errors.d.ts.map +1 -0
  209. package/dist/server/composio/errors.js +16 -0
  210. package/dist/server/composio/errors.js.map +1 -0
  211. package/dist/server/composio/file-lock.d.ts +13 -0
  212. package/dist/server/composio/file-lock.d.ts.map +1 -0
  213. package/dist/server/composio/file-lock.js +92 -0
  214. package/dist/server/composio/file-lock.js.map +1 -0
  215. package/dist/server/composio/index.d.ts +18 -0
  216. package/dist/server/composio/index.d.ts.map +1 -0
  217. package/dist/server/composio/index.js +7 -0
  218. package/dist/server/composio/index.js.map +1 -0
  219. package/dist/server/composio/json-schema.d.ts +93 -0
  220. package/dist/server/composio/json-schema.d.ts.map +1 -0
  221. package/dist/server/composio/json-schema.js +498 -0
  222. package/dist/server/composio/json-schema.js.map +1 -0
  223. package/dist/server/composio/output-protection.d.ts +32 -0
  224. package/dist/server/composio/output-protection.d.ts.map +1 -0
  225. package/dist/server/composio/output-protection.js +105 -0
  226. package/dist/server/composio/output-protection.js.map +1 -0
  227. package/dist/server/composio/service.d.ts +181 -0
  228. package/dist/server/composio/service.d.ts.map +1 -0
  229. package/dist/server/composio/service.js +758 -0
  230. package/dist/server/composio/service.js.map +1 -0
  231. package/dist/server/index.d.ts +15 -0
  232. package/dist/server/index.d.ts.map +1 -0
  233. package/dist/server/index.js +15 -0
  234. package/dist/server/index.js.map +1 -0
  235. package/package.json +92 -0
@@ -0,0 +1,53 @@
1
+ /**
2
+ * @file `@jini-ai/admin/react` — the React layer. Presentational primitives the admin shell and its
3
+ * panels are built from.
4
+ *
5
+ * ## What belongs here
6
+ *
7
+ * Components and hooks that are genuinely reusable across hosts. Anything that decides *policy* —
8
+ * which panels exist, what a route means, who may see a section — lives in `/core` and is passed in
9
+ * as data. `Sidebar` is the worked example: it renders an `AdminNavGroup[]` produced by `/core`'s
10
+ * `buildNav`, and has no nav list of its own.
11
+ *
12
+ * ## Styling contract
13
+ *
14
+ * **Every component here is unstyled**, with one narrow exception. Most emit stable class names
15
+ * (`.cms-nav`, `.row-menu-*`, `.confirm-dialog`, `.btn-danger`, `.btn-warning`, `.btn-secondary`,
16
+ * `.visually-hidden`) and ship no CSS whatsoever — the host owns the stylesheet. Inline styles
17
+ * appear only where a value must be measured at runtime — portal coordinates in `Sidebar`'s rail
18
+ * tooltip and `RowMenu`'s popup. `InteractiveHtmlEditor` is the exception: it (transitively, via
19
+ * `@jini-ai/ui/html-editor`, which this file's own `InteractiveHtmlEditor` composes with a
20
+ * Tovu-specific embed-protection predicate) imports GrapesJS's own vendor stylesheet, because it
21
+ * wraps a third-party editor whose chrome does not render without it — see that primitive's file
22
+ * header for why this isn't authored styling the exception undoes.
23
+ *
24
+ * A few behaviors documented in these files assume the host defines a matching rule (for instance
25
+ * that `.visually-hidden` is `position: absolute`, so `ConfirmButton`'s live region does not
26
+ * consume layout). Those assumptions are called out where they are load-bearing.
27
+ *
28
+ * ## Runtime
29
+ *
30
+ * `browser` — `react-dom`'s `createPortal` into `document.body`, `localStorage`, and `window`
31
+ * listeners. Declared as such in `jini.entries`. React and react-dom are optional peers of this
32
+ * package, so a host importing only `/core`, `/browser`, or `/server` never installs them.
33
+ */
34
+ export { resolveTone, toneClassName } from './types.js';
35
+ export type { ConfirmTone } from './types.js';
36
+ export { ConfirmButton } from './components/ConfirmButton/ConfirmButton.js';
37
+ export type { ConfirmButtonProps } from './components/ConfirmButton/ConfirmButton.js';
38
+ export { ConfirmDialog } from './components/ConfirmDialog/ConfirmDialog.js';
39
+ export type { ConfirmDialogProps } from './components/ConfirmDialog/ConfirmDialog.js';
40
+ export type { ConfirmDialogController, UseConfirmDialog } from './components/ConfirmDialog/ConfirmDialog.hooks.js';
41
+ export { DataTable } from './components/DataTable.js';
42
+ export type { DataTableColumn, DataTableProps } from './components/DataTable.js';
43
+ export { InteractiveHtmlEditor } from './components/InteractiveHtmlEditor/InteractiveHtmlEditor.js';
44
+ export type { InteractiveHtmlEditorProps } from './components/InteractiveHtmlEditor/InteractiveHtmlEditor.js';
45
+ export { RowMenu } from './components/RowMenu/RowMenu.js';
46
+ export type { RowMenuItem, RowMenuProps } from './components/RowMenu/RowMenu.js';
47
+ export { Sidebar, useSidebar } from './components/Sidebar.js';
48
+ export type { RailTooltipHandlers, SidebarContextValue, SidebarFooterProps, SidebarMobileHeaderProps, SidebarNavProps, SidebarProps, SidebarRailToggleProps, } from './components/Sidebar.js';
49
+ export { DEFAULT_SIDEBAR_RAIL_STORAGE_KEY, useSidebarRail } from './hooks/use-sidebar-rail.js';
50
+ export type { SidebarRail } from './hooks/use-sidebar-rail.js';
51
+ export { DEFAULT_NAV_SECTIONS_STORAGE_KEY, useNavSections } from './hooks/use-nav-sections.js';
52
+ export type { NavSections, NavSectionState } from './hooks/use-nav-sections.js';
53
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAIH,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACxD,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,OAAO,EAAE,aAAa,EAAE,MAAM,6CAA6C,CAAC;AAC5E,YAAY,EAAE,kBAAkB,EAAE,MAAM,6CAA6C,CAAC;AAEtF,OAAO,EAAE,aAAa,EAAE,MAAM,6CAA6C,CAAC;AAC5E,YAAY,EAAE,kBAAkB,EAAE,MAAM,6CAA6C,CAAC;AAGtF,YAAY,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,mDAAmD,CAAC;AAInH,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAKjF,OAAO,EAAE,qBAAqB,EAAE,MAAM,6DAA6D,CAAC;AACpG,YAAY,EAAE,0BAA0B,EAAE,MAAM,6DAA6D,CAAC;AAE9G,OAAO,EAAE,OAAO,EAAE,MAAM,iCAAiC,CAAC;AAC1D,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAKjF,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAC9D,YAAY,EACV,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,EAClB,wBAAwB,EACxB,eAAe,EACf,YAAY,EACZ,sBAAsB,GACvB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,gCAAgC,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC/F,YAAY,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,gCAAgC,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC/F,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * @file `@jini-ai/admin/react` — the React layer. Presentational primitives the admin shell and its
3
+ * panels are built from.
4
+ *
5
+ * ## What belongs here
6
+ *
7
+ * Components and hooks that are genuinely reusable across hosts. Anything that decides *policy* —
8
+ * which panels exist, what a route means, who may see a section — lives in `/core` and is passed in
9
+ * as data. `Sidebar` is the worked example: it renders an `AdminNavGroup[]` produced by `/core`'s
10
+ * `buildNav`, and has no nav list of its own.
11
+ *
12
+ * ## Styling contract
13
+ *
14
+ * **Every component here is unstyled**, with one narrow exception. Most emit stable class names
15
+ * (`.cms-nav`, `.row-menu-*`, `.confirm-dialog`, `.btn-danger`, `.btn-warning`, `.btn-secondary`,
16
+ * `.visually-hidden`) and ship no CSS whatsoever — the host owns the stylesheet. Inline styles
17
+ * appear only where a value must be measured at runtime — portal coordinates in `Sidebar`'s rail
18
+ * tooltip and `RowMenu`'s popup. `InteractiveHtmlEditor` is the exception: it (transitively, via
19
+ * `@jini-ai/ui/html-editor`, which this file's own `InteractiveHtmlEditor` composes with a
20
+ * Tovu-specific embed-protection predicate) imports GrapesJS's own vendor stylesheet, because it
21
+ * wraps a third-party editor whose chrome does not render without it — see that primitive's file
22
+ * header for why this isn't authored styling the exception undoes.
23
+ *
24
+ * A few behaviors documented in these files assume the host defines a matching rule (for instance
25
+ * that `.visually-hidden` is `position: absolute`, so `ConfirmButton`'s live region does not
26
+ * consume layout). Those assumptions are called out where they are load-bearing.
27
+ *
28
+ * ## Runtime
29
+ *
30
+ * `browser` — `react-dom`'s `createPortal` into `document.body`, `localStorage`, and `window`
31
+ * listeners. Declared as such in `jini.entries`. React and react-dom are optional peers of this
32
+ * package, so a host importing only `/core`, `/browser`, or `/server` never installs them.
33
+ */
34
+ // Shared vocabulary. Lives outside any one component so taking `RowMenu` alone does not imply a
35
+ // dependency on `ConfirmDialog` — see `types.ts`.
36
+ export { resolveTone, toneClassName } from './types.js';
37
+ export { ConfirmButton } from './components/ConfirmButton/ConfirmButton.js';
38
+ export { ConfirmDialog } from './components/ConfirmDialog/ConfirmDialog.js';
39
+ // The list table. Deliberately has no sorting, pagination or row selection — see its file header
40
+ // for the corpus evidence behind each omission.
41
+ export { DataTable } from './components/DataTable.js';
42
+ // Visual click-into-text editing surface for a bespoke HTML document, built on GrapesJS. See its
43
+ // own file header for the styling-contract exception it carries (vendor CSS import) and the
44
+ // embed-placeholder protection it owns.
45
+ export { InteractiveHtmlEditor } from './components/InteractiveHtmlEditor/InteractiveHtmlEditor.js';
46
+ export { RowMenu } from './components/RowMenu/RowMenu.js';
47
+ // Compound: `Sidebar.MobileHeader`, `.Nav`, `.Footer`, `.RailToggle` hang off the root. `useSidebar`
48
+ // is exported so a host's own control (a log-out button, a workspace switcher) can read the rail
49
+ // state and opt into rail tooltips rather than losing that behavior by not being ours.
50
+ export { Sidebar, useSidebar } from './components/Sidebar.js';
51
+ export { DEFAULT_SIDEBAR_RAIL_STORAGE_KEY, useSidebarRail } from './hooks/use-sidebar-rail.js';
52
+ export { DEFAULT_NAV_SECTIONS_STORAGE_KEY, useNavSections } from './hooks/use-nav-sections.js';
53
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,gGAAgG;AAChG,kDAAkD;AAClD,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAGxD,OAAO,EAAE,aAAa,EAAE,MAAM,6CAA6C,CAAC;AAG5E,OAAO,EAAE,aAAa,EAAE,MAAM,6CAA6C,CAAC;AAM5E,iGAAiG;AACjG,gDAAgD;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAGtD,iGAAiG;AACjG,4FAA4F;AAC5F,wCAAwC;AACxC,OAAO,EAAE,qBAAqB,EAAE,MAAM,6DAA6D,CAAC;AAGpG,OAAO,EAAE,OAAO,EAAE,MAAM,iCAAiC,CAAC;AAG1D,qGAAqG;AACrG,iGAAiG;AACjG,uFAAuF;AACvF,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAW9D,OAAO,EAAE,gCAAgC,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAE/F,OAAO,EAAE,gCAAgC,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * @file Vocabulary shared across this layer's components, so picking one does not drag in another.
3
+ *
4
+ * `ConfirmTone` lived in `ConfirmDialog.tsx` and was imported from there by `RowMenu.tsx`. The
5
+ * import was type-only and therefore free at runtime, but it still said something untrue about the
6
+ * package: that a host wanting only a row menu depends on the confirm dialog. In a layer whose
7
+ * whole premise is "take the pieces you need", that is the wrong signal to send.
8
+ */
9
+ /**
10
+ * The three action tiers this vocabulary distinguishes: `"default"` for a neutral action,
11
+ * `"warning"` for reversible-but-access-affecting ones (e.g. Disable), `"danger"` for genuinely
12
+ * destructive ones (e.g. Delete).
13
+ *
14
+ * Deliberately shared between `ConfirmDialog` and `RowMenu`: a caller wiring up "Disable opens
15
+ * nothing, Delete opens a ConfirmDialog" from one item list should not have to reconcile two tone
16
+ * enums to keep the colors matching.
17
+ */
18
+ export type ConfirmTone = 'default' | 'warning' | 'danger';
19
+ /** Maps a tone onto the class name the host stylesheet is expected to define. `"default"` yields
20
+ * `undefined` — the plain button, no class. */
21
+ export declare function toneClassName(tone: ConfirmTone): string | undefined;
22
+ /** `tone` wins when both `tone` and the deprecated `destructive` are passed; `destructive: true`
23
+ * alone still maps to `"danger"` (its only prior meaning) for callers that haven't migrated. */
24
+ export declare function resolveTone(source: {
25
+ tone?: ConfirmTone;
26
+ destructive?: boolean;
27
+ }): ConfirmTone;
28
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/react/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;;;;;GAQG;AACH,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE3D;gDACgD;AAChD,wBAAgB,aAAa,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,GAAG,SAAS,CAInE;AAED;iGACiG;AACjG,wBAAgB,WAAW,CAAC,MAAM,EAAE;IAAE,IAAI,CAAC,EAAE,WAAW,CAAC;IAAC,WAAW,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,WAAW,CAE9F"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * @file Vocabulary shared across this layer's components, so picking one does not drag in another.
3
+ *
4
+ * `ConfirmTone` lived in `ConfirmDialog.tsx` and was imported from there by `RowMenu.tsx`. The
5
+ * import was type-only and therefore free at runtime, but it still said something untrue about the
6
+ * package: that a host wanting only a row menu depends on the confirm dialog. In a layer whose
7
+ * whole premise is "take the pieces you need", that is the wrong signal to send.
8
+ */
9
+ /** Maps a tone onto the class name the host stylesheet is expected to define. `"default"` yields
10
+ * `undefined` — the plain button, no class. */
11
+ export function toneClassName(tone) {
12
+ if (tone === 'danger')
13
+ return 'btn-danger';
14
+ if (tone === 'warning')
15
+ return 'btn-warning';
16
+ return undefined;
17
+ }
18
+ /** `tone` wins when both `tone` and the deprecated `destructive` are passed; `destructive: true`
19
+ * alone still maps to `"danger"` (its only prior meaning) for callers that haven't migrated. */
20
+ export function resolveTone(source) {
21
+ return source.tone ?? (source.destructive ? 'danger' : 'default');
22
+ }
23
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/react/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAaH;gDACgD;AAChD,MAAM,UAAU,aAAa,CAAC,IAAiB;IAC7C,IAAI,IAAI,KAAK,QAAQ;QAAE,OAAO,YAAY,CAAC;IAC3C,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,aAAa,CAAC;IAC7C,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;iGACiG;AACjG,MAAM,UAAU,WAAW,CAAC,MAAqD;IAC/E,OAAO,MAAM,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;AACpE,CAAC"}
@@ -0,0 +1,36 @@
1
+ import type { JsonValue } from '@jini-ai/protocol';
2
+ export declare const COMPOSIO_MAX_RESPONSE_BYTES: number;
3
+ export declare const COMPOSIO_MAX_ERROR_RESPONSE_BYTES: number;
4
+ export declare const COMPOSIO_MAX_CACHE_BYTES: number;
5
+ export declare const COMPOSIO_MAX_SECRET_STORE_BYTES: number;
6
+ export interface JsonStructureLimits {
7
+ maxDepth: number;
8
+ maxNodes: number;
9
+ maxArrayItems: number;
10
+ maxObjectKeys: number;
11
+ maxStringBytes: number;
12
+ }
13
+ export declare const COMPOSIO_REMOTE_JSON_LIMITS: JsonStructureLimits;
14
+ export declare class BoundedDataError extends Error {
15
+ constructor(message: string);
16
+ }
17
+ /** Reads at most `maxBytes` from a response body before allocating/decoding it. */
18
+ export declare function readBoundedResponseText(response: Response, maxBytes: number, label?: string): Promise<string>;
19
+ /** Reads and parses a response body only after its byte size is bounded. */
20
+ export declare function readBoundedResponseJson(response: Response, maxBytes?: number, label?: string): Promise<unknown>;
21
+ /** Reads a local UTF-8 file without allowing it to grow past `maxBytes`. */
22
+ export declare function readBoundedUtf8File(filePath: string, maxBytes: number): string;
23
+ /**
24
+ * Opens a secret-bearing regular file without following its final symlink,
25
+ * enforces owner-only mode on the opened inode, and reads it within a byte cap.
26
+ *
27
+ * @complexity Time: O(n). Space: O(n), where n is capped by `maxBytes`.
28
+ * @overallScore 100/100
29
+ */
30
+ export declare function readPrivateBoundedUtf8File(filePath: string, maxBytes: number): string;
31
+ /**
32
+ * Converts an unknown value into JSON while enforcing depth, node, collection,
33
+ * and string bounds before recursive copies are allocated.
34
+ */
35
+ export declare function toStructurallyBoundedJsonValue(value: unknown, limits?: JsonStructureLimits): JsonValue;
36
+ //# sourceMappingURL=bounded-data.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bounded-data.d.ts","sourceRoot":"","sources":["../../../src/server/composio/bounded-data.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEnD,eAAO,MAAM,2BAA2B,QAAkB,CAAC;AAC3D,eAAO,MAAM,iCAAiC,QAAY,CAAC;AAC3D,eAAO,MAAM,wBAAwB,QAAkB,CAAC;AACxD,eAAO,MAAM,+BAA+B,QAAc,CAAC;AAE3D,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,eAAO,MAAM,2BAA2B,EAAE,mBAMzC,CAAC;AAEF,qBAAa,gBAAiB,SAAQ,KAAK;gBAC7B,OAAO,EAAE,MAAM;CAI5B;AAED,mFAAmF;AACnF,wBAAsB,uBAAuB,CAC3C,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,MAAM,EAChB,KAAK,SAAsB,GAC1B,OAAO,CAAC,MAAM,CAAC,CAoCjB;AAED,4EAA4E;AAC5E,wBAAsB,uBAAuB,CAC3C,QAAQ,EAAE,QAAQ,EAClB,QAAQ,SAA8B,EACtC,KAAK,SAAsB,GAC1B,OAAO,CAAC,OAAO,CAAC,CASlB;AAED,4EAA4E;AAC5E,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAO9E;AAED;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAcrF;AAuBD;;;GAGG;AACH,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,OAAO,EACd,MAAM,GAAE,mBAAiD,GACxD,SAAS,CAyDX"}
@@ -0,0 +1,181 @@
1
+ /**
2
+ * @module bounded-data
3
+ *
4
+ * Size and structural guards for untrusted remote and persisted JSON.
5
+ */
6
+ import fs from 'node:fs';
7
+ export const COMPOSIO_MAX_RESPONSE_BYTES = 8 * 1024 * 1024;
8
+ export const COMPOSIO_MAX_ERROR_RESPONSE_BYTES = 64 * 1024;
9
+ export const COMPOSIO_MAX_CACHE_BYTES = 8 * 1024 * 1024;
10
+ export const COMPOSIO_MAX_SECRET_STORE_BYTES = 1024 * 1024;
11
+ export const COMPOSIO_REMOTE_JSON_LIMITS = {
12
+ maxDepth: 40,
13
+ maxNodes: 50_000,
14
+ maxArrayItems: 10_000,
15
+ maxObjectKeys: 10_000,
16
+ maxStringBytes: 1024 * 1024,
17
+ };
18
+ export class BoundedDataError extends Error {
19
+ constructor(message) {
20
+ super(message);
21
+ this.name = 'BoundedDataError';
22
+ }
23
+ }
24
+ /** Reads at most `maxBytes` from a response body before allocating/decoding it. */
25
+ export async function readBoundedResponseText(response, maxBytes, label = 'Composio response') {
26
+ const declaredLength = response.headers.get('content-length');
27
+ if (declaredLength !== null && /^\d+$/.test(declaredLength)) {
28
+ const bytes = Number(declaredLength);
29
+ if (!Number.isSafeInteger(bytes) || bytes > maxBytes) {
30
+ throw new BoundedDataError(`${label} exceeds the ${maxBytes}-byte limit`);
31
+ }
32
+ }
33
+ if (response.body === null)
34
+ return '';
35
+ const reader = response.body.getReader();
36
+ const chunks = [];
37
+ let totalBytes = 0;
38
+ try {
39
+ while (true) {
40
+ const { done, value } = await reader.read();
41
+ if (done)
42
+ break;
43
+ totalBytes += value.byteLength;
44
+ if (totalBytes > maxBytes) {
45
+ await reader.cancel().catch(() => undefined);
46
+ throw new BoundedDataError(`${label} exceeds the ${maxBytes}-byte limit`);
47
+ }
48
+ chunks.push(value);
49
+ }
50
+ }
51
+ finally {
52
+ reader.releaseLock();
53
+ }
54
+ const bytes = new Uint8Array(totalBytes);
55
+ let offset = 0;
56
+ for (const chunk of chunks) {
57
+ bytes.set(chunk, offset);
58
+ offset += chunk.byteLength;
59
+ }
60
+ return new TextDecoder('utf-8', { fatal: true }).decode(bytes);
61
+ }
62
+ /** Reads and parses a response body only after its byte size is bounded. */
63
+ export async function readBoundedResponseJson(response, maxBytes = COMPOSIO_MAX_RESPONSE_BYTES, label = 'Composio response') {
64
+ const text = await readBoundedResponseText(response, maxBytes, label);
65
+ let parsed;
66
+ try {
67
+ parsed = JSON.parse(text);
68
+ }
69
+ catch {
70
+ throw new BoundedDataError(`${label} is not valid JSON`);
71
+ }
72
+ return toStructurallyBoundedJsonValue(parsed);
73
+ }
74
+ /** Reads a local UTF-8 file without allowing it to grow past `maxBytes`. */
75
+ export function readBoundedUtf8File(filePath, maxBytes) {
76
+ const descriptor = fs.openSync(filePath, 'r');
77
+ try {
78
+ return readBoundedUtf8Descriptor(descriptor, maxBytes);
79
+ }
80
+ finally {
81
+ fs.closeSync(descriptor);
82
+ }
83
+ }
84
+ /**
85
+ * Opens a secret-bearing regular file without following its final symlink,
86
+ * enforces owner-only mode on the opened inode, and reads it within a byte cap.
87
+ *
88
+ * @complexity Time: O(n). Space: O(n), where n is capped by `maxBytes`.
89
+ * @overallScore 100/100
90
+ */
91
+ export function readPrivateBoundedUtf8File(filePath, maxBytes) {
92
+ const descriptor = fs.openSync(filePath, fs.constants.O_RDONLY | fs.constants.O_NOFOLLOW);
93
+ try {
94
+ if (!fs.fstatSync(descriptor).isFile()) {
95
+ throw new BoundedDataError('Secret JSON path must be a regular file');
96
+ }
97
+ fs.fchmodSync(descriptor, 0o600);
98
+ return readBoundedUtf8Descriptor(descriptor, maxBytes);
99
+ }
100
+ finally {
101
+ fs.closeSync(descriptor);
102
+ }
103
+ }
104
+ function readBoundedUtf8Descriptor(descriptor, maxBytes) {
105
+ const chunks = [];
106
+ const buffer = Buffer.allocUnsafe(Math.min(64 * 1024, maxBytes + 1));
107
+ let totalBytes = 0;
108
+ while (true) {
109
+ const bytesRead = fs.readSync(descriptor, buffer, 0, buffer.length, null);
110
+ if (bytesRead === 0)
111
+ break;
112
+ totalBytes += bytesRead;
113
+ if (totalBytes > maxBytes) {
114
+ throw new BoundedDataError(`JSON file exceeds the ${maxBytes}-byte limit`);
115
+ }
116
+ chunks.push(Buffer.from(buffer.subarray(0, bytesRead)));
117
+ }
118
+ return new TextDecoder('utf-8', { fatal: true }).decode(Buffer.concat(chunks, totalBytes));
119
+ }
120
+ /**
121
+ * Converts an unknown value into JSON while enforcing depth, node, collection,
122
+ * and string bounds before recursive copies are allocated.
123
+ */
124
+ export function toStructurallyBoundedJsonValue(value, limits = COMPOSIO_REMOTE_JSON_LIMITS) {
125
+ const state = { nodes: 0, ancestors: new WeakSet() };
126
+ const visit = (current, depth) => {
127
+ state.nodes += 1;
128
+ if (state.nodes > limits.maxNodes) {
129
+ throw new BoundedDataError(`JSON value exceeds the ${limits.maxNodes}-node limit`);
130
+ }
131
+ if (depth > limits.maxDepth) {
132
+ throw new BoundedDataError(`JSON value exceeds the ${limits.maxDepth}-level depth limit`);
133
+ }
134
+ if (current === null || typeof current === 'boolean')
135
+ return current;
136
+ if (typeof current === 'number') {
137
+ if (!Number.isFinite(current))
138
+ throw new BoundedDataError('JSON value contains a non-finite number');
139
+ return current;
140
+ }
141
+ if (typeof current === 'string') {
142
+ if (Buffer.byteLength(current, 'utf8') > limits.maxStringBytes) {
143
+ throw new BoundedDataError(`JSON string exceeds the ${limits.maxStringBytes}-byte limit`);
144
+ }
145
+ return current;
146
+ }
147
+ if (typeof current !== 'object') {
148
+ throw new BoundedDataError('JSON value contains an unsupported runtime value');
149
+ }
150
+ if (state.ancestors.has(current))
151
+ throw new BoundedDataError('JSON value contains a cycle');
152
+ state.ancestors.add(current);
153
+ try {
154
+ if (Array.isArray(current)) {
155
+ if (current.length > limits.maxArrayItems) {
156
+ throw new BoundedDataError(`JSON array exceeds the ${limits.maxArrayItems}-item limit`);
157
+ }
158
+ return current.map((item) => visit(item, depth + 1));
159
+ }
160
+ const entries = Object.entries(current);
161
+ if (entries.length > limits.maxObjectKeys) {
162
+ throw new BoundedDataError(`JSON object exceeds the ${limits.maxObjectKeys}-key limit`);
163
+ }
164
+ const output = {};
165
+ for (const [key, child] of entries) {
166
+ Object.defineProperty(output, key, {
167
+ configurable: true,
168
+ enumerable: true,
169
+ value: visit(child, depth + 1),
170
+ writable: true,
171
+ });
172
+ }
173
+ return output;
174
+ }
175
+ finally {
176
+ state.ancestors.delete(current);
177
+ }
178
+ };
179
+ return visit(value, 0);
180
+ }
181
+ //# sourceMappingURL=bounded-data.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bounded-data.js","sourceRoot":"","sources":["../../../src/server/composio/bounded-data.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,147 @@
1
+ /**
2
+ * @module catalog
3
+ *
4
+ * Product-neutral catalog and safety contracts used by the Composio adapter.
5
+ */
6
+ import type { JsonValue } from '@jini-ai/protocol';
7
+ export type JsonObject = {
8
+ [key: string]: JsonValue;
9
+ };
10
+ export type ConnectorStatus = 'available' | 'connected' | 'error' | 'disabled';
11
+ export type ConnectorToolSideEffect = 'read' | 'write' | 'destructive' | 'unknown';
12
+ export type ConnectorToolApproval = 'auto' | 'confirm' | 'disabled';
13
+ export type ConnectorToolUseCase = string;
14
+ export interface ConnectorToolSafety {
15
+ sideEffect: ConnectorToolSideEffect;
16
+ approval: ConnectorToolApproval;
17
+ reason: string;
18
+ }
19
+ export interface ConnectorToolCuration {
20
+ useCases?: ConnectorToolUseCase[];
21
+ reason?: string;
22
+ }
23
+ export interface ConnectorToolDetail {
24
+ name: string;
25
+ title: string;
26
+ description?: string;
27
+ inputSchemaJson?: JsonObject;
28
+ /** Present when the provider schema cannot be enforced safely. Such tools are never auto-callable. */
29
+ inputSchemaUnsupportedReason?: string | undefined;
30
+ outputSchemaJson?: JsonObject;
31
+ safety: ConnectorToolSafety;
32
+ refreshEligible: boolean;
33
+ curation?: ConnectorToolCuration;
34
+ }
35
+ export interface ConnectorCatalogToolDefinition extends ConnectorToolDetail {
36
+ /** Provider scopes required for this tool. Empty for local/read-only providers. */
37
+ requiredScopes: string[];
38
+ /** Provider-native tool identifier, when different from the package tool name. */
39
+ providerToolId?: string;
40
+ }
41
+ export interface ConnectorDetail {
42
+ id: string;
43
+ name: string;
44
+ provider: string;
45
+ category: string;
46
+ description?: string;
47
+ status: ConnectorStatus;
48
+ accountLabel?: string;
49
+ tools: ConnectorToolDetail[];
50
+ /**
51
+ * Runtime execution allowlist. Subset of `tools`. The agent layer
52
+ * only invokes tools whose names appear here. For Composio
53
+ * connectors hydration may only preserve static tool authority or add an
54
+ * exact package/host-curated provider identifier. Other discovered tools
55
+ * are display-only regardless of provider metadata.
56
+ *
57
+ * Optional in the type only for fixture brevity; daemon-built
58
+ * `ConnectorDetail` payloads always carry it.
59
+ */
60
+ allowedToolNames?: string[];
61
+ /**
62
+ * The hand-curated catalog subset. Stable across hydration: never
63
+ * extended by provider discovery, only ever the static catalog
64
+ * names. This preserves the static catalog baseline for consumers
65
+ * that need that curated subset, but it is not the advertised
66
+ * provider inventory count. UI summary badges should use `toolCount`
67
+ * when present; the drawer's rendered tool rows still come from
68
+ * `tools` directly.
69
+ *
70
+ * Optional in the type only for fixture brevity; daemon-built
71
+ * `ConnectorDetail` payloads always carry it.
72
+ */
73
+ curatedToolNames?: string[];
74
+ toolCount?: number;
75
+ toolsNextCursor?: string;
76
+ toolsHasMore?: boolean;
77
+ featuredToolNames?: string[];
78
+ minimumApproval?: ConnectorToolApproval;
79
+ lastError?: string;
80
+ auth?: ConnectorAuthDetail;
81
+ }
82
+ export interface ConnectorAuthDetail {
83
+ provider: 'local' | 'none' | 'oauth' | 'composio';
84
+ configured: boolean;
85
+ }
86
+ export interface ConnectorCatalogDefinition {
87
+ id: string;
88
+ name: string;
89
+ provider: string;
90
+ category: string;
91
+ description?: string;
92
+ tools: ConnectorCatalogToolDefinition[];
93
+ /** The complete allowlist of callable tool names for this connector. */
94
+ allowedToolNames: string[];
95
+ /**
96
+ * The hand-curated subset of `allowedToolNames` that is fixed at the
97
+ * catalog level — never extended by provider discovery (issue #748).
98
+ * Optional: when omitted, serialized wire details fall back to
99
+ * `allowedToolNames`, which is the right preview subset for
100
+ * non-Composio connectors that don't have a dynamic discovery layer
101
+ * in the first place.
102
+ */
103
+ curatedToolNames?: string[];
104
+ /** Display-only count of provider tools. This may be known before tool schemas are hydrated. */
105
+ toolCount?: number;
106
+ /** Preview pagination state for hydrated tool definitions. Execution code must not rely on partial pages. */
107
+ toolsNextCursor?: string;
108
+ toolsHasMore?: boolean;
109
+ /** How the connector is made available. `none` and `local` connectors require no user OAuth state. */
110
+ authentication: 'local' | 'none' | 'oauth' | 'composio';
111
+ /** Provider toolkit slug used by external connector providers such as Composio. */
112
+ providerConnectorId?: string;
113
+ featuredToolNames?: string[];
114
+ minimumApproval?: ConnectorToolApproval;
115
+ disabled?: boolean;
116
+ }
117
+ export interface ConnectorToolSafetyClassificationInput {
118
+ name: string;
119
+ providerToolId?: string;
120
+ title?: string;
121
+ description?: string;
122
+ requiredScopes?: readonly string[];
123
+ }
124
+ /**
125
+ * Classifies a provider tool conservatively from its name, description, and
126
+ * scopes. Ambiguous tools require confirmation.
127
+ */
128
+ export declare function classifyConnectorToolSafety(input: ConnectorToolSafetyClassificationInput): ConnectorToolSafety;
129
+ /** Returns whether a tool is safe for unattended refresh execution. */
130
+ export declare function isRefreshEligibleConnectorToolSafety(safety: ConnectorToolSafety): boolean;
131
+ /**
132
+ * Builds a catalog tool and derives safety defaults when the caller omitted
133
+ * them.
134
+ *
135
+ * @overallScore 100/100
136
+ */
137
+ export declare function defineConnectorTool(tool: Omit<ConnectorCatalogToolDefinition, 'safety' | 'refreshEligible'> & {
138
+ safety?: ConnectorToolSafety;
139
+ refreshEligible?: boolean;
140
+ }): ConnectorCatalogToolDefinition;
141
+ /**
142
+ * Creates a detached wire detail from a catalog definition.
143
+ *
144
+ * @overallScore 100/100
145
+ */
146
+ export declare function connectorDefinitionToDetail(definition: ConnectorCatalogDefinition): ConnectorDetail;
147
+ //# sourceMappingURL=catalog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../../../src/server/composio/catalog.ts"],"names":[],"mappings":"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"}