@molecule/app-ide-react 1.0.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 (250) hide show
  1. package/LICENSE +115 -0
  2. package/dist/chatTimelineOrdering.d.ts +50 -0
  3. package/dist/chatTimelineOrdering.d.ts.map +1 -0
  4. package/dist/chatTimelineOrdering.js +46 -0
  5. package/dist/chatTimelineOrdering.js.map +1 -0
  6. package/dist/command-metadata.d.ts +78 -0
  7. package/dist/command-metadata.d.ts.map +1 -0
  8. package/dist/command-metadata.js +214 -0
  9. package/dist/command-metadata.js.map +1 -0
  10. package/dist/components/ActivityCard.d.ts +28 -0
  11. package/dist/components/ActivityCard.d.ts.map +1 -0
  12. package/dist/components/ActivityCard.js +62 -0
  13. package/dist/components/ActivityCard.js.map +1 -0
  14. package/dist/components/AutoCommitBadge.d.ts +58 -0
  15. package/dist/components/AutoCommitBadge.d.ts.map +1 -0
  16. package/dist/components/AutoCommitBadge.js +78 -0
  17. package/dist/components/AutoCommitBadge.js.map +1 -0
  18. package/dist/components/ChatPanel.d.ts +184 -0
  19. package/dist/components/ChatPanel.d.ts.map +1 -0
  20. package/dist/components/ChatPanel.js +6691 -0
  21. package/dist/components/ChatPanel.js.map +1 -0
  22. package/dist/components/CommandPalette.d.ts +18 -0
  23. package/dist/components/CommandPalette.d.ts.map +1 -0
  24. package/dist/components/CommandPalette.js +33 -0
  25. package/dist/components/CommandPalette.js.map +1 -0
  26. package/dist/components/DeviceFrameSelector.d.ts +60 -0
  27. package/dist/components/DeviceFrameSelector.d.ts.map +1 -0
  28. package/dist/components/DeviceFrameSelector.js +230 -0
  29. package/dist/components/DeviceFrameSelector.js.map +1 -0
  30. package/dist/components/EditorPanel.d.ts +17 -0
  31. package/dist/components/EditorPanel.d.ts.map +1 -0
  32. package/dist/components/EditorPanel.js +241 -0
  33. package/dist/components/EditorPanel.js.map +1 -0
  34. package/dist/components/FileExplorer.d.ts +64 -0
  35. package/dist/components/FileExplorer.d.ts.map +1 -0
  36. package/dist/components/FileExplorer.js +1111 -0
  37. package/dist/components/FileExplorer.js.map +1 -0
  38. package/dist/components/FileExplorerContextMenu.d.ts +37 -0
  39. package/dist/components/FileExplorerContextMenu.d.ts.map +1 -0
  40. package/dist/components/FileExplorerContextMenu.js +241 -0
  41. package/dist/components/FileExplorerContextMenu.js.map +1 -0
  42. package/dist/components/HelpCard.d.ts +34 -0
  43. package/dist/components/HelpCard.d.ts.map +1 -0
  44. package/dist/components/HelpCard.js +28 -0
  45. package/dist/components/HelpCard.js.map +1 -0
  46. package/dist/components/Icon.d.ts +50 -0
  47. package/dist/components/Icon.d.ts.map +1 -0
  48. package/dist/components/Icon.js +25 -0
  49. package/dist/components/Icon.js.map +1 -0
  50. package/dist/components/KeyboardShortcutsPanel.d.ts +19 -0
  51. package/dist/components/KeyboardShortcutsPanel.d.ts.map +1 -0
  52. package/dist/components/KeyboardShortcutsPanel.js +187 -0
  53. package/dist/components/KeyboardShortcutsPanel.js.map +1 -0
  54. package/dist/components/MarkdownContent.d.ts +52 -0
  55. package/dist/components/MarkdownContent.d.ts.map +1 -0
  56. package/dist/components/MarkdownContent.js +303 -0
  57. package/dist/components/MarkdownContent.js.map +1 -0
  58. package/dist/components/ModelsTable.d.ts +38 -0
  59. package/dist/components/ModelsTable.d.ts.map +1 -0
  60. package/dist/components/ModelsTable.js +96 -0
  61. package/dist/components/ModelsTable.js.map +1 -0
  62. package/dist/components/PreviewPanel.d.ts +66 -0
  63. package/dist/components/PreviewPanel.d.ts.map +1 -0
  64. package/dist/components/PreviewPanel.js +1752 -0
  65. package/dist/components/PreviewPanel.js.map +1 -0
  66. package/dist/components/QuickOpen.d.ts +20 -0
  67. package/dist/components/QuickOpen.d.ts.map +1 -0
  68. package/dist/components/QuickOpen.js +72 -0
  69. package/dist/components/QuickOpen.js.map +1 -0
  70. package/dist/components/QuickPicker.d.ts +21 -0
  71. package/dist/components/QuickPicker.d.ts.map +1 -0
  72. package/dist/components/QuickPicker.js +174 -0
  73. package/dist/components/QuickPicker.js.map +1 -0
  74. package/dist/components/RelevantSkillSuggestion.d.ts +41 -0
  75. package/dist/components/RelevantSkillSuggestion.d.ts.map +1 -0
  76. package/dist/components/RelevantSkillSuggestion.js +85 -0
  77. package/dist/components/RelevantSkillSuggestion.js.map +1 -0
  78. package/dist/components/ReportModal.d.ts +35 -0
  79. package/dist/components/ReportModal.d.ts.map +1 -0
  80. package/dist/components/ReportModal.js +112 -0
  81. package/dist/components/ReportModal.js.map +1 -0
  82. package/dist/components/ResizeHandle.d.ts +21 -0
  83. package/dist/components/ResizeHandle.d.ts.map +1 -0
  84. package/dist/components/ResizeHandle.js +109 -0
  85. package/dist/components/ResizeHandle.js.map +1 -0
  86. package/dist/components/ScriptsCard.d.ts +37 -0
  87. package/dist/components/ScriptsCard.d.ts.map +1 -0
  88. package/dist/components/ScriptsCard.js +177 -0
  89. package/dist/components/ScriptsCard.js.map +1 -0
  90. package/dist/components/SearchPanel.d.ts +18 -0
  91. package/dist/components/SearchPanel.d.ts.map +1 -0
  92. package/dist/components/SearchPanel.js +449 -0
  93. package/dist/components/SearchPanel.js.map +1 -0
  94. package/dist/components/SettingsCard.d.ts +49 -0
  95. package/dist/components/SettingsCard.d.ts.map +1 -0
  96. package/dist/components/SettingsCard.js +59 -0
  97. package/dist/components/SettingsCard.js.map +1 -0
  98. package/dist/components/ShareModal.d.ts +32 -0
  99. package/dist/components/ShareModal.d.ts.map +1 -0
  100. package/dist/components/ShareModal.js +126 -0
  101. package/dist/components/ShareModal.js.map +1 -0
  102. package/dist/components/SidebarTabs.d.ts +18 -0
  103. package/dist/components/SidebarTabs.d.ts.map +1 -0
  104. package/dist/components/SidebarTabs.js +20 -0
  105. package/dist/components/SidebarTabs.js.map +1 -0
  106. package/dist/components/SkillsCard.d.ts +86 -0
  107. package/dist/components/SkillsCard.d.ts.map +1 -0
  108. package/dist/components/SkillsCard.js +227 -0
  109. package/dist/components/SkillsCard.js.map +1 -0
  110. package/dist/components/StreamingIndicator.d.ts +50 -0
  111. package/dist/components/StreamingIndicator.d.ts.map +1 -0
  112. package/dist/components/StreamingIndicator.js +142 -0
  113. package/dist/components/StreamingIndicator.js.map +1 -0
  114. package/dist/components/TabBar.d.ts +37 -0
  115. package/dist/components/TabBar.d.ts.map +1 -0
  116. package/dist/components/TabBar.js +187 -0
  117. package/dist/components/TabBar.js.map +1 -0
  118. package/dist/components/TipCard.d.ts +22 -0
  119. package/dist/components/TipCard.d.ts.map +1 -0
  120. package/dist/components/TipCard.js +73 -0
  121. package/dist/components/TipCard.js.map +1 -0
  122. package/dist/components/ToolCallCard.d.ts +18 -0
  123. package/dist/components/ToolCallCard.d.ts.map +1 -0
  124. package/dist/components/ToolCallCard.js +716 -0
  125. package/dist/components/ToolCallCard.js.map +1 -0
  126. package/dist/components/UserAvatar.d.ts +45 -0
  127. package/dist/components/UserAvatar.d.ts.map +1 -0
  128. package/dist/components/UserAvatar.js +80 -0
  129. package/dist/components/UserAvatar.js.map +1 -0
  130. package/dist/components/WorkspaceLayout.d.ts +19 -0
  131. package/dist/components/WorkspaceLayout.d.ts.map +1 -0
  132. package/dist/components/WorkspaceLayout.js +56 -0
  133. package/dist/components/WorkspaceLayout.js.map +1 -0
  134. package/dist/components/activity-utilities.d.ts +107 -0
  135. package/dist/components/activity-utilities.d.ts.map +1 -0
  136. package/dist/components/activity-utilities.js +154 -0
  137. package/dist/components/activity-utilities.js.map +1 -0
  138. package/dist/components/chat-autocommit-utilities.d.ts +172 -0
  139. package/dist/components/chat-autocommit-utilities.d.ts.map +1 -0
  140. package/dist/components/chat-autocommit-utilities.js +185 -0
  141. package/dist/components/chat-autocommit-utilities.js.map +1 -0
  142. package/dist/components/chat-card-style.d.ts +64 -0
  143. package/dist/components/chat-card-style.d.ts.map +1 -0
  144. package/dist/components/chat-card-style.js +74 -0
  145. package/dist/components/chat-card-style.js.map +1 -0
  146. package/dist/components/chat-commands.d.ts +17 -0
  147. package/dist/components/chat-commands.d.ts.map +1 -0
  148. package/dist/components/chat-commands.js +17 -0
  149. package/dist/components/chat-commands.js.map +1 -0
  150. package/dist/components/chat-commit-utilities.d.ts +29 -0
  151. package/dist/components/chat-commit-utilities.d.ts.map +1 -0
  152. package/dist/components/chat-commit-utilities.js +31 -0
  153. package/dist/components/chat-commit-utilities.js.map +1 -0
  154. package/dist/components/chat-cost-utilities.d.ts +62 -0
  155. package/dist/components/chat-cost-utilities.d.ts.map +1 -0
  156. package/dist/components/chat-cost-utilities.js +66 -0
  157. package/dist/components/chat-cost-utilities.js.map +1 -0
  158. package/dist/components/chat-effort-utilities.d.ts +96 -0
  159. package/dist/components/chat-effort-utilities.d.ts.map +1 -0
  160. package/dist/components/chat-effort-utilities.js +97 -0
  161. package/dist/components/chat-effort-utilities.js.map +1 -0
  162. package/dist/components/chat-help-utilities.d.ts +89 -0
  163. package/dist/components/chat-help-utilities.d.ts.map +1 -0
  164. package/dist/components/chat-help-utilities.js +131 -0
  165. package/dist/components/chat-help-utilities.js.map +1 -0
  166. package/dist/components/chat-model-mode-utilities.d.ts +143 -0
  167. package/dist/components/chat-model-mode-utilities.d.ts.map +1 -0
  168. package/dist/components/chat-model-mode-utilities.js +191 -0
  169. package/dist/components/chat-model-mode-utilities.js.map +1 -0
  170. package/dist/components/chat-models-utilities.d.ts +98 -0
  171. package/dist/components/chat-models-utilities.d.ts.map +1 -0
  172. package/dist/components/chat-models-utilities.js +136 -0
  173. package/dist/components/chat-models-utilities.js.map +1 -0
  174. package/dist/components/chat-report-utilities.d.ts +149 -0
  175. package/dist/components/chat-report-utilities.d.ts.map +1 -0
  176. package/dist/components/chat-report-utilities.js +151 -0
  177. package/dist/components/chat-report-utilities.js.map +1 -0
  178. package/dist/components/chat-scripts-utilities.d.ts +140 -0
  179. package/dist/components/chat-scripts-utilities.d.ts.map +1 -0
  180. package/dist/components/chat-scripts-utilities.js +158 -0
  181. package/dist/components/chat-scripts-utilities.js.map +1 -0
  182. package/dist/components/chat-settings-utilities.d.ts +72 -0
  183. package/dist/components/chat-settings-utilities.d.ts.map +1 -0
  184. package/dist/components/chat-settings-utilities.js +56 -0
  185. package/dist/components/chat-settings-utilities.js.map +1 -0
  186. package/dist/components/chat-share-utilities.d.ts +104 -0
  187. package/dist/components/chat-share-utilities.d.ts.map +1 -0
  188. package/dist/components/chat-share-utilities.js +90 -0
  189. package/dist/components/chat-share-utilities.js.map +1 -0
  190. package/dist/components/chat-skills-utilities.d.ts +242 -0
  191. package/dist/components/chat-skills-utilities.d.ts.map +1 -0
  192. package/dist/components/chat-skills-utilities.js +433 -0
  193. package/dist/components/chat-skills-utilities.js.map +1 -0
  194. package/dist/components/chat-stream-utilities.d.ts +74 -0
  195. package/dist/components/chat-stream-utilities.d.ts.map +1 -0
  196. package/dist/components/chat-stream-utilities.js +103 -0
  197. package/dist/components/chat-stream-utilities.js.map +1 -0
  198. package/dist/components/chat-tips-utilities.d.ts +108 -0
  199. package/dist/components/chat-tips-utilities.d.ts.map +1 -0
  200. package/dist/components/chat-tips-utilities.js +137 -0
  201. package/dist/components/chat-tips-utilities.js.map +1 -0
  202. package/dist/components/device-cycle.d.ts +84 -0
  203. package/dist/components/device-cycle.d.ts.map +1 -0
  204. package/dist/components/device-cycle.js +77 -0
  205. package/dist/components/device-cycle.js.map +1 -0
  206. package/dist/components/index.d.ts +36 -0
  207. package/dist/components/index.d.ts.map +1 -0
  208. package/dist/components/index.js +33 -0
  209. package/dist/components/index.js.map +1 -0
  210. package/dist/components/tool-call-utilities.d.ts +69 -0
  211. package/dist/components/tool-call-utilities.d.ts.map +1 -0
  212. package/dist/components/tool-call-utilities.js +368 -0
  213. package/dist/components/tool-call-utilities.js.map +1 -0
  214. package/dist/components/user-avatar-utilities.d.ts +41 -0
  215. package/dist/components/user-avatar-utilities.d.ts.map +1 -0
  216. package/dist/components/user-avatar-utilities.js +56 -0
  217. package/dist/components/user-avatar-utilities.js.map +1 -0
  218. package/dist/components/workspace-layout-utilities.d.ts +37 -0
  219. package/dist/components/workspace-layout-utilities.d.ts.map +1 -0
  220. package/dist/components/workspace-layout-utilities.js +58 -0
  221. package/dist/components/workspace-layout-utilities.js.map +1 -0
  222. package/dist/customEventCards.d.ts +117 -0
  223. package/dist/customEventCards.d.ts.map +1 -0
  224. package/dist/customEventCards.js +36 -0
  225. package/dist/customEventCards.js.map +1 -0
  226. package/dist/hooks/index.d.ts +8 -0
  227. package/dist/hooks/index.d.ts.map +1 -0
  228. package/dist/hooks/index.js +8 -0
  229. package/dist/hooks/index.js.map +1 -0
  230. package/dist/hooks/useKeyboardShortcuts.d.ts +48 -0
  231. package/dist/hooks/useKeyboardShortcuts.d.ts.map +1 -0
  232. package/dist/hooks/useKeyboardShortcuts.js +112 -0
  233. package/dist/hooks/useKeyboardShortcuts.js.map +1 -0
  234. package/dist/hooks/useViewport.d.ts +42 -0
  235. package/dist/hooks/useViewport.d.ts.map +1 -0
  236. package/dist/hooks/useViewport.js +61 -0
  237. package/dist/hooks/useViewport.js.map +1 -0
  238. package/dist/index.d.ts +75 -0
  239. package/dist/index.d.ts.map +1 -0
  240. package/dist/index.js +74 -0
  241. package/dist/index.js.map +1 -0
  242. package/dist/settings-metadata.d.ts +78 -0
  243. package/dist/settings-metadata.d.ts.map +1 -0
  244. package/dist/settings-metadata.js +131 -0
  245. package/dist/settings-metadata.js.map +1 -0
  246. package/dist/types.d.ts +751 -0
  247. package/dist/types.d.ts.map +1 -0
  248. package/dist/types.js +25 -0
  249. package/dist/types.js.map +1 -0
  250. package/package.json +90 -0
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Pure helpers backing the `/settings` view.
3
+ *
4
+ * The list of user-controllable settings itself now lives in the React-free
5
+ * {@link module:../settings-metadata | settings-metadata} module at the package
6
+ * root — the **single source of truth** that can be imported on either side of
7
+ * the api/app boundary (the IDE `/settings` card here, and the molecule.dev API
8
+ * system prompt's "User-Controllable Settings" section via the package's
9
+ * `./settings-metadata` subpath export). This module adds no settings of its
10
+ * own; it zips that canonical metadata together with the already-formatted,
11
+ * display-ready current values into a flat list of {@link SettingDescriptor}s
12
+ * the React {@link SettingsCard} renders. Splitting the value-binding out of the
13
+ * component lets it be unit tested without rendering, and deriving from the
14
+ * shared metadata is what keeps the settings card and the canonical list (and
15
+ * the command menu) from ever drifting apart — the SYN11 fix.
16
+ *
17
+ * All prose in the metadata is the English default; the {@link SettingsCard}
18
+ * wraps each `label`/`description` in `t('ide.chat.settings.<id>.…', …,
19
+ * { defaultValue })` at render time. The `value` is the already-formatted,
20
+ * display-ready current value supplied by the caller (so dynamic,
21
+ * possibly-localized fragments stay out of this pure layer).
22
+ *
23
+ * @module
24
+ */
25
+ import type { SettingKey, SettingMeta } from '../settings-metadata.js';
26
+ /** Notification-sound mode for a single event (mirrors ChatPanel's `SoundMode`). */
27
+ export type SoundEventMode = 'off' | 'whenNotFocused' | 'always';
28
+ /**
29
+ * A canonical {@link SettingMeta} paired with its display-ready current value —
30
+ * what the `/settings` card renders for one row.
31
+ */
32
+ export type SettingDescriptor = SettingMeta & {
33
+ /** The formatted, display-ready current value (already localized by caller). */
34
+ value: string;
35
+ };
36
+ /**
37
+ * Display-ready current values for the user-controllable settings, keyed by the
38
+ * canonical {@link SettingKey}. The caller resolves these (model labels from the
39
+ * catalog, on/off and mode words via `t()`, the effort label, the sounds summary
40
+ * via {@link summarizeSounds}) so this layer stays pure.
41
+ */
42
+ export type SettingsDisplayValues = Record<SettingKey, string>;
43
+ /**
44
+ * Builds the ordered list of user-controllable agent settings by zipping the
45
+ * canonical {@link SETTINGS} metadata together with the supplied display-ready
46
+ * values, so the `/settings` card always shows the live state AND can never
47
+ * drift from the shared single source of truth.
48
+ *
49
+ * Each `description` may contain the `{{agentName}}` interpolation token; the
50
+ * caller ({@link SettingsCard}) fills it in from the host's agent identity
51
+ * (neutral default: "the assistant") at render time.
52
+ *
53
+ * @param values - Display-ready current values for each setting, keyed by {@link SettingKey}.
54
+ * @returns One {@link SettingDescriptor} per setting in {@link SETTINGS}, in display order.
55
+ */
56
+ export declare function buildSettingsList(values: SettingsDisplayValues): SettingDescriptor[];
57
+ /** Aggregate enabled/total counts for a notification-sounds config. */
58
+ export interface SoundsSummary {
59
+ /** Number of events set to anything other than `'off'`. */
60
+ enabled: number;
61
+ /** Total number of sound events. */
62
+ total: number;
63
+ }
64
+ /**
65
+ * Summarizes a notification-sounds config into enabled/total counts. Pure and
66
+ * deterministic; the component turns the counts into a localized string.
67
+ *
68
+ * @param sounds - Per-event sound modes (event name → mode).
69
+ * @returns The number of enabled events and the total event count.
70
+ */
71
+ export declare function summarizeSounds(sounds: Record<string, SoundEventMode>): SoundsSummary;
72
+ //# sourceMappingURL=chat-settings-utilities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-settings-utilities.d.ts","sourceRoot":"","sources":["../../src/components/chat-settings-utilities.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAGtE,oFAAoF;AACpF,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,gBAAgB,GAAG,QAAQ,CAAA;AAEhE;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG,WAAW,GAAG;IAC5C,gFAAgF;IAChF,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAED;;;;;GAKG;AACH,MAAM,MAAM,qBAAqB,GAAG,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAA;AAE9D;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,qBAAqB,GAAG,iBAAiB,EAAE,CAEpF;AAED,uEAAuE;AACvE,MAAM,WAAW,aAAa;IAC5B,2DAA2D;IAC3D,OAAO,EAAE,MAAM,CAAA;IACf,oCAAoC;IACpC,KAAK,EAAE,MAAM,CAAA;CACd;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,aAAa,CAMrF"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Pure helpers backing the `/settings` view.
3
+ *
4
+ * The list of user-controllable settings itself now lives in the React-free
5
+ * {@link module:../settings-metadata | settings-metadata} module at the package
6
+ * root — the **single source of truth** that can be imported on either side of
7
+ * the api/app boundary (the IDE `/settings` card here, and the molecule.dev API
8
+ * system prompt's "User-Controllable Settings" section via the package's
9
+ * `./settings-metadata` subpath export). This module adds no settings of its
10
+ * own; it zips that canonical metadata together with the already-formatted,
11
+ * display-ready current values into a flat list of {@link SettingDescriptor}s
12
+ * the React {@link SettingsCard} renders. Splitting the value-binding out of the
13
+ * component lets it be unit tested without rendering, and deriving from the
14
+ * shared metadata is what keeps the settings card and the canonical list (and
15
+ * the command menu) from ever drifting apart — the SYN11 fix.
16
+ *
17
+ * All prose in the metadata is the English default; the {@link SettingsCard}
18
+ * wraps each `label`/`description` in `t('ide.chat.settings.<id>.…', …,
19
+ * { defaultValue })` at render time. The `value` is the already-formatted,
20
+ * display-ready current value supplied by the caller (so dynamic,
21
+ * possibly-localized fragments stay out of this pure layer).
22
+ *
23
+ * @module
24
+ */
25
+ import { SETTINGS } from '../settings-metadata.js';
26
+ /**
27
+ * Builds the ordered list of user-controllable agent settings by zipping the
28
+ * canonical {@link SETTINGS} metadata together with the supplied display-ready
29
+ * values, so the `/settings` card always shows the live state AND can never
30
+ * drift from the shared single source of truth.
31
+ *
32
+ * Each `description` may contain the `{{agentName}}` interpolation token; the
33
+ * caller ({@link SettingsCard}) fills it in from the host's agent identity
34
+ * (neutral default: "the assistant") at render time.
35
+ *
36
+ * @param values - Display-ready current values for each setting, keyed by {@link SettingKey}.
37
+ * @returns One {@link SettingDescriptor} per setting in {@link SETTINGS}, in display order.
38
+ */
39
+ export function buildSettingsList(values) {
40
+ return SETTINGS.map((meta) => ({ ...meta, value: values[meta.id] }));
41
+ }
42
+ /**
43
+ * Summarizes a notification-sounds config into enabled/total counts. Pure and
44
+ * deterministic; the component turns the counts into a localized string.
45
+ *
46
+ * @param sounds - Per-event sound modes (event name → mode).
47
+ * @returns The number of enabled events and the total event count.
48
+ */
49
+ export function summarizeSounds(sounds) {
50
+ const modes = Object.values(sounds);
51
+ return {
52
+ enabled: modes.filter((mode) => mode !== 'off').length,
53
+ total: modes.length,
54
+ };
55
+ }
56
+ //# sourceMappingURL=chat-settings-utilities.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-settings-utilities.js","sourceRoot":"","sources":["../../src/components/chat-settings-utilities.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAGH,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAsBlD;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAA6B;IAC7D,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;AACtE,CAAC;AAUD;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,MAAsC;IACpE,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;IACnC,OAAO;QACL,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,MAAM;QACtD,KAAK,EAAE,KAAK,CAAC,MAAM;KACpB,CAAA;AACH,CAAC"}
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Pure helpers backing the `/share <role>` command and the header share button.
3
+ *
4
+ * `/share` creates a public share link for the current project by POSTing
5
+ * `{ role }` to `POST /projects/:projectId/shares`. The backend (wired in the
6
+ * host app) mints a slug-bearing link row and returns it; anyone who opens
7
+ * `GET /share/:slug` is granted that role — a `viewer` link is an
8
+ * unauthenticated read. Roles, least- to most-privileged: viewer, commenter,
9
+ * editor, owner. The default — and the safest — role is `viewer`.
10
+ *
11
+ * These helpers parse the command, validate the role against the shared
12
+ * contract, build the exact POST body, and resolve the copyable public URL from
13
+ * the response. They are deterministic and side-effect free so they can be unit
14
+ * tested without rendering or a backend. The role labels are English defaults
15
+ * the component wraps in `t()` at render.
16
+ *
17
+ * @module
18
+ */
19
+ /**
20
+ * Share roles, ordered least- to most-privileged. Mirrors the
21
+ * `@molecule/api-resource-share` `SHARE_ROLES` contract; duplicated here (rather
22
+ * than imported) because an `app-*` package may not import an `api-*` package
23
+ * across the stack boundary.
24
+ */
25
+ export declare const SHARE_ROLES: readonly ["viewer", "commenter", "editor", "owner"];
26
+ /** A role granted by a share link. */
27
+ export type ShareRole = (typeof SHARE_ROLES)[number];
28
+ /** The default (and safest) role when `/share` is run with no argument. */
29
+ export declare const DEFAULT_SHARE_ROLE: ShareRole;
30
+ /** Short English labels per role (the component wraps these in `t()` at render). */
31
+ export declare const SHARE_ROLE_LABELS: Record<ShareRole, string>;
32
+ /** The `POST /projects/:projectId/shares` request body. */
33
+ export interface SharePayload {
34
+ /** Role granted to anyone who opens the link. */
35
+ role: ShareRole;
36
+ }
37
+ /**
38
+ * The `POST /projects/:projectId/shares` response — the created public link.
39
+ * Mirrors the relevant fields of the `@molecule/api-resource-share` `ShareLink`.
40
+ */
41
+ export interface ShareLinkResult {
42
+ /** The link's unique id (used by the revoke route). */
43
+ id?: string;
44
+ /** Opaque slug embedded in the public URL. */
45
+ slug: string;
46
+ /** The role this link grants. */
47
+ role: ShareRole;
48
+ /**
49
+ * A fully-qualified share URL, when the backend supplies one. Preferred over
50
+ * client-side construction so the canonical origin (e.g. a custom domain)
51
+ * wins over the current page origin.
52
+ */
53
+ url?: string;
54
+ }
55
+ /**
56
+ * The parsed result of a `/share` command:
57
+ *
58
+ * - `create` — POST a link at a valid role (`/share`, defaulting to `viewer`,
59
+ * or `/share <role>` with a recognized role).
60
+ * - `invalid` — an unrecognized role argument was given (the caller shows usage).
61
+ */
62
+ export type ShareCommand = {
63
+ kind: 'create';
64
+ role: ShareRole;
65
+ } | {
66
+ kind: 'invalid';
67
+ arg: string;
68
+ };
69
+ /**
70
+ * Type guard for a valid {@link ShareRole} (case-insensitive callers should
71
+ * lower-case first).
72
+ *
73
+ * @param value - The candidate value.
74
+ * @returns `true` when `value` is one of the {@link SHARE_ROLES}.
75
+ */
76
+ export declare function isShareRole(value: string): value is ShareRole;
77
+ /**
78
+ * Parses a `/share [role]` command. Bare `/share` creates a link at the default
79
+ * `viewer` role; `/share <role>` uses the named role when valid (any case); an
80
+ * unrecognized role is reported as invalid so the caller can show usage. Returns
81
+ * `null` when the input is not the `/share` command.
82
+ *
83
+ * @param input - The raw chat input.
84
+ * @returns The parsed {@link ShareCommand}, or `null`.
85
+ */
86
+ export declare function parseShareCommand(input: string): ShareCommand | null;
87
+ /**
88
+ * Builds the `POST /projects/:projectId/shares` body for a role.
89
+ *
90
+ * @param role - The role to grant (defaults to {@link DEFAULT_SHARE_ROLE}).
91
+ * @returns The normalized share payload.
92
+ */
93
+ export declare function buildSharePayload(role?: ShareRole): SharePayload;
94
+ /**
95
+ * Resolves the copyable public URL for a created share link. Prefers the
96
+ * backend-supplied `url` (canonical origin / custom domain); otherwise builds
97
+ * `<origin>/share/<slug>` from the given origin, tolerating a trailing slash.
98
+ *
99
+ * @param result - The created link from the share endpoint.
100
+ * @param origin - The current page origin (e.g. `window.location.origin`).
101
+ * @returns The absolute, copyable share URL.
102
+ */
103
+ export declare function buildShareUrl(result: ShareLinkResult, origin: string): string;
104
+ //# sourceMappingURL=chat-share-utilities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-share-utilities.d.ts","sourceRoot":"","sources":["../../src/components/chat-share-utilities.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH;;;;;GAKG;AACH,eAAO,MAAM,WAAW,qDAAsD,CAAA;AAE9E,sCAAsC;AACtC,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAA;AAEpD,2EAA2E;AAC3E,eAAO,MAAM,kBAAkB,EAAE,SAAoB,CAAA;AAErD,oFAAoF;AACpF,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAKvD,CAAA;AAED,2DAA2D;AAC3D,MAAM,WAAW,YAAY;IAC3B,iDAAiD;IACjD,IAAI,EAAE,SAAS,CAAA;CAChB;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,uDAAuD;IACvD,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAA;IACZ,iCAAiC;IACjC,IAAI,EAAE,SAAS,CAAA;IACf;;;;OAIG;IACH,GAAG,CAAC,EAAE,MAAM,CAAA;CACb;AAED;;;;;;GAMG;AACH,MAAM,MAAM,YAAY,GAAG;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,SAAS,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAA;AAEjG;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,SAAS,CAE7D;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAQpE;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,GAAE,SAA8B,GAAG,YAAY,CAEpF;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAI7E"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Pure helpers backing the `/share <role>` command and the header share button.
3
+ *
4
+ * `/share` creates a public share link for the current project by POSTing
5
+ * `{ role }` to `POST /projects/:projectId/shares`. The backend (wired in the
6
+ * host app) mints a slug-bearing link row and returns it; anyone who opens
7
+ * `GET /share/:slug` is granted that role — a `viewer` link is an
8
+ * unauthenticated read. Roles, least- to most-privileged: viewer, commenter,
9
+ * editor, owner. The default — and the safest — role is `viewer`.
10
+ *
11
+ * These helpers parse the command, validate the role against the shared
12
+ * contract, build the exact POST body, and resolve the copyable public URL from
13
+ * the response. They are deterministic and side-effect free so they can be unit
14
+ * tested without rendering or a backend. The role labels are English defaults
15
+ * the component wraps in `t()` at render.
16
+ *
17
+ * @module
18
+ */
19
+ /**
20
+ * Share roles, ordered least- to most-privileged. Mirrors the
21
+ * `@molecule/api-resource-share` `SHARE_ROLES` contract; duplicated here (rather
22
+ * than imported) because an `app-*` package may not import an `api-*` package
23
+ * across the stack boundary.
24
+ */
25
+ export const SHARE_ROLES = ['viewer', 'commenter', 'editor', 'owner'];
26
+ /** The default (and safest) role when `/share` is run with no argument. */
27
+ export const DEFAULT_SHARE_ROLE = 'viewer';
28
+ /** Short English labels per role (the component wraps these in `t()` at render). */
29
+ export const SHARE_ROLE_LABELS = {
30
+ viewer: 'Viewer — view only',
31
+ commenter: 'Commenter — view & comment',
32
+ editor: 'Editor — view & edit',
33
+ owner: 'Owner — full access',
34
+ };
35
+ /**
36
+ * Type guard for a valid {@link ShareRole} (case-insensitive callers should
37
+ * lower-case first).
38
+ *
39
+ * @param value - The candidate value.
40
+ * @returns `true` when `value` is one of the {@link SHARE_ROLES}.
41
+ */
42
+ export function isShareRole(value) {
43
+ return SHARE_ROLES.includes(value);
44
+ }
45
+ /**
46
+ * Parses a `/share [role]` command. Bare `/share` creates a link at the default
47
+ * `viewer` role; `/share <role>` uses the named role when valid (any case); an
48
+ * unrecognized role is reported as invalid so the caller can show usage. Returns
49
+ * `null` when the input is not the `/share` command.
50
+ *
51
+ * @param input - The raw chat input.
52
+ * @returns The parsed {@link ShareCommand}, or `null`.
53
+ */
54
+ export function parseShareCommand(input) {
55
+ const match = input.trim().match(/^\/share(?:\s+(.*))?$/i);
56
+ if (!match)
57
+ return null;
58
+ const arg = (match[1] ?? '').trim();
59
+ if (arg === '')
60
+ return { kind: 'create', role: DEFAULT_SHARE_ROLE };
61
+ const lower = arg.toLowerCase();
62
+ if (isShareRole(lower))
63
+ return { kind: 'create', role: lower };
64
+ return { kind: 'invalid', arg };
65
+ }
66
+ /**
67
+ * Builds the `POST /projects/:projectId/shares` body for a role.
68
+ *
69
+ * @param role - The role to grant (defaults to {@link DEFAULT_SHARE_ROLE}).
70
+ * @returns The normalized share payload.
71
+ */
72
+ export function buildSharePayload(role = DEFAULT_SHARE_ROLE) {
73
+ return { role };
74
+ }
75
+ /**
76
+ * Resolves the copyable public URL for a created share link. Prefers the
77
+ * backend-supplied `url` (canonical origin / custom domain); otherwise builds
78
+ * `<origin>/share/<slug>` from the given origin, tolerating a trailing slash.
79
+ *
80
+ * @param result - The created link from the share endpoint.
81
+ * @param origin - The current page origin (e.g. `window.location.origin`).
82
+ * @returns The absolute, copyable share URL.
83
+ */
84
+ export function buildShareUrl(result, origin) {
85
+ if (result.url)
86
+ return result.url;
87
+ const trimmedOrigin = origin.replace(/\/+$/, '');
88
+ return `${trimmedOrigin}/share/${result.slug}`;
89
+ }
90
+ //# sourceMappingURL=chat-share-utilities.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-share-utilities.js","sourceRoot":"","sources":["../../src/components/chat-share-utilities.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,CAAU,CAAA;AAK9E,2EAA2E;AAC3E,MAAM,CAAC,MAAM,kBAAkB,GAAc,QAAQ,CAAA;AAErD,oFAAoF;AACpF,MAAM,CAAC,MAAM,iBAAiB,GAA8B;IAC1D,MAAM,EAAE,oBAAoB;IAC5B,SAAS,EAAE,4BAA4B;IACvC,MAAM,EAAE,sBAAsB;IAC9B,KAAK,EAAE,qBAAqB;CAC7B,CAAA;AAoCD;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,OAAQ,WAAiC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;AAC3D,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAa;IAC7C,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAA;IAC1D,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAA;IACvB,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;IACnC,IAAI,GAAG,KAAK,EAAE;QAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAA;IACnE,MAAM,KAAK,GAAG,GAAG,CAAC,WAAW,EAAE,CAAA;IAC/B,IAAI,WAAW,CAAC,KAAK,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,CAAA;IAC9D,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,CAAA;AACjC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAkB,kBAAkB;IACpE,OAAO,EAAE,IAAI,EAAE,CAAA;AACjB,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,aAAa,CAAC,MAAuB,EAAE,MAAc;IACnE,IAAI,MAAM,CAAC,GAAG;QAAE,OAAO,MAAM,CAAC,GAAG,CAAA;IACjC,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;IAChD,OAAO,GAAG,aAAa,UAAU,MAAM,CAAC,IAAI,EAAE,CAAA;AAChD,CAAC"}
@@ -0,0 +1,242 @@
1
+ /**
2
+ * Pure helpers backing the `/skills` browser and the proactive "Relevant skill"
3
+ * suggestion.
4
+ *
5
+ * Following the 2026 Agent Skills folder convention, a skill is a *directory*
6
+ * under the project's `.agents/skills/` tree whose entry file is `SKILL.md`
7
+ * (e.g. `.agents/skills/auth/SKILL.md`), carrying a YAML frontmatter block that
8
+ * declares `name` and `description`. Discovery deliberately matches ONLY those
9
+ * `SKILL.md` entry files — loose Markdown fragments under `patterns/` and the
10
+ * `examples/` reference corpus are scaffold support material, NOT user-facing
11
+ * skills, so surfacing them would bury the real skills (the bug this convention
12
+ * fixes). These helpers discover skill files via the SAME file-list /
13
+ * file-content API the chat already uses for `@`-mentions (injected as
14
+ * functions so this layer stays decoupled from any HTTP client), parse each
15
+ * skill's metadata, filter the list by a query, and run a lightweight relevance
16
+ * pass over recent messages so the most relevant skill can be offered with a
17
+ * one-click load.
18
+ *
19
+ * All functions here are deterministic and side-effect free (apart from the
20
+ * caller-supplied fetchers in {@link loadProjectSkills}), so they can be unit
21
+ * tested without rendering or a real backend.
22
+ *
23
+ * @module
24
+ */
25
+ /** A discovered project skill. */
26
+ export interface SkillInfo {
27
+ /** Relative path within the project, e.g. `'.agents/skills/patterns/styling.md'` (no leading slash). */
28
+ path: string;
29
+ /** Display name (frontmatter `name`, else first heading, else path-derived). */
30
+ name: string;
31
+ /** One-line description (frontmatter `description`, else first paragraph). */
32
+ description: string;
33
+ }
34
+ /**
35
+ * Normalizes a file path returned by the file-list API into a project-relative
36
+ * path: strips a leading `/workspace/` and any leading slash.
37
+ *
38
+ * @param path - The raw file path.
39
+ * @returns The project-relative path.
40
+ */
41
+ export declare function toRelativePath(path: string): string;
42
+ /**
43
+ * Whether a path points at a skill's entry file under the 2026 Agent Skills
44
+ * folder convention: a `SKILL.md` directly inside a skill directory under
45
+ * `.agents/skills/` (i.e. `.agents/skills/<name>/SKILL.md`). Loose `*.md`
46
+ * fragments and the reserved `patterns/` + `examples/` support trees are NOT
47
+ * skills and return `false`. Tolerant of `/workspace/`-prefixed or
48
+ * leading-slash paths.
49
+ *
50
+ * @param path - The file path to test.
51
+ * @returns `true` if the path is a skill's `SKILL.md` entry file.
52
+ */
53
+ export declare function isSkillFile(path: string): boolean;
54
+ /**
55
+ * Derives a fallback skill name from its path: the filename without extension,
56
+ * or — for the conventional `SKILL.md`/`INDEX.md` entry files — the parent
57
+ * directory name (which names the skill).
58
+ *
59
+ * @param path - The skill file's relative path.
60
+ * @returns A human-ish name derived from the path.
61
+ */
62
+ export declare function deriveSkillNameFromPath(path: string): string;
63
+ /**
64
+ * Slugifies a skill display name into a filesystem-safe directory name for its
65
+ * folder under `.agents/skills/`: lowercased, with every run of non-alphanumeric
66
+ * characters collapsed to a single hyphen and surrounding hyphens trimmed. Falls
67
+ * back to `'new-skill'` when the name has no usable characters, so the derived
68
+ * path is always valid.
69
+ *
70
+ * @param name - The skill's display name.
71
+ * @returns A safe directory slug for the skill.
72
+ */
73
+ export declare function slugifySkillName(name: string): string;
74
+ /**
75
+ * The project-relative path of a new skill's entry file under the 2026 Agent
76
+ * Skills folder convention: `.agents/skills/<slug>/SKILL.md` (no leading slash),
77
+ * where `<slug>` is {@link slugifySkillName} of the display name. The result is
78
+ * exactly the shape {@link isSkillFile} recognizes, so a freshly created skill is
79
+ * immediately discoverable by the same `/skills` browser.
80
+ *
81
+ * @param name - The skill's display name.
82
+ * @returns The new skill's `SKILL.md` relative path.
83
+ */
84
+ export declare function newSkillPath(name: string): string;
85
+ /**
86
+ * Builds the starter `SKILL.md` content for a new skill: a YAML frontmatter
87
+ * block declaring the `name` and a `description` placeholder (so the skill shows
88
+ * up — with a clear "edit me" hint — in the `/skills` browser right away),
89
+ * followed by a short authoring scaffold. The content round-trips through
90
+ * {@link parseSkillMeta} (the same parser discovery uses), so a created skill's
91
+ * metadata is identical whether read from this template or re-discovered on disk.
92
+ *
93
+ * @param name - The skill's display name (used verbatim as the frontmatter `name`).
94
+ * @returns The `SKILL.md` file content for a new skill.
95
+ */
96
+ export declare function buildNewSkillTemplate(name: string): string;
97
+ /**
98
+ * Extracts a skill's display name and description from its content. Prefers the
99
+ * frontmatter `name`/`description`; falls back to the first Markdown heading
100
+ * for the name and the first non-empty body paragraph for the description, and
101
+ * finally to a path-derived name.
102
+ *
103
+ * @param path - The skill file's relative path (used for the name fallback).
104
+ * @param content - The raw file content (may be empty if it couldn't be read).
105
+ * @returns The resolved `name` and `description`.
106
+ */
107
+ export declare function parseSkillMeta(path: string, content: string): {
108
+ name: string;
109
+ description: string;
110
+ };
111
+ /**
112
+ * Filters skills by a free-text query, matching (case-insensitively) against
113
+ * the name, description, and path. An empty/blank query returns all skills.
114
+ *
115
+ * @param skills - The skills to filter.
116
+ * @param query - The search query.
117
+ * @returns The matching skills, in input order.
118
+ */
119
+ export declare function filterSkills(skills: readonly SkillInfo[], query: string): SkillInfo[];
120
+ /**
121
+ * Discovers and loads every project skill. Uses the injected `fetchList` to get
122
+ * the project's file paths, keeps the ones under `.agents/skills/`, reads each
123
+ * via `fetchContent`, parses its metadata, and returns the list sorted by name.
124
+ *
125
+ * The fetchers are injected (rather than importing an HTTP client) so this stays
126
+ * decoupled and unit-testable. A single unreadable skill file is tolerated: it
127
+ * still appears with a path-derived name and no description.
128
+ *
129
+ * @param fetchList - Returns all project file paths.
130
+ * @param fetchContent - Returns the content of one skill file by relative path.
131
+ * @returns The discovered skills, sorted by display name.
132
+ */
133
+ export declare function loadProjectSkills(fetchList: () => Promise<string[]>, fetchContent: (relativePath: string) => Promise<string>): Promise<SkillInfo[]>;
134
+ /** Outcome of one {@link loadProjectSkillsResilient} attempt, used to drive the UI. */
135
+ export interface ResilientSkillsLoad {
136
+ /** The discovered skills (possibly empty if the sandbox is genuinely skill-less). */
137
+ skills: SkillInfo[];
138
+ /**
139
+ * `true` when every attempt came back with zero skill files (the sandbox is
140
+ * almost certainly still scaffolding `.agents/skills/`), so the UI should show
141
+ * a "waiting for the sandbox" state rather than a definitive "no skills" one.
142
+ */
143
+ stillBooting: boolean;
144
+ }
145
+ /**
146
+ * Loads project skills with bounded retry, for the window where a sandbox has
147
+ * booted far enough to answer the file-list call but has NOT yet materialized
148
+ * its `.agents/skills/` tree.
149
+ *
150
+ * The server announces "Loaded N skills" from a static, always-available source
151
+ * (its baked-in built-in skill set); the `/skills` browser reads the LIVE
152
+ * sandbox file list, which is empty until scaffolding finishes. Clicking the
153
+ * announce card during that gap previously hit a
154
+ * permanent "No skills found" dead-end. Because a ready sandbox effectively
155
+ * always has the built-in skills scaffolded, "zero skill files" (or a transient
156
+ * fetch error) is treated as "still booting" and retried a bounded number of
157
+ * times before settling — so the skills appear on their own once ready, with an
158
+ * honest waiting state in between instead of a misleading empty one.
159
+ *
160
+ * @param fetchList - Returns all project file paths.
161
+ * @param fetchContent - Returns the content of one skill file by relative path.
162
+ * @param options - Retry tuning + injectables for cancellation and tests.
163
+ * @param options.attempts - Total tries before settling. Defaults to 10.
164
+ * @param options.delayMs - Delay between tries, in ms. Defaults to 2000.
165
+ * @param options.sleep - Awaitable delay (injected in tests). Defaults to `setTimeout`.
166
+ * @param options.isCancelled - Bail-out predicate (e.g. the card was closed).
167
+ * @param options.onRetry - Invoked before each retry sleep (e.g. to show "waiting").
168
+ * @returns The discovered skills plus whether the sandbox still looks like it's booting.
169
+ */
170
+ export declare function loadProjectSkillsResilient(fetchList: () => Promise<string[]>, fetchContent: (relativePath: string) => Promise<string>, options?: {
171
+ attempts?: number;
172
+ delayMs?: number;
173
+ sleep?: (ms: number) => Promise<void>;
174
+ isCancelled?: () => boolean;
175
+ onRetry?: () => void;
176
+ }): Promise<ResilientSkillsLoad>;
177
+ /** A skill the relevance pass judged relevant to the recent conversation. */
178
+ export interface SkillSuggestion {
179
+ /** The relevant skill. */
180
+ skill: SkillInfo;
181
+ /** Relevance score (higher = more relevant); name matches weigh heavier. */
182
+ score: number;
183
+ }
184
+ /**
185
+ * Joins the text of the most recent USER messages into a single relevance
186
+ * signal. Assistant/system turns are excluded so the suggestion tracks what the
187
+ * user is actually asking for, not the agent's own verbiage.
188
+ *
189
+ * @param messages - Conversation messages (newest last), each with a `role` and `content`.
190
+ * @param count - How many trailing user messages to include. Defaults to 3.
191
+ * @returns The concatenated text of the recent user messages.
192
+ */
193
+ export declare function recentUserText(messages: ReadonlyArray<{
194
+ role: string;
195
+ content: string;
196
+ }>, count?: number): string;
197
+ /**
198
+ * Runs a lightweight relevance pass: scores each skill by how many of its
199
+ * name/description keywords appear in `recentText` (name matches weigh heavier),
200
+ * and returns the top matches above a minimum score. Deterministic and
201
+ * side-effect free, so the caller can recompute it as the conversation grows.
202
+ *
203
+ * @param skills - The candidate skills (already excluding loaded/dismissed ones).
204
+ * @param recentText - Recent conversation text (see {@link recentUserText}).
205
+ * @param options - Tuning: `max` results (default 1) and `minScore` threshold (default 2).
206
+ * @param options.max - Maximum number of suggestions to return.
207
+ * @param options.minScore - Minimum score a skill must reach to be suggested.
208
+ * @returns The most relevant skills, highest score first (ties broken by name).
209
+ */
210
+ export declare function suggestRelevantSkills(skills: readonly SkillInfo[], recentText: string, options?: {
211
+ max?: number;
212
+ minScore?: number;
213
+ }): SkillSuggestion[];
214
+ /**
215
+ * The single skill to NUDGE the user to load for the current conversation, or null when there's
216
+ * nothing useful to suggest. Picks the genuine top match for `recentText` (via
217
+ * {@link suggestRelevantSkills}) from the candidate pool — all skills minus the ones the user
218
+ * dismissed or already @-attached — then returns null if that top match is ALREADY LOADED:
219
+ * either @-loaded this session (`loaded`) OR default-loaded (`defaultLoaded`, its full body
220
+ * always-on in the system prompt). Suggesting an already-loaded skill just points at context
221
+ * the agent already has, so we never do it; for a fresh project where every skill is
222
+ * default-loaded the tip simply never fires. We null the top match (rather than dropping loaded
223
+ * skills from the pool) so the next-best doesn't immediately pop up — the tip changes only when
224
+ * the conversation produces a genuinely different top match, never just because the last one got
225
+ * loaded (the "suggests one after another" parade the user reported).
226
+ *
227
+ * @param skills - All discovered project skills.
228
+ * @param recentText - Recent user text to match against.
229
+ * @param sets - Exclusion sets, all keyed by skill `path`.
230
+ * @param sets.dismissed - Skills the user dismissed.
231
+ * @param sets.attachedPaths - Already-@-attached file paths (leading-slash form, matched against `'/' + skill.path`).
232
+ * @param sets.loaded - Skills @-loaded this session.
233
+ * @param sets.defaultLoaded - Default-loaded skills (always-on in the prompt).
234
+ * @returns The skill to suggest, or null.
235
+ */
236
+ export declare function pickRelevantSkill(skills: readonly SkillInfo[], recentText: string, sets: {
237
+ dismissed: ReadonlySet<string>;
238
+ attachedPaths: ReadonlySet<string>;
239
+ loaded: ReadonlySet<string>;
240
+ defaultLoaded: ReadonlySet<string>;
241
+ }): SkillInfo | null;
242
+ //# sourceMappingURL=chat-skills-utilities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-skills-utilities.d.ts","sourceRoot":"","sources":["../../src/components/chat-skills-utilities.ts"],"names":[],"mappings":"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"}