@sero-ai/ui 0.3.2 → 0.4.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 (190) hide show
  1. package/.turbo/turbo-build.log +628 -0
  2. package/.turbo/turbo-typecheck.log +1 -1
  3. package/CHANGELOG.md +38 -0
  4. package/dist/components/context-editor/CapabilitySection.cjs +57 -0
  5. package/dist/components/context-editor/CapabilitySection.d.cts +20 -0
  6. package/dist/components/context-editor/CapabilitySection.d.ts +20 -0
  7. package/dist/components/context-editor/CapabilitySection.js +57 -0
  8. package/dist/components/context-editor/ContextEditor.cjs +108 -0
  9. package/dist/components/context-editor/ContextEditor.d.cts +26 -0
  10. package/dist/components/context-editor/ContextEditor.d.ts +26 -0
  11. package/dist/components/context-editor/ContextEditor.js +108 -0
  12. package/dist/components/context-editor/PresetBar.cjs +71 -0
  13. package/dist/components/context-editor/PresetBar.d.cts +19 -0
  14. package/dist/components/context-editor/PresetBar.d.ts +19 -0
  15. package/dist/components/context-editor/PresetBar.js +71 -0
  16. package/dist/components/context-editor/SkillsSection.cjs +31 -0
  17. package/dist/components/context-editor/SkillsSection.d.cts +14 -0
  18. package/dist/components/context-editor/SkillsSection.d.ts +14 -0
  19. package/dist/components/context-editor/SkillsSection.js +31 -0
  20. package/dist/components/context-editor/SystemPromptSection.cjs +58 -0
  21. package/dist/components/context-editor/SystemPromptSection.d.cts +25 -0
  22. package/dist/components/context-editor/SystemPromptSection.d.ts +25 -0
  23. package/dist/components/context-editor/SystemPromptSection.js +58 -0
  24. package/dist/components/context-editor/ToolsSection.cjs +31 -0
  25. package/dist/components/context-editor/ToolsSection.d.cts +14 -0
  26. package/dist/components/context-editor/ToolsSection.d.ts +14 -0
  27. package/dist/components/context-editor/ToolsSection.js +31 -0
  28. package/dist/components/context-editor/index.cjs +8 -0
  29. package/dist/components/context-editor/index.d.cts +5 -0
  30. package/dist/components/context-editor/index.d.ts +5 -0
  31. package/dist/components/context-editor/index.js +8 -0
  32. package/dist/components/context-editor/parts.cjs +184 -0
  33. package/dist/components/context-editor/parts.d.cts +32 -0
  34. package/dist/components/context-editor/parts.d.ts +32 -0
  35. package/dist/components/context-editor/parts.js +184 -0
  36. package/dist/components/context-editor/use-context-editor-model.cjs +194 -0
  37. package/dist/components/context-editor/use-context-editor-model.d.cts +57 -0
  38. package/dist/components/context-editor/use-context-editor-model.d.ts +57 -0
  39. package/dist/components/context-editor/use-context-editor-model.js +194 -0
  40. package/dist/components/dashboard/activity-list.cjs +59 -0
  41. package/dist/components/dashboard/activity-list.d.cts +27 -0
  42. package/dist/components/dashboard/activity-list.d.ts +27 -0
  43. package/dist/components/dashboard/activity-list.js +59 -0
  44. package/dist/components/dashboard/catalog.cjs +322 -0
  45. package/dist/components/dashboard/catalog.d.cts +14 -0
  46. package/dist/components/dashboard/catalog.d.ts +14 -0
  47. package/dist/components/dashboard/catalog.js +322 -0
  48. package/dist/components/dashboard/data-boundary.cjs +29 -0
  49. package/dist/components/dashboard/data-boundary.d.cts +21 -0
  50. package/dist/components/dashboard/data-boundary.d.ts +21 -0
  51. package/dist/components/dashboard/data-boundary.js +29 -0
  52. package/dist/components/dashboard/empty-state.cjs +49 -0
  53. package/dist/components/dashboard/empty-state.d.cts +20 -0
  54. package/dist/components/dashboard/empty-state.d.ts +20 -0
  55. package/dist/components/dashboard/empty-state.js +49 -0
  56. package/dist/components/dashboard/icon-button.cjs +40 -0
  57. package/dist/components/dashboard/icon-button.d.cts +24 -0
  58. package/dist/components/dashboard/icon-button.d.ts +24 -0
  59. package/dist/components/dashboard/icon-button.js +40 -0
  60. package/dist/components/dashboard/index.cjs +15 -0
  61. package/dist/components/dashboard/index.d.cts +24 -0
  62. package/dist/components/dashboard/index.d.ts +24 -0
  63. package/dist/components/dashboard/index.js +15 -0
  64. package/dist/components/dashboard/item-list.cjs +71 -0
  65. package/dist/components/dashboard/item-list.d.cts +28 -0
  66. package/dist/components/dashboard/item-list.d.ts +28 -0
  67. package/dist/components/dashboard/item-list.js +71 -0
  68. package/dist/components/dashboard/key-value.cjs +39 -0
  69. package/dist/components/dashboard/key-value.d.cts +17 -0
  70. package/dist/components/dashboard/key-value.d.ts +17 -0
  71. package/dist/components/dashboard/key-value.js +39 -0
  72. package/dist/components/dashboard/layout.cjs +193 -0
  73. package/dist/components/dashboard/layout.d.cts +91 -0
  74. package/dist/components/dashboard/layout.d.ts +91 -0
  75. package/dist/components/dashboard/layout.js +193 -0
  76. package/dist/components/dashboard/metric.cjs +98 -0
  77. package/dist/components/dashboard/metric.d.cts +44 -0
  78. package/dist/components/dashboard/metric.d.ts +44 -0
  79. package/dist/components/dashboard/metric.js +98 -0
  80. package/dist/components/dashboard/progress-ring.cjs +77 -0
  81. package/dist/components/dashboard/progress-ring.d.cts +25 -0
  82. package/dist/components/dashboard/progress-ring.d.ts +25 -0
  83. package/dist/components/dashboard/progress-ring.js +77 -0
  84. package/dist/components/dashboard/skeletons.cjs +54 -0
  85. package/dist/components/dashboard/skeletons.d.cts +15 -0
  86. package/dist/components/dashboard/skeletons.d.ts +15 -0
  87. package/dist/components/dashboard/skeletons.js +54 -0
  88. package/dist/components/dashboard/spacing.cjs +10 -0
  89. package/dist/components/dashboard/spacing.d.cts +4 -0
  90. package/dist/components/dashboard/spacing.d.ts +4 -0
  91. package/dist/components/dashboard/spacing.js +10 -0
  92. package/dist/components/dashboard/stale-indicator.cjs +42 -0
  93. package/dist/components/dashboard/stale-indicator.d.cts +15 -0
  94. package/dist/components/dashboard/stale-indicator.d.ts +15 -0
  95. package/dist/components/dashboard/stale-indicator.js +42 -0
  96. package/dist/components/dashboard/status.cjs +62 -0
  97. package/dist/components/dashboard/status.d.cts +15 -0
  98. package/dist/components/dashboard/status.d.ts +15 -0
  99. package/dist/components/dashboard/status.js +62 -0
  100. package/dist/components/dashboard/tone.cjs +26 -0
  101. package/dist/components/dashboard/tone.d.cts +9 -0
  102. package/dist/components/dashboard/tone.d.ts +9 -0
  103. package/dist/components/dashboard/tone.js +26 -0
  104. package/dist/components/dashboard/typography.cjs +99 -0
  105. package/dist/components/dashboard/typography.d.cts +57 -0
  106. package/dist/components/dashboard/typography.d.ts +57 -0
  107. package/dist/components/dashboard/typography.js +99 -0
  108. package/dist/components/reference/ActivityExample.cjs +47 -0
  109. package/dist/components/reference/ActivityExample.d.cts +5 -0
  110. package/dist/components/reference/ActivityExample.d.ts +5 -0
  111. package/dist/components/reference/ActivityExample.js +47 -0
  112. package/dist/components/reference/ResourceExample.cjs +54 -0
  113. package/dist/components/reference/ResourceExample.d.cts +5 -0
  114. package/dist/components/reference/ResourceExample.d.ts +5 -0
  115. package/dist/components/reference/ResourceExample.js +54 -0
  116. package/dist/components/reference/SchedulerExample.cjs +68 -0
  117. package/dist/components/reference/SchedulerExample.d.cts +5 -0
  118. package/dist/components/reference/SchedulerExample.d.ts +5 -0
  119. package/dist/components/reference/SchedulerExample.js +68 -0
  120. package/dist/components/reference/StarterExample.cjs +34 -0
  121. package/dist/components/reference/StarterExample.d.cts +5 -0
  122. package/dist/components/reference/StarterExample.d.ts +5 -0
  123. package/dist/components/reference/StarterExample.js +34 -0
  124. package/dist/components/reference/index.cjs +10 -0
  125. package/dist/components/reference/index.d.cts +5 -0
  126. package/dist/components/reference/index.d.ts +5 -0
  127. package/dist/components/reference/index.js +10 -0
  128. package/dist/components/ui/badge.cjs +5 -1
  129. package/dist/components/ui/badge.d.cts +1 -1
  130. package/dist/components/ui/badge.d.ts +1 -1
  131. package/dist/components/ui/badge.js +5 -1
  132. package/dist/dashboard-catalog.cjs +8 -0
  133. package/dist/dashboard-catalog.d.cts +1 -0
  134. package/dist/dashboard-catalog.d.ts +1 -0
  135. package/dist/dashboard-catalog.js +8 -0
  136. package/dist/index.cjs +1 -0
  137. package/dist/index.d.cts +15 -0
  138. package/dist/index.d.ts +15 -0
  139. package/dist/index.js +1 -0
  140. package/dist/reference.cjs +12 -0
  141. package/dist/reference.d.cts +5 -0
  142. package/dist/reference.d.ts +5 -0
  143. package/dist/reference.js +12 -0
  144. package/dist/styles/glass-board.css +43 -0
  145. package/dist/styles/globals.css +59 -0
  146. package/package.json +70 -41
  147. package/src/components/context-editor/CapabilitySection.tsx +85 -0
  148. package/src/components/context-editor/ContextEditor.tsx +138 -0
  149. package/src/components/context-editor/PresetBar.tsx +94 -0
  150. package/src/components/context-editor/SkillsSection.tsx +37 -0
  151. package/src/components/context-editor/SystemPromptSection.tsx +88 -0
  152. package/src/components/context-editor/ToolsSection.tsx +37 -0
  153. package/src/components/context-editor/index.ts +7 -0
  154. package/src/components/context-editor/parts.tsx +217 -0
  155. package/src/components/context-editor/use-context-editor-model.ts +296 -0
  156. package/src/components/dashboard/__tests__/catalog.test.ts +57 -0
  157. package/src/components/dashboard/__tests__/glass.test.tsx +42 -0
  158. package/src/components/dashboard/__tests__/state.test.tsx +110 -0
  159. package/src/components/dashboard/__tests__/variants.test.tsx +95 -0
  160. package/src/components/dashboard/activity-list.tsx +99 -0
  161. package/src/components/dashboard/catalog.ts +351 -0
  162. package/src/components/dashboard/data-boundary.tsx +54 -0
  163. package/src/components/dashboard/empty-state.tsx +70 -0
  164. package/src/components/dashboard/icon-button.tsx +58 -0
  165. package/src/components/dashboard/index.ts +21 -0
  166. package/src/components/dashboard/item-list.tsx +106 -0
  167. package/src/components/dashboard/key-value.tsx +54 -0
  168. package/src/components/dashboard/layout.tsx +286 -0
  169. package/src/components/dashboard/metric.tsx +139 -0
  170. package/src/components/dashboard/progress-ring.tsx +100 -0
  171. package/src/components/dashboard/skeletons.tsx +73 -0
  172. package/src/components/dashboard/spacing.ts +14 -0
  173. package/src/components/dashboard/stale-indicator.tsx +55 -0
  174. package/src/components/dashboard/status.tsx +75 -0
  175. package/src/components/dashboard/tone.ts +35 -0
  176. package/src/components/dashboard/typography.tsx +151 -0
  177. package/src/components/reference/ActivityExample.tsx +68 -0
  178. package/src/components/reference/ResourceExample.tsx +78 -0
  179. package/src/components/reference/SchedulerExample.tsx +88 -0
  180. package/src/components/reference/StarterExample.tsx +48 -0
  181. package/src/components/reference/index.ts +10 -0
  182. package/src/components/ui/badge.tsx +6 -0
  183. package/src/dashboard-catalog.ts +13 -0
  184. package/src/index.ts +5 -0
  185. package/src/reference.ts +15 -0
  186. package/src/styles/glass-board.css +43 -0
  187. package/src/styles/globals.css +59 -0
  188. package/tsup.config.ts +6 -2
  189. package/vitest.config.ts +8 -0
  190. package/LICENSE +0 -201
@@ -0,0 +1,184 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import { AnimatePresence, motion } from "motion/react";
4
+ import { ChevronRight } from "lucide-react";
5
+ import { cn } from "../../lib/utils";
6
+ import { Switch } from "../ui/switch";
7
+ const iconTintClass = {
8
+ blue: "text-status-info",
9
+ amber: "text-status-warning",
10
+ violet: "text-[var(--collab-primary)]",
11
+ neutral: "text-[var(--text-muted)]"
12
+ };
13
+ const badgeClass = {
14
+ default: "bg-[var(--bg-base)] text-[var(--text-muted)]",
15
+ modified: "bg-status-warning-subtle text-status-warning",
16
+ disabled: "bg-status-error-subtle text-status-error",
17
+ partial: "bg-status-info-subtle text-status-info"
18
+ };
19
+ const sectionBorderClass = {
20
+ default: "border-border/50",
21
+ modified: "border-status-warning-border",
22
+ disabled: "border-status-error-border",
23
+ partial: "border-status-info-border"
24
+ };
25
+ const sectionBgClass = {
26
+ default: "bg-[var(--bg-elevated)]/50",
27
+ modified: "bg-status-warning-faint",
28
+ disabled: "bg-status-error-faint",
29
+ partial: "bg-status-info-faint"
30
+ };
31
+ function ContextSection({
32
+ icon: Icon,
33
+ title,
34
+ count,
35
+ badge,
36
+ badgeVariant = "default",
37
+ tint = "neutral",
38
+ defaultOpen = false,
39
+ children
40
+ }) {
41
+ const [expanded, setExpanded] = useState(defaultOpen);
42
+ return /* @__PURE__ */ jsxs(
43
+ "div",
44
+ {
45
+ className: cn(
46
+ "overflow-hidden rounded-lg border transition-colors duration-200",
47
+ sectionBorderClass[badgeVariant],
48
+ sectionBgClass[badgeVariant]
49
+ ),
50
+ children: [
51
+ /* @__PURE__ */ jsxs(
52
+ "button",
53
+ {
54
+ type: "button",
55
+ onClick: () => setExpanded((prev) => !prev),
56
+ className: cn(
57
+ "flex w-full items-center gap-2.5 px-3 py-2 text-left transition-colors duration-150",
58
+ "hover:bg-[var(--bg-elevated)]/80"
59
+ ),
60
+ children: [
61
+ /* @__PURE__ */ jsx(
62
+ motion.div,
63
+ {
64
+ animate: { rotate: expanded ? 90 : 0 },
65
+ transition: { type: "spring", stiffness: 300, damping: 25 },
66
+ children: /* @__PURE__ */ jsx(ChevronRight, { className: "size-3.5 text-[var(--text-muted)]" })
67
+ }
68
+ ),
69
+ /* @__PURE__ */ jsx(Icon, { className: cn("size-3.5", iconTintClass[tint]) }),
70
+ /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-[var(--text-secondary)]", children: title }),
71
+ count !== void 0 && /* @__PURE__ */ jsxs("span", { className: "text-[11px] text-[var(--text-muted)]", children: [
72
+ "(",
73
+ count,
74
+ ")"
75
+ ] }),
76
+ badge && /* @__PURE__ */ jsx(
77
+ "span",
78
+ {
79
+ className: cn(
80
+ "ml-auto rounded-full px-2 py-0.5 text-[10px] font-medium",
81
+ badgeClass[badgeVariant]
82
+ ),
83
+ children: badge
84
+ }
85
+ )
86
+ ]
87
+ }
88
+ ),
89
+ /* @__PURE__ */ jsx(AnimatePresence, { children: expanded && /* @__PURE__ */ jsx(
90
+ motion.div,
91
+ {
92
+ initial: { height: 0, opacity: 0 },
93
+ animate: { height: "auto", opacity: 1 },
94
+ exit: { height: 0, opacity: 0 },
95
+ transition: { duration: 0.2, ease: [0.25, 0.46, 0.45, 0.94] },
96
+ className: "overflow-hidden",
97
+ children: /* @__PURE__ */ jsx("div", { className: "min-w-0 border-t border-border/30 p-3", children })
98
+ }
99
+ ) })
100
+ ]
101
+ }
102
+ );
103
+ }
104
+ function ToggleRow({
105
+ name,
106
+ description,
107
+ enabled,
108
+ onToggle
109
+ }) {
110
+ return /* @__PURE__ */ jsxs(
111
+ "div",
112
+ {
113
+ className: cn(
114
+ "flex min-w-0 items-start justify-between gap-3 rounded-md px-2 py-1.5 transition-colors",
115
+ enabled ? "hover:bg-[var(--bg-elevated)]/60" : "opacity-60 hover:bg-[var(--bg-elevated)]/40"
116
+ ),
117
+ children: [
118
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
119
+ /* @__PURE__ */ jsx("div", { className: cn(
120
+ "text-[11px] font-medium",
121
+ enabled ? "text-[var(--text-secondary)]" : "text-[var(--text-muted)]"
122
+ ), children: name }),
123
+ description && /* @__PURE__ */ jsx("div", { className: "mt-0.5 text-[10px] leading-snug text-[var(--text-muted)]/60", children: description })
124
+ ] }),
125
+ /* @__PURE__ */ jsx(
126
+ Switch,
127
+ {
128
+ size: "sm",
129
+ className: "mt-0.5 shrink-0",
130
+ checked: enabled,
131
+ onCheckedChange: onToggle
132
+ }
133
+ )
134
+ ]
135
+ }
136
+ );
137
+ }
138
+ function SavePresetInput({
139
+ onSave,
140
+ onCancel
141
+ }) {
142
+ const [name, setName] = useState("");
143
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
144
+ /* @__PURE__ */ jsx(
145
+ "input",
146
+ {
147
+ "aria-label": "Preset name",
148
+ type: "text",
149
+ value: name,
150
+ onChange: (e) => setName(e.target.value),
151
+ placeholder: "Preset name...",
152
+ className: "flex-1 rounded-md border border-border/50 bg-[var(--bg-base)] px-2 py-1 text-xs text-[var(--text-primary)] placeholder:text-[var(--text-muted)] outline-none focus:border-[var(--accent-primary)]",
153
+ onKeyDown: (e) => {
154
+ if (e.key === "Enter" && name.trim()) onSave(name.trim());
155
+ if (e.key === "Escape") onCancel();
156
+ }
157
+ }
158
+ ),
159
+ /* @__PURE__ */ jsx(
160
+ "button",
161
+ {
162
+ type: "button",
163
+ onClick: () => name.trim() && onSave(name.trim()),
164
+ disabled: !name.trim(),
165
+ className: "rounded-md bg-[var(--accent-primary)] px-2 py-1 text-[11px] font-medium text-white disabled:opacity-50",
166
+ children: "Save"
167
+ }
168
+ ),
169
+ /* @__PURE__ */ jsx(
170
+ "button",
171
+ {
172
+ type: "button",
173
+ onClick: onCancel,
174
+ className: "text-[11px] text-[var(--text-muted)] hover:text-[var(--text-secondary)]",
175
+ children: "Cancel"
176
+ }
177
+ )
178
+ ] });
179
+ }
180
+ export {
181
+ ContextSection,
182
+ SavePresetInput,
183
+ ToggleRow
184
+ };
@@ -0,0 +1,194 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }var _react = require('react');
2
+ const NONE_PRESET = {
3
+ id: "__none__",
4
+ name: "None",
5
+ systemPrompt: "",
6
+ disabledTools: ["__all__"],
7
+ disabledSkills: ["__all__"]
8
+ };
9
+ const DEFAULT_PRESET = {
10
+ id: "__default__",
11
+ name: "Default",
12
+ systemPrompt: null,
13
+ disabledTools: [],
14
+ disabledSkills: []
15
+ };
16
+ const BUILTIN_PRESETS = [DEFAULT_PRESET, NONE_PRESET];
17
+ function normalizeDisabledNames(names, availableNames) {
18
+ const allowed = new Set(availableNames);
19
+ return new Set((_nullishCoalesce(names, () => ( []))).filter((name) => allowed.has(name)));
20
+ }
21
+ function appliedSystemPrompt(overrides) {
22
+ if (!overrides || !Object.prototype.hasOwnProperty.call(overrides, "systemPrompt")) return null;
23
+ return typeof overrides.systemPrompt === "string" ? overrides.systemPrompt : null;
24
+ }
25
+ function enabledCount(items, disabled, allDisabled) {
26
+ if (allDisabled) return 0;
27
+ return items.filter((item) => !disabled.has(item.name)).length;
28
+ }
29
+ function useContextEditorModel({
30
+ open,
31
+ available,
32
+ initialOverrides,
33
+ presets,
34
+ onSavePreset,
35
+ onDeletePreset
36
+ }) {
37
+ const [systemPrompt, setSystemPromptState] = _react.useState.call(void 0, null);
38
+ const [disabledTools, setDisabledTools] = _react.useState.call(void 0, /* @__PURE__ */ new Set());
39
+ const [disabledSkills, setDisabledSkills] = _react.useState.call(void 0, /* @__PURE__ */ new Set());
40
+ const [allToolsDisabled, setAllToolsDisabled] = _react.useState.call(void 0, false);
41
+ const [allSkillsDisabled, setAllSkillsDisabled] = _react.useState.call(void 0, false);
42
+ const [activePresetId, setActivePresetId] = _react.useState.call(void 0, "__default__");
43
+ const [showSaveInput, setShowSaveInput] = _react.useState.call(void 0, false);
44
+ const tools = _nullishCoalesce(_optionalChain([available, 'optionalAccess', _ => _.tools]), () => ( []));
45
+ const skills = _nullishCoalesce(_optionalChain([available, 'optionalAccess', _2 => _2.skills]), () => ( []));
46
+ const seededRef = _react.useRef.call(void 0, false);
47
+ _react.useEffect.call(void 0, () => {
48
+ if (!open) {
49
+ seededRef.current = false;
50
+ return;
51
+ }
52
+ if (seededRef.current || !available) return;
53
+ seededRef.current = true;
54
+ const seedDisabledTools = normalizeDisabledNames(
55
+ _optionalChain([initialOverrides, 'optionalAccess', _3 => _3.disabledTools]),
56
+ available.tools.map((t) => t.name)
57
+ );
58
+ const seedDisabledSkills = normalizeDisabledNames(
59
+ _optionalChain([initialOverrides, 'optionalAccess', _4 => _4.disabledSkills]),
60
+ available.skills.map((s) => s.name)
61
+ );
62
+ const allTools = available.tools.length > 0 && seedDisabledTools.size >= available.tools.length;
63
+ const allSkills = available.skills.length > 0 && seedDisabledSkills.size >= available.skills.length;
64
+ setSystemPromptState(appliedSystemPrompt(initialOverrides));
65
+ setDisabledTools(allTools ? /* @__PURE__ */ new Set() : seedDisabledTools);
66
+ setDisabledSkills(allSkills ? /* @__PURE__ */ new Set() : seedDisabledSkills);
67
+ setAllToolsDisabled(allTools);
68
+ setAllSkillsDisabled(allSkills);
69
+ setActivePresetId(initialOverrides ? null : "__default__");
70
+ setShowSaveInput(false);
71
+ }, [open, available, initialOverrides]);
72
+ const setSystemPrompt = _react.useCallback.call(void 0, (value) => {
73
+ setSystemPromptState(value);
74
+ setActivePresetId(null);
75
+ }, []);
76
+ const toggleCapability = _react.useCallback.call(void 0,
77
+ (name, items, disabled, allDisabled, setDisabled, setAll) => {
78
+ let next;
79
+ if (allDisabled) {
80
+ next = new Set(items.map((i) => i.name));
81
+ next.delete(name);
82
+ } else {
83
+ next = new Set(disabled);
84
+ if (next.has(name)) next.delete(name);
85
+ else next.add(name);
86
+ }
87
+ const total = items.length;
88
+ const allNowDisabled = total > 0 && next.size >= total;
89
+ setDisabled(allNowDisabled ? /* @__PURE__ */ new Set() : next);
90
+ setAll(allNowDisabled);
91
+ setActivePresetId(null);
92
+ },
93
+ []
94
+ );
95
+ const loadPreset = _react.useCallback.call(void 0,
96
+ (presetId) => {
97
+ const all = [...BUILTIN_PRESETS, ...presets];
98
+ const preset = all.find((p) => p.id === presetId);
99
+ if (!preset) return;
100
+ const allTools = preset.disabledTools.includes("__all__");
101
+ const allSkills = preset.disabledSkills.includes("__all__");
102
+ setSystemPromptState(preset.systemPrompt);
103
+ setDisabledTools(new Set(allTools ? [] : preset.disabledTools));
104
+ setDisabledSkills(new Set(allSkills ? [] : preset.disabledSkills));
105
+ setAllToolsDisabled(allTools);
106
+ setAllSkillsDisabled(allSkills);
107
+ setActivePresetId(presetId);
108
+ },
109
+ [presets]
110
+ );
111
+ const resetToDefault = _react.useCallback.call(void 0, () => {
112
+ setSystemPromptState(null);
113
+ setDisabledTools(/* @__PURE__ */ new Set());
114
+ setDisabledSkills(/* @__PURE__ */ new Set());
115
+ setAllToolsDisabled(false);
116
+ setAllSkillsDisabled(false);
117
+ setActivePresetId("__default__");
118
+ setShowSaveInput(false);
119
+ }, []);
120
+ const buildOverrides = _react.useCallback.call(void 0, () => {
121
+ const toolsToDisable = allToolsDisabled ? tools.map((t) => t.name) : Array.from(disabledTools);
122
+ const skillsToDisable = allSkillsDisabled ? skills.map((s) => s.name) : Array.from(disabledSkills);
123
+ const has = systemPrompt !== null || toolsToDisable.length > 0 || skillsToDisable.length > 0;
124
+ if (!has) return null;
125
+ return {
126
+ systemPrompt: _nullishCoalesce(systemPrompt, () => ( void 0)),
127
+ disabledTools: toolsToDisable.length > 0 ? toolsToDisable : void 0,
128
+ disabledSkills: skillsToDisable.length > 0 ? skillsToDisable : void 0
129
+ };
130
+ }, [allToolsDisabled, allSkillsDisabled, tools, skills, disabledTools, disabledSkills, systemPrompt]);
131
+ const handleSavePreset = _react.useCallback.call(void 0,
132
+ (name) => {
133
+ onSavePreset(name, {
134
+ systemPrompt,
135
+ disabledTools: allToolsDisabled ? ["__all__"] : Array.from(disabledTools),
136
+ disabledSkills: allSkillsDisabled ? ["__all__"] : Array.from(disabledSkills)
137
+ });
138
+ setShowSaveInput(false);
139
+ },
140
+ [onSavePreset, systemPrompt, allToolsDisabled, disabledTools, allSkillsDisabled, disabledSkills]
141
+ );
142
+ const allPresets = _react.useMemo.call(void 0, () => [...BUILTIN_PRESETS, ...presets], [presets]);
143
+ const activeUserPreset = _react.useMemo.call(void 0,
144
+ () => activePresetId && !activePresetId.startsWith("__") ? _nullishCoalesce(allPresets.find((p) => p.id === activePresetId), () => ( null)) : null,
145
+ [activePresetId, allPresets]
146
+ );
147
+ const hasOverrides = systemPrompt !== null || disabledTools.size > 0 || disabledSkills.size > 0 || allToolsDisabled || allSkillsDisabled;
148
+ return {
149
+ displayedPrompt: _nullishCoalesce(_nullishCoalesce(systemPrompt, () => ( _optionalChain([available, 'optionalAccess', _5 => _5.systemPrompt]))), () => ( "")),
150
+ systemPrompt,
151
+ setSystemPrompt,
152
+ preset: {
153
+ allPresets,
154
+ activePresetId,
155
+ activeUserPreset,
156
+ hasOverrides,
157
+ showSaveInput,
158
+ onPresetChange: loadPreset,
159
+ onDelete: onDeletePreset,
160
+ onReset: resetToDefault,
161
+ onShowSave: () => setShowSaveInput(true),
162
+ onSave: handleSavePreset,
163
+ onCancelSave: () => setShowSaveInput(false)
164
+ },
165
+ tools: {
166
+ items: tools,
167
+ allDisabled: allToolsDisabled,
168
+ enabledCount: enabledCount(tools, disabledTools, allToolsDisabled),
169
+ isEnabled: (name) => !allToolsDisabled && !disabledTools.has(name),
170
+ onToggle: (name) => toggleCapability(name, tools, disabledTools, allToolsDisabled, setDisabledTools, setAllToolsDisabled),
171
+ onToggleAll: (disabled) => {
172
+ setAllToolsDisabled(disabled);
173
+ setDisabledTools(/* @__PURE__ */ new Set());
174
+ setActivePresetId(null);
175
+ }
176
+ },
177
+ skills: {
178
+ items: skills,
179
+ allDisabled: allSkillsDisabled,
180
+ enabledCount: enabledCount(skills, disabledSkills, allSkillsDisabled),
181
+ isEnabled: (name) => !allSkillsDisabled && !disabledSkills.has(name),
182
+ onToggle: (name) => toggleCapability(name, skills, disabledSkills, allSkillsDisabled, setDisabledSkills, setAllSkillsDisabled),
183
+ onToggleAll: (disabled) => {
184
+ setAllSkillsDisabled(disabled);
185
+ setDisabledSkills(/* @__PURE__ */ new Set());
186
+ setActivePresetId(null);
187
+ }
188
+ },
189
+ buildOverrides
190
+ };
191
+ }
192
+
193
+
194
+ exports.useContextEditorModel = useContextEditorModel;
@@ -0,0 +1,57 @@
1
+ import { ContextPreset, ContextToolInfo, ContextSkillInfo, ContextOverrides, AvailableContext } from '@sero-ai/common';
2
+
3
+ /**
4
+ * useContextEditorModel — the controlled editing state for the ContextEditor.
5
+ *
6
+ * Holds the working overrides (system prompt, disabled tools/skills, preset
7
+ * selection) and all the toggle/normalize/preset logic, seeded from the
8
+ * `available` context and `initialOverrides`. Host-agnostic: persistence
9
+ * (apply / save preset / delete preset) is injected by the consumer, so the
10
+ * chat session editor and an app module (e.g. an Orchestrator loop) share one
11
+ * implementation.
12
+ */
13
+
14
+ /** The persistable body of a preset (id assigned by the consumer). */
15
+ type ContextPresetBody = Pick<ContextPreset, 'systemPrompt' | 'disabledTools' | 'disabledSkills'>;
16
+ interface CapabilityState<TItem extends ContextToolInfo | ContextSkillInfo> {
17
+ items: TItem[];
18
+ allDisabled: boolean;
19
+ enabledCount: number;
20
+ isEnabled: (name: string) => boolean;
21
+ onToggle: (name: string) => void;
22
+ onToggleAll: (disabled: boolean) => void;
23
+ }
24
+ interface ContextEditorModel {
25
+ displayedPrompt: string;
26
+ systemPrompt: string | null;
27
+ setSystemPrompt: (value: string | null) => void;
28
+ preset: {
29
+ allPresets: ContextPreset[];
30
+ activePresetId: string | null;
31
+ activeUserPreset: ContextPreset | null;
32
+ hasOverrides: boolean;
33
+ showSaveInput: boolean;
34
+ onPresetChange: (id: string) => void;
35
+ onDelete: (id: string) => void;
36
+ onReset: () => void;
37
+ onShowSave: () => void;
38
+ onSave: (name: string) => void;
39
+ onCancelSave: () => void;
40
+ };
41
+ tools: CapabilityState<ContextToolInfo>;
42
+ skills: CapabilityState<ContextSkillInfo>;
43
+ /** Build the overrides to persist, or null when nothing is overridden. */
44
+ buildOverrides: () => ContextOverrides | null;
45
+ }
46
+ interface UseContextEditorModelParams {
47
+ /** Whether the editor is open — drives one-time seeding per open. */
48
+ open: boolean;
49
+ available: AvailableContext | null;
50
+ initialOverrides: ContextOverrides | null;
51
+ presets: ContextPreset[];
52
+ onSavePreset: (name: string, preset: ContextPresetBody) => void;
53
+ onDeletePreset: (id: string) => void;
54
+ }
55
+ declare function useContextEditorModel({ open, available, initialOverrides, presets, onSavePreset, onDeletePreset, }: UseContextEditorModelParams): ContextEditorModel;
56
+
57
+ export { type ContextEditorModel, type ContextPresetBody, type UseContextEditorModelParams, useContextEditorModel };
@@ -0,0 +1,57 @@
1
+ import { ContextPreset, ContextToolInfo, ContextSkillInfo, ContextOverrides, AvailableContext } from '@sero-ai/common';
2
+
3
+ /**
4
+ * useContextEditorModel — the controlled editing state for the ContextEditor.
5
+ *
6
+ * Holds the working overrides (system prompt, disabled tools/skills, preset
7
+ * selection) and all the toggle/normalize/preset logic, seeded from the
8
+ * `available` context and `initialOverrides`. Host-agnostic: persistence
9
+ * (apply / save preset / delete preset) is injected by the consumer, so the
10
+ * chat session editor and an app module (e.g. an Orchestrator loop) share one
11
+ * implementation.
12
+ */
13
+
14
+ /** The persistable body of a preset (id assigned by the consumer). */
15
+ type ContextPresetBody = Pick<ContextPreset, 'systemPrompt' | 'disabledTools' | 'disabledSkills'>;
16
+ interface CapabilityState<TItem extends ContextToolInfo | ContextSkillInfo> {
17
+ items: TItem[];
18
+ allDisabled: boolean;
19
+ enabledCount: number;
20
+ isEnabled: (name: string) => boolean;
21
+ onToggle: (name: string) => void;
22
+ onToggleAll: (disabled: boolean) => void;
23
+ }
24
+ interface ContextEditorModel {
25
+ displayedPrompt: string;
26
+ systemPrompt: string | null;
27
+ setSystemPrompt: (value: string | null) => void;
28
+ preset: {
29
+ allPresets: ContextPreset[];
30
+ activePresetId: string | null;
31
+ activeUserPreset: ContextPreset | null;
32
+ hasOverrides: boolean;
33
+ showSaveInput: boolean;
34
+ onPresetChange: (id: string) => void;
35
+ onDelete: (id: string) => void;
36
+ onReset: () => void;
37
+ onShowSave: () => void;
38
+ onSave: (name: string) => void;
39
+ onCancelSave: () => void;
40
+ };
41
+ tools: CapabilityState<ContextToolInfo>;
42
+ skills: CapabilityState<ContextSkillInfo>;
43
+ /** Build the overrides to persist, or null when nothing is overridden. */
44
+ buildOverrides: () => ContextOverrides | null;
45
+ }
46
+ interface UseContextEditorModelParams {
47
+ /** Whether the editor is open — drives one-time seeding per open. */
48
+ open: boolean;
49
+ available: AvailableContext | null;
50
+ initialOverrides: ContextOverrides | null;
51
+ presets: ContextPreset[];
52
+ onSavePreset: (name: string, preset: ContextPresetBody) => void;
53
+ onDeletePreset: (id: string) => void;
54
+ }
55
+ declare function useContextEditorModel({ open, available, initialOverrides, presets, onSavePreset, onDeletePreset, }: UseContextEditorModelParams): ContextEditorModel;
56
+
57
+ export { type ContextEditorModel, type ContextPresetBody, type UseContextEditorModelParams, useContextEditorModel };
@@ -0,0 +1,194 @@
1
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
2
+ const NONE_PRESET = {
3
+ id: "__none__",
4
+ name: "None",
5
+ systemPrompt: "",
6
+ disabledTools: ["__all__"],
7
+ disabledSkills: ["__all__"]
8
+ };
9
+ const DEFAULT_PRESET = {
10
+ id: "__default__",
11
+ name: "Default",
12
+ systemPrompt: null,
13
+ disabledTools: [],
14
+ disabledSkills: []
15
+ };
16
+ const BUILTIN_PRESETS = [DEFAULT_PRESET, NONE_PRESET];
17
+ function normalizeDisabledNames(names, availableNames) {
18
+ const allowed = new Set(availableNames);
19
+ return new Set((names ?? []).filter((name) => allowed.has(name)));
20
+ }
21
+ function appliedSystemPrompt(overrides) {
22
+ if (!overrides || !Object.prototype.hasOwnProperty.call(overrides, "systemPrompt")) return null;
23
+ return typeof overrides.systemPrompt === "string" ? overrides.systemPrompt : null;
24
+ }
25
+ function enabledCount(items, disabled, allDisabled) {
26
+ if (allDisabled) return 0;
27
+ return items.filter((item) => !disabled.has(item.name)).length;
28
+ }
29
+ function useContextEditorModel({
30
+ open,
31
+ available,
32
+ initialOverrides,
33
+ presets,
34
+ onSavePreset,
35
+ onDeletePreset
36
+ }) {
37
+ const [systemPrompt, setSystemPromptState] = useState(null);
38
+ const [disabledTools, setDisabledTools] = useState(/* @__PURE__ */ new Set());
39
+ const [disabledSkills, setDisabledSkills] = useState(/* @__PURE__ */ new Set());
40
+ const [allToolsDisabled, setAllToolsDisabled] = useState(false);
41
+ const [allSkillsDisabled, setAllSkillsDisabled] = useState(false);
42
+ const [activePresetId, setActivePresetId] = useState("__default__");
43
+ const [showSaveInput, setShowSaveInput] = useState(false);
44
+ const tools = available?.tools ?? [];
45
+ const skills = available?.skills ?? [];
46
+ const seededRef = useRef(false);
47
+ useEffect(() => {
48
+ if (!open) {
49
+ seededRef.current = false;
50
+ return;
51
+ }
52
+ if (seededRef.current || !available) return;
53
+ seededRef.current = true;
54
+ const seedDisabledTools = normalizeDisabledNames(
55
+ initialOverrides?.disabledTools,
56
+ available.tools.map((t) => t.name)
57
+ );
58
+ const seedDisabledSkills = normalizeDisabledNames(
59
+ initialOverrides?.disabledSkills,
60
+ available.skills.map((s) => s.name)
61
+ );
62
+ const allTools = available.tools.length > 0 && seedDisabledTools.size >= available.tools.length;
63
+ const allSkills = available.skills.length > 0 && seedDisabledSkills.size >= available.skills.length;
64
+ setSystemPromptState(appliedSystemPrompt(initialOverrides));
65
+ setDisabledTools(allTools ? /* @__PURE__ */ new Set() : seedDisabledTools);
66
+ setDisabledSkills(allSkills ? /* @__PURE__ */ new Set() : seedDisabledSkills);
67
+ setAllToolsDisabled(allTools);
68
+ setAllSkillsDisabled(allSkills);
69
+ setActivePresetId(initialOverrides ? null : "__default__");
70
+ setShowSaveInput(false);
71
+ }, [open, available, initialOverrides]);
72
+ const setSystemPrompt = useCallback((value) => {
73
+ setSystemPromptState(value);
74
+ setActivePresetId(null);
75
+ }, []);
76
+ const toggleCapability = useCallback(
77
+ (name, items, disabled, allDisabled, setDisabled, setAll) => {
78
+ let next;
79
+ if (allDisabled) {
80
+ next = new Set(items.map((i) => i.name));
81
+ next.delete(name);
82
+ } else {
83
+ next = new Set(disabled);
84
+ if (next.has(name)) next.delete(name);
85
+ else next.add(name);
86
+ }
87
+ const total = items.length;
88
+ const allNowDisabled = total > 0 && next.size >= total;
89
+ setDisabled(allNowDisabled ? /* @__PURE__ */ new Set() : next);
90
+ setAll(allNowDisabled);
91
+ setActivePresetId(null);
92
+ },
93
+ []
94
+ );
95
+ const loadPreset = useCallback(
96
+ (presetId) => {
97
+ const all = [...BUILTIN_PRESETS, ...presets];
98
+ const preset = all.find((p) => p.id === presetId);
99
+ if (!preset) return;
100
+ const allTools = preset.disabledTools.includes("__all__");
101
+ const allSkills = preset.disabledSkills.includes("__all__");
102
+ setSystemPromptState(preset.systemPrompt);
103
+ setDisabledTools(new Set(allTools ? [] : preset.disabledTools));
104
+ setDisabledSkills(new Set(allSkills ? [] : preset.disabledSkills));
105
+ setAllToolsDisabled(allTools);
106
+ setAllSkillsDisabled(allSkills);
107
+ setActivePresetId(presetId);
108
+ },
109
+ [presets]
110
+ );
111
+ const resetToDefault = useCallback(() => {
112
+ setSystemPromptState(null);
113
+ setDisabledTools(/* @__PURE__ */ new Set());
114
+ setDisabledSkills(/* @__PURE__ */ new Set());
115
+ setAllToolsDisabled(false);
116
+ setAllSkillsDisabled(false);
117
+ setActivePresetId("__default__");
118
+ setShowSaveInput(false);
119
+ }, []);
120
+ const buildOverrides = useCallback(() => {
121
+ const toolsToDisable = allToolsDisabled ? tools.map((t) => t.name) : Array.from(disabledTools);
122
+ const skillsToDisable = allSkillsDisabled ? skills.map((s) => s.name) : Array.from(disabledSkills);
123
+ const has = systemPrompt !== null || toolsToDisable.length > 0 || skillsToDisable.length > 0;
124
+ if (!has) return null;
125
+ return {
126
+ systemPrompt: systemPrompt ?? void 0,
127
+ disabledTools: toolsToDisable.length > 0 ? toolsToDisable : void 0,
128
+ disabledSkills: skillsToDisable.length > 0 ? skillsToDisable : void 0
129
+ };
130
+ }, [allToolsDisabled, allSkillsDisabled, tools, skills, disabledTools, disabledSkills, systemPrompt]);
131
+ const handleSavePreset = useCallback(
132
+ (name) => {
133
+ onSavePreset(name, {
134
+ systemPrompt,
135
+ disabledTools: allToolsDisabled ? ["__all__"] : Array.from(disabledTools),
136
+ disabledSkills: allSkillsDisabled ? ["__all__"] : Array.from(disabledSkills)
137
+ });
138
+ setShowSaveInput(false);
139
+ },
140
+ [onSavePreset, systemPrompt, allToolsDisabled, disabledTools, allSkillsDisabled, disabledSkills]
141
+ );
142
+ const allPresets = useMemo(() => [...BUILTIN_PRESETS, ...presets], [presets]);
143
+ const activeUserPreset = useMemo(
144
+ () => activePresetId && !activePresetId.startsWith("__") ? allPresets.find((p) => p.id === activePresetId) ?? null : null,
145
+ [activePresetId, allPresets]
146
+ );
147
+ const hasOverrides = systemPrompt !== null || disabledTools.size > 0 || disabledSkills.size > 0 || allToolsDisabled || allSkillsDisabled;
148
+ return {
149
+ displayedPrompt: systemPrompt ?? available?.systemPrompt ?? "",
150
+ systemPrompt,
151
+ setSystemPrompt,
152
+ preset: {
153
+ allPresets,
154
+ activePresetId,
155
+ activeUserPreset,
156
+ hasOverrides,
157
+ showSaveInput,
158
+ onPresetChange: loadPreset,
159
+ onDelete: onDeletePreset,
160
+ onReset: resetToDefault,
161
+ onShowSave: () => setShowSaveInput(true),
162
+ onSave: handleSavePreset,
163
+ onCancelSave: () => setShowSaveInput(false)
164
+ },
165
+ tools: {
166
+ items: tools,
167
+ allDisabled: allToolsDisabled,
168
+ enabledCount: enabledCount(tools, disabledTools, allToolsDisabled),
169
+ isEnabled: (name) => !allToolsDisabled && !disabledTools.has(name),
170
+ onToggle: (name) => toggleCapability(name, tools, disabledTools, allToolsDisabled, setDisabledTools, setAllToolsDisabled),
171
+ onToggleAll: (disabled) => {
172
+ setAllToolsDisabled(disabled);
173
+ setDisabledTools(/* @__PURE__ */ new Set());
174
+ setActivePresetId(null);
175
+ }
176
+ },
177
+ skills: {
178
+ items: skills,
179
+ allDisabled: allSkillsDisabled,
180
+ enabledCount: enabledCount(skills, disabledSkills, allSkillsDisabled),
181
+ isEnabled: (name) => !allSkillsDisabled && !disabledSkills.has(name),
182
+ onToggle: (name) => toggleCapability(name, skills, disabledSkills, allSkillsDisabled, setDisabledSkills, setAllSkillsDisabled),
183
+ onToggleAll: (disabled) => {
184
+ setAllSkillsDisabled(disabled);
185
+ setDisabledSkills(/* @__PURE__ */ new Set());
186
+ setActivePresetId(null);
187
+ }
188
+ },
189
+ buildOverrides
190
+ };
191
+ }
192
+ export {
193
+ useContextEditorModel
194
+ };