bazilion 0.5.1 → 0.7.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 (122) hide show
  1. package/README.md +17 -12
  2. package/dist/cli.js +383 -152
  3. package/dist/cli.js.map +1 -1
  4. package/dist/daemon.js +238 -14064
  5. package/dist/daemon.js.map +1 -1
  6. package/dist/web/client/assets/AgentAvatar-JYijLvZ2.js +1 -0
  7. package/dist/web/client/assets/AgentTabs-DioGqUVR.js +1 -0
  8. package/dist/web/client/assets/Button-ByiV6fpd.js +1 -0
  9. package/dist/web/client/assets/ChatPane-DzEgOEqS.js +74 -0
  10. package/dist/web/client/assets/ConfigTabs-pY-V0Rie.js +1 -0
  11. package/dist/web/client/assets/FieldRow-CNKma5LE.js +1 -0
  12. package/dist/web/client/assets/MembersEditor-C6UpqDdV.js +1 -0
  13. package/dist/web/client/assets/SpawnTeamModal-BEkNCKXm.js +1 -0
  14. package/dist/web/client/assets/TemplatesTabs-Da7mg9FI.js +1 -0
  15. package/dist/web/client/assets/_id-BdKmo0gb.js +1 -0
  16. package/dist/web/client/assets/_id-LT6Ejjr0.js +1 -0
  17. package/dist/web/client/assets/_id-MR2XjWh0.js +1 -0
  18. package/dist/web/client/assets/_id-_6jIt0_-.js +1 -0
  19. package/dist/web/client/assets/agents-0arKbVYG.js +1 -0
  20. package/dist/web/client/assets/config-BSAVT-17.js +3 -0
  21. package/dist/web/client/assets/groups-BqTkhHes.js +1 -0
  22. package/dist/web/client/assets/inbox-ozoCXzr5.js +1 -0
  23. package/dist/web/client/assets/index-iayCEuU2.js +12 -0
  24. package/dist/web/client/assets/jsx-runtime-DGeXAQPT.js +1 -0
  25. package/dist/web/client/assets/login-D8lNr2SX.js +1 -0
  26. package/dist/web/client/assets/mcp-BLnngDsj.js +1 -0
  27. package/dist/web/client/assets/memory-D1GQjEvN.js +1 -0
  28. package/dist/web/client/assets/preload-helper-CvnapA2_.js +1 -0
  29. package/dist/web/client/assets/profile-groups-C2yJPTaE.js +1 -0
  30. package/dist/web/client/assets/profiles-BV7AAZjj.js +1 -0
  31. package/dist/web/client/assets/routes-DSHQLA7K.js +1 -0
  32. package/dist/web/client/assets/services-BbCJe1Du.js +1 -0
  33. package/dist/web/client/assets/skills-C6czKR5I.js +1 -0
  34. package/dist/web/client/assets/styles-C06axZZk.css +2 -0
  35. package/dist/web/client/assets/telegram-gE4j8gte.js +1 -0
  36. package/dist/web/client/assets/tokens-D2_O9ARe.js +1 -0
  37. package/dist/web/client/assets/triggers-WljnfEfJ.js +1 -0
  38. package/dist/web/client/assets/welcome-Dn-zvmBE.js +1 -0
  39. package/dist/web/client/assets/wire-constants-BkT5-597.js +1 -0
  40. package/dist/web/client/baziu.svg +8 -0
  41. package/dist/web/server/assets/AgentAvatar-8gTAy_tP.js +37 -0
  42. package/dist/web/server/assets/AgentTabs-BOjTN7QF.js +34 -0
  43. package/dist/web/server/assets/Button-Dsnw22OF.js +17 -0
  44. package/dist/web/server/assets/ChatPane-BvpswYvF.js +1084 -0
  45. package/dist/web/server/assets/ConfigTabs-CyuxzesF.js +41 -0
  46. package/dist/web/server/assets/FieldRow-DwyqycWI.js +94 -0
  47. package/dist/web/server/assets/MembersEditor-BWQztvrX.js +131 -0
  48. package/dist/web/server/assets/Sidebar-DmEiewRN.js +529 -0
  49. package/dist/web/server/assets/SpawnTeamModal-dSN421k_.js +107 -0
  50. package/dist/web/server/assets/TemplatesTabs---7h5GYa.js +30 -0
  51. package/dist/web/server/assets/_id-81NrHA5d.js +16 -0
  52. package/dist/web/server/assets/_id-BKev9H1p.js +12 -0
  53. package/dist/web/server/assets/_id-BNwlbWHP.js +24 -0
  54. package/dist/web/server/assets/_id-BqnDy_Ca.js +16 -0
  55. package/dist/web/server/assets/_id-CRqqi8IE.js +161 -0
  56. package/dist/web/server/assets/_id-CXg-Blec.js +367 -0
  57. package/dist/web/server/assets/_id-CnQflrRv.js +16 -0
  58. package/dist/web/server/assets/_id-D0ytyXGY.js +662 -0
  59. package/dist/web/server/assets/_id-D8duqgd5.js +27 -0
  60. package/dist/web/server/assets/_id-DDixKEud.js +467 -0
  61. package/dist/web/server/assets/_id-D_Ew11ED.js +28 -0
  62. package/dist/web/server/assets/_id-Sjw0zhA6.js +38 -0
  63. package/dist/web/server/assets/_tanstack-start-manifest_v-DBlFH2gg.js +178 -0
  64. package/dist/web/server/assets/agents-C7SBPN0M.js +210 -0
  65. package/dist/web/server/assets/agents-ChcAJUI5.js +14 -0
  66. package/dist/web/server/assets/agents-k5QURC4I.js +26 -0
  67. package/dist/web/server/assets/auth-DzRAMwVt.js +26 -0
  68. package/dist/web/server/assets/config-Bq3o924J.js +12 -0
  69. package/dist/web/server/assets/config-CHaCv89D.js +19 -0
  70. package/dist/web/server/assets/config-CdVjqjin.js +391 -0
  71. package/dist/web/server/assets/createServerRpc-CeKECg65.js +12 -0
  72. package/dist/web/server/assets/createSsrRpc-ZBGxhl8t.js +16 -0
  73. package/dist/web/server/assets/daemon-client-2NRMzlTr.js +96 -0
  74. package/dist/web/server/assets/empty-plugin-adapters-DKUlnwwl.js +5 -0
  75. package/dist/web/server/assets/groups-CbSwND2r.js +12 -0
  76. package/dist/web/server/assets/groups-CeRRlZaZ.js +150 -0
  77. package/dist/web/server/assets/groups-pk4CYSuf.js +21 -0
  78. package/dist/web/server/assets/inbox-Bxb3W04M.js +27 -0
  79. package/dist/web/server/assets/inbox-CkiSvD14.js +42 -0
  80. package/dist/web/server/assets/inbox-DU27iHv_.js +133 -0
  81. package/dist/web/server/assets/login-CNznncgA.js +58 -0
  82. package/dist/web/server/assets/login-CQybKk7Y.js +74 -0
  83. package/dist/web/server/assets/mcp-BU_kKENi.js +268 -0
  84. package/dist/web/server/assets/mcp-BsFKEoXt.js +12 -0
  85. package/dist/web/server/assets/mcp-CKqwG4mt.js +12 -0
  86. package/dist/web/server/assets/memory-BaYnfm7K.js +28 -0
  87. package/dist/web/server/assets/memory-CQaqWnyM.js +284 -0
  88. package/dist/web/server/assets/memory-Ns2-Z31p.js +16 -0
  89. package/dist/web/server/assets/profile-groups-CiU06yN1.js +28 -0
  90. package/dist/web/server/assets/profile-groups-D21MYoLM.js +208 -0
  91. package/dist/web/server/assets/profile-groups-aoJleXHP.js +12 -0
  92. package/dist/web/server/assets/profiles-C6a3RKgu.js +26 -0
  93. package/dist/web/server/assets/profiles-CZ5NkmVw.js +12 -0
  94. package/dist/web/server/assets/profiles-LxcC_L6n.js +453 -0
  95. package/dist/web/server/assets/router-BpBZgRwn.js +460 -0
  96. package/dist/web/server/assets/routes-C61gBiXa.js +57 -0
  97. package/dist/web/server/assets/routes-Ce2VWrU9.js +33 -0
  98. package/dist/web/server/assets/routes-V9URcp1v.js +14 -0
  99. package/dist/web/server/assets/services-B91w2f-X.js +94 -0
  100. package/dist/web/server/assets/services-Ccc5s2bS.js +17 -0
  101. package/dist/web/server/assets/services-DhRiNeq0.js +12 -0
  102. package/dist/web/server/assets/skills-CFIWVg32.js +12 -0
  103. package/dist/web/server/assets/skills-CpsyR_WA.js +12 -0
  104. package/dist/web/server/assets/skills-dLyBZb3B.js +261 -0
  105. package/dist/web/server/assets/start-CYDpZ6cb.js +4 -0
  106. package/dist/web/server/assets/telegram-BdaUIjvs.js +12 -0
  107. package/dist/web/server/assets/telegram-DfAddLdv.js +583 -0
  108. package/dist/web/server/assets/telegram-T3l9KtiE.js +12 -0
  109. package/dist/web/server/assets/tokens-BCz3PSoT.js +12 -0
  110. package/dist/web/server/assets/tokens-CkKqrtk-.js +193 -0
  111. package/dist/web/server/assets/tokens-DdpnfV_Y.js +14 -0
  112. package/dist/web/server/assets/triggers-BcH_6PW1.js +26 -0
  113. package/dist/web/server/assets/triggers-BcTTwMfy.js +16 -0
  114. package/dist/web/server/assets/triggers-BzJG1nN5.js +191 -0
  115. package/dist/web/server/assets/welcome-CP4CZ9B6.js +85 -0
  116. package/dist/web/server/assets/wire-constants-Deb4NxBb.js +16 -0
  117. package/dist/web/server/server.js +5911 -0
  118. package/dist/web-server.js +42 -0
  119. package/dist/web-server.js.map +1 -0
  120. package/dist/worker.js +65 -2
  121. package/dist/worker.js.map +1 -1
  122. package/package.json +18 -12
@@ -0,0 +1,467 @@
1
+ import { t as Route } from "./_id-BqnDy_Ca.js";
2
+ import { useState } from "react";
3
+ import { useRouter } from "@tanstack/react-router";
4
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
5
+ //#region src/routes/profiles/$id.tsx?tsr-split=component
6
+ function ProfileDetailPage() {
7
+ const { loaded, modelGroups, skills } = Route.useLoaderData();
8
+ const [tab, setTab] = useState("basics");
9
+ return /* @__PURE__ */ jsxs("div", { children: [
10
+ /* @__PURE__ */ jsxs("header", {
11
+ className: "mb-1",
12
+ children: [
13
+ /* @__PURE__ */ jsx("a", {
14
+ href: "/profiles",
15
+ className: "mb-1 inline-block text-[0.85em] text-mocha-light hover:text-sapphire",
16
+ children: "← profiles"
17
+ }),
18
+ /* @__PURE__ */ jsx("h1", { children: loaded.profile.name }),
19
+ /* @__PURE__ */ jsxs("div", {
20
+ className: "mt-1 flex flex-wrap items-center gap-2 text-[0.9em] text-mocha-light",
21
+ children: [
22
+ /* @__PURE__ */ jsx("code", { children: loaded.profile.id }),
23
+ /* @__PURE__ */ jsx("span", { children: "·" }),
24
+ /* @__PURE__ */ jsxs("span", { children: ["model: ", /* @__PURE__ */ jsx("code", { children: loaded.profile.defaultModel })] })
25
+ ]
26
+ })
27
+ ]
28
+ }),
29
+ /* @__PURE__ */ jsxs("p", {
30
+ className: "muted my-6",
31
+ children: [
32
+ "These settings and files seed every agent spawned from this profile going forward.",
33
+ " ",
34
+ /* @__PURE__ */ jsx("strong", { children: "Existing agents keep their own copies" }),
35
+ " — edits here don't propagate to already-spawned agents."
36
+ ]
37
+ }),
38
+ /* @__PURE__ */ jsx(Tabs, {
39
+ items: [{
40
+ id: "basics",
41
+ label: "1. basics"
42
+ }, {
43
+ id: "skills",
44
+ label: "2. skills"
45
+ }],
46
+ active: tab,
47
+ onChange: (t) => setTab(t)
48
+ }),
49
+ tab === "basics" && /* @__PURE__ */ jsxs("div", { children: [
50
+ /* @__PURE__ */ jsx(SettingsCard, {
51
+ profileId: loaded.profile.id,
52
+ initialName: loaded.profile.name,
53
+ currentModel: loaded.profile.defaultModel,
54
+ modelGroups
55
+ }),
56
+ /* @__PURE__ */ jsx(FileCard, {
57
+ profileId: loaded.profile.id,
58
+ file: "SOUL.md",
59
+ initialContent: loaded.files.soul,
60
+ rows: 14
61
+ }),
62
+ /* @__PURE__ */ jsx(FileCard, {
63
+ profileId: loaded.profile.id,
64
+ file: "IDENTITY.md",
65
+ initialContent: loaded.files.identity,
66
+ rows: 10
67
+ }),
68
+ loaded.files.bootstrap === null ? /* @__PURE__ */ jsxs("section", {
69
+ className: "file-card",
70
+ children: [/* @__PURE__ */ jsx("div", {
71
+ className: "file-head",
72
+ children: /* @__PURE__ */ jsx("h3", { children: "BOOTSTRAP.md" })
73
+ }), /* @__PURE__ */ jsx("p", {
74
+ className: "muted",
75
+ children: "This profile was created without a bootstrap prompt. Spawned agents won't see a first-run intro message."
76
+ })]
77
+ }) : /* @__PURE__ */ jsx(FileCard, {
78
+ profileId: loaded.profile.id,
79
+ file: "BOOTSTRAP.md",
80
+ initialContent: loaded.files.bootstrap,
81
+ rows: 10
82
+ }),
83
+ /* @__PURE__ */ jsx(OptionalFileCard, {
84
+ profileId: loaded.profile.id,
85
+ file: "AGENTS.md",
86
+ initialContent: loaded.files.agents,
87
+ hint: "Peers and routing notes — who this agent can hand off to."
88
+ }),
89
+ /* @__PURE__ */ jsx(OptionalFileCard, {
90
+ profileId: loaded.profile.id,
91
+ file: "TOOLS.md",
92
+ initialContent: loaded.files.tools,
93
+ hint: "Tool playbook. Agent-specific usage notes that go beyond the generic tool descriptions."
94
+ }),
95
+ /* @__PURE__ */ jsx(OptionalFileCard, {
96
+ profileId: loaded.profile.id,
97
+ file: "HEARTBEAT.md",
98
+ initialContent: loaded.files.heartbeat,
99
+ hint: "Tasks the agent should check on scheduled wake-ups. Pair with a trigger whose message is the canned heartbeat prompt."
100
+ })
101
+ ] }),
102
+ tab === "skills" && /* @__PURE__ */ jsx(SkillsCard, {
103
+ profileId: loaded.profile.id,
104
+ initialMode: loaded.profile.skillsMode,
105
+ initialPicked: new Set(loaded.defaultSkills),
106
+ skills
107
+ })
108
+ ] });
109
+ }
110
+ function Tabs({ items, active, onChange }) {
111
+ return /* @__PURE__ */ jsx("nav", {
112
+ role: "tablist",
113
+ className: "-mb-px mb-5 flex gap-1 border-b border-frost",
114
+ children: items.map((it) => /* @__PURE__ */ jsx("button", {
115
+ type: "button",
116
+ role: "tab",
117
+ "aria-selected": active === it.id,
118
+ onClick: () => onChange(it.id),
119
+ className: `unstyled cursor-pointer border-b-2 bg-transparent px-4 py-2 text-[0.9em] font-medium transition-colors ${active === it.id ? "border-sapphire text-sapphire" : "border-transparent text-mocha hover:text-sapphire"}`,
120
+ children: it.label
121
+ }, it.id))
122
+ });
123
+ }
124
+ function statusColor(kind) {
125
+ if (kind === "saved") return "text-sapphire";
126
+ if (kind === "error") return "text-[#9B3D3D]";
127
+ if (kind === "dirty") return "text-mocha";
128
+ return "text-mocha-light";
129
+ }
130
+ function FileCardShell({ title, status, children }) {
131
+ return /* @__PURE__ */ jsxs("section", {
132
+ className: "file-card mb-5 rounded-[16px] border border-frost bg-snow p-5 shadow-baziu-sm",
133
+ children: [/* @__PURE__ */ jsxs("div", {
134
+ className: "mb-2 flex items-baseline justify-between",
135
+ children: [/* @__PURE__ */ jsx("h3", {
136
+ className: "m-0 font-mono text-[0.95em] font-semibold normal-case tracking-normal text-chocolate",
137
+ children: title
138
+ }), status && /* @__PURE__ */ jsx("span", {
139
+ className: `text-[0.82em] ${statusColor(status.kind)}`,
140
+ children: status.message
141
+ })]
142
+ }), children]
143
+ });
144
+ }
145
+ function FileCard({ profileId, file, initialContent, rows = 10 }) {
146
+ const [original, setOriginal] = useState(initialContent);
147
+ const [content, setContent] = useState(initialContent);
148
+ const [status, setStatus] = useState({
149
+ kind: "idle",
150
+ message: ""
151
+ });
152
+ const display = content !== original && status.kind !== "saving" && status.kind !== "error" ? {
153
+ kind: "dirty",
154
+ message: "unsaved changes"
155
+ } : status;
156
+ async function save() {
157
+ setStatus({
158
+ kind: "saving",
159
+ message: "saving…"
160
+ });
161
+ try {
162
+ const res = await fetch(`/api/profiles/${encodeURIComponent(profileId)}/files/${encodeURIComponent(file)}`, {
163
+ method: "PUT",
164
+ headers: { "content-type": "application/json" },
165
+ body: JSON.stringify({ content })
166
+ });
167
+ if (!res.ok && res.status !== 204) {
168
+ const e = await res.json().catch(() => null);
169
+ throw new Error(e?.error ?? res.statusText);
170
+ }
171
+ setOriginal(content);
172
+ setStatus({
173
+ kind: "saved",
174
+ message: "saved"
175
+ });
176
+ } catch (err) {
177
+ setStatus({
178
+ kind: "error",
179
+ message: `error: ${err.message}`
180
+ });
181
+ }
182
+ }
183
+ function revert() {
184
+ setContent(original);
185
+ setStatus({
186
+ kind: "idle",
187
+ message: ""
188
+ });
189
+ }
190
+ return /* @__PURE__ */ jsxs(FileCardShell, {
191
+ title: file,
192
+ status: display,
193
+ children: [/* @__PURE__ */ jsx("textarea", {
194
+ rows,
195
+ value: content,
196
+ onChange: (e) => setContent(e.target.value),
197
+ className: "font-mono text-[0.88em] leading-[1.55]"
198
+ }), /* @__PURE__ */ jsxs("div", {
199
+ className: "mt-3 flex gap-2",
200
+ children: [/* @__PURE__ */ jsx("button", {
201
+ type: "button",
202
+ className: "btn-primary",
203
+ onClick: save,
204
+ disabled: status.kind === "saving",
205
+ children: "save"
206
+ }), /* @__PURE__ */ jsx("button", {
207
+ type: "button",
208
+ className: "ghost-btn",
209
+ onClick: revert,
210
+ children: "revert"
211
+ })]
212
+ })]
213
+ });
214
+ }
215
+ function OptionalFileCard({ profileId, file, initialContent, hint }) {
216
+ const router = useRouter();
217
+ const [creating, setCreating] = useState(false);
218
+ const [status, setStatus] = useState({
219
+ kind: "idle",
220
+ message: ""
221
+ });
222
+ async function createEmpty() {
223
+ setCreating(true);
224
+ setStatus({
225
+ kind: "saving",
226
+ message: "creating…"
227
+ });
228
+ try {
229
+ const res = await fetch(`/api/profiles/${encodeURIComponent(profileId)}/files/${encodeURIComponent(file)}`, {
230
+ method: "PUT",
231
+ headers: { "content-type": "application/json" },
232
+ body: JSON.stringify({ content: "" })
233
+ });
234
+ if (!res.ok && res.status !== 204) {
235
+ const e = await res.json().catch(() => null);
236
+ throw new Error(e?.error ?? res.statusText);
237
+ }
238
+ await router.invalidate();
239
+ } catch (err) {
240
+ setStatus({
241
+ kind: "error",
242
+ message: `error: ${err.message}`
243
+ });
244
+ setCreating(false);
245
+ }
246
+ }
247
+ if (initialContent === null) return /* @__PURE__ */ jsxs(FileCardShell, {
248
+ title: file,
249
+ status,
250
+ children: [/* @__PURE__ */ jsx("p", {
251
+ className: "muted my-1",
252
+ children: hint
253
+ }), /* @__PURE__ */ jsx("div", {
254
+ className: "mt-3 flex gap-2",
255
+ children: /* @__PURE__ */ jsx("button", {
256
+ type: "button",
257
+ className: "btn-primary",
258
+ onClick: createEmpty,
259
+ disabled: creating,
260
+ children: creating ? "creating…" : "create empty"
261
+ })
262
+ })]
263
+ });
264
+ return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("p", {
265
+ className: "muted -mb-3 ml-1 mt-2 text-[0.85em]",
266
+ children: hint
267
+ }), /* @__PURE__ */ jsx(FileCard, {
268
+ profileId,
269
+ file,
270
+ initialContent,
271
+ rows: 10
272
+ })] });
273
+ }
274
+ function SettingsCard({ profileId, initialName, currentModel, modelGroups }) {
275
+ const router = useRouter();
276
+ const [name, setName] = useState(initialName);
277
+ const [defaultModel, setDefaultModel] = useState(currentModel);
278
+ const [status, setStatus] = useState({
279
+ kind: "idle",
280
+ message: ""
281
+ });
282
+ const modelMissing = !modelGroups.flatMap((g) => g.models.map((m) => `${g.provider}:${m}`)).includes(currentModel);
283
+ async function save(e) {
284
+ e.preventDefault();
285
+ setStatus({
286
+ kind: "saving",
287
+ message: "saving…"
288
+ });
289
+ try {
290
+ const res = await fetch(`/api/profiles/${encodeURIComponent(profileId)}`, {
291
+ method: "PATCH",
292
+ headers: { "content-type": "application/json" },
293
+ body: JSON.stringify({
294
+ name: name.trim(),
295
+ defaultModel: defaultModel.trim()
296
+ })
297
+ });
298
+ if (!res.ok) {
299
+ const e2 = await res.json().catch(() => null);
300
+ throw new Error(e2?.error ?? res.statusText);
301
+ }
302
+ await router.invalidate();
303
+ setStatus({
304
+ kind: "saved",
305
+ message: "saved"
306
+ });
307
+ } catch (err) {
308
+ setStatus({
309
+ kind: "error",
310
+ message: `error: ${err.message}`
311
+ });
312
+ }
313
+ }
314
+ return /* @__PURE__ */ jsx(FileCardShell, {
315
+ title: "settings",
316
+ status,
317
+ children: /* @__PURE__ */ jsxs("form", {
318
+ onSubmit: save,
319
+ children: [/* @__PURE__ */ jsxs("div", {
320
+ className: "flex gap-4",
321
+ children: [/* @__PURE__ */ jsxs("label", {
322
+ className: "flex-1",
323
+ children: ["name", /* @__PURE__ */ jsx("input", {
324
+ value: name,
325
+ onChange: (e) => setName(e.target.value)
326
+ })]
327
+ }), /* @__PURE__ */ jsxs("label", {
328
+ className: "flex-1",
329
+ children: ["default model", modelGroups.length === 0 ? /* @__PURE__ */ jsx("select", {
330
+ disabled: true,
331
+ children: /* @__PURE__ */ jsx("option", { children: "(no models available — enable on /config)" })
332
+ }) : /* @__PURE__ */ jsxs("select", {
333
+ value: defaultModel,
334
+ onChange: (e) => setDefaultModel(e.target.value),
335
+ children: [modelMissing && /* @__PURE__ */ jsxs("option", {
336
+ value: currentModel,
337
+ children: [currentModel, " (not in enabled list)"]
338
+ }), modelGroups.map((g) => /* @__PURE__ */ jsx("optgroup", {
339
+ label: g.provider,
340
+ children: g.models.map((m) => /* @__PURE__ */ jsx("option", {
341
+ value: `${g.provider}:${m}`,
342
+ children: `${g.provider}:${m}`
343
+ }, m))
344
+ }, g.provider))]
345
+ })]
346
+ })]
347
+ }), /* @__PURE__ */ jsx("div", {
348
+ className: "mt-3 flex gap-2",
349
+ children: /* @__PURE__ */ jsx("button", {
350
+ type: "submit",
351
+ disabled: status.kind === "saving",
352
+ children: "save settings"
353
+ })
354
+ })]
355
+ })
356
+ });
357
+ }
358
+ function SkillsCard({ profileId, initialMode, initialPicked, skills }) {
359
+ const router = useRouter();
360
+ const [mode, setMode] = useState(initialMode);
361
+ const [picked, setPicked] = useState(initialPicked);
362
+ const [status, setStatus] = useState({
363
+ kind: "idle",
364
+ message: ""
365
+ });
366
+ function toggle(name) {
367
+ setPicked((prev) => {
368
+ const next = new Set(prev);
369
+ if (next.has(name)) next.delete(name);
370
+ else next.add(name);
371
+ return next;
372
+ });
373
+ }
374
+ async function save(e) {
375
+ e.preventDefault();
376
+ setStatus({
377
+ kind: "saving",
378
+ message: "saving…"
379
+ });
380
+ try {
381
+ const res = await fetch(`/api/profiles/${encodeURIComponent(profileId)}`, {
382
+ method: "PATCH",
383
+ headers: { "content-type": "application/json" },
384
+ body: JSON.stringify({
385
+ skillsMode: mode,
386
+ defaultSkills: mode === "selected" ? Array.from(picked) : []
387
+ })
388
+ });
389
+ if (!res.ok) {
390
+ const e2 = await res.json().catch(() => null);
391
+ throw new Error(e2?.error ?? res.statusText);
392
+ }
393
+ await router.invalidate();
394
+ setStatus({
395
+ kind: "saved",
396
+ message: "saved"
397
+ });
398
+ } catch (err) {
399
+ setStatus({
400
+ kind: "error",
401
+ message: `error: ${err.message}`
402
+ });
403
+ }
404
+ }
405
+ return /* @__PURE__ */ jsxs(FileCardShell, {
406
+ title: "skills",
407
+ status,
408
+ children: [/* @__PURE__ */ jsx("p", {
409
+ className: "muted my-2",
410
+ children: "Choose what agents spawned from this profile inherit. Existing agents aren't affected — they keep whatever skills they were spawned with."
411
+ }), /* @__PURE__ */ jsxs("form", {
412
+ onSubmit: save,
413
+ children: [
414
+ /* @__PURE__ */ jsxs("label", {
415
+ className: "my-2 flex cursor-pointer items-start gap-2",
416
+ children: [/* @__PURE__ */ jsx("input", {
417
+ type: "radio",
418
+ checked: mode === "all",
419
+ onChange: () => setMode("all")
420
+ }), /* @__PURE__ */ jsxs("span", { children: [/* @__PURE__ */ jsx("strong", { children: "allow all skills" }), " — every skill on disk is attached at spawn."] })]
421
+ }),
422
+ /* @__PURE__ */ jsxs("label", {
423
+ className: "my-2 flex cursor-pointer items-start gap-2",
424
+ children: [/* @__PURE__ */ jsx("input", {
425
+ type: "radio",
426
+ checked: mode === "selected",
427
+ onChange: () => setMode("selected")
428
+ }), /* @__PURE__ */ jsxs("span", { children: [/* @__PURE__ */ jsx("strong", { children: "select skills" }), " — attach only the ones ticked below."] })]
429
+ }),
430
+ /* @__PURE__ */ jsx("div", {
431
+ className: `mt-3 max-h-[22rem] overflow-y-auto rounded-md border border-frost p-3 ${mode === "all" ? "pointer-events-none opacity-50" : ""}`,
432
+ children: skills.length === 0 ? /* @__PURE__ */ jsxs("p", {
433
+ className: "muted",
434
+ children: [
435
+ "No skills installed yet. Import some on ",
436
+ /* @__PURE__ */ jsx("a", {
437
+ href: "/skills",
438
+ children: "/skills"
439
+ }),
440
+ "."
441
+ ]
442
+ }) : skills.map((s) => /* @__PURE__ */ jsxs("label", {
443
+ className: "my-1.5 flex cursor-pointer items-start gap-2",
444
+ children: [/* @__PURE__ */ jsx("input", {
445
+ type: "checkbox",
446
+ checked: picked.has(s.name),
447
+ onChange: () => toggle(s.name)
448
+ }), /* @__PURE__ */ jsxs("span", { children: [/* @__PURE__ */ jsx("code", { children: s.name }), s.description && /* @__PURE__ */ jsxs("span", {
449
+ className: "text-[0.9em] text-mocha-light",
450
+ children: [" — ", s.description]
451
+ })] })]
452
+ }, s.name))
453
+ }),
454
+ /* @__PURE__ */ jsx("div", {
455
+ className: "mt-3 flex gap-2",
456
+ children: /* @__PURE__ */ jsx("button", {
457
+ type: "submit",
458
+ disabled: status.kind === "saving",
459
+ children: "save skills"
460
+ })
461
+ })
462
+ ]
463
+ })]
464
+ });
465
+ }
466
+ //#endregion
467
+ export { ProfileDetailPage as component };
@@ -0,0 +1,28 @@
1
+ import { t as createServerFn } from "../server.js";
2
+ import { t as createServerRpc } from "./createServerRpc-CeKECg65.js";
3
+ import { n as daemonClient, r as ApiClientError } from "./daemon-client-2NRMzlTr.js";
4
+ //#region src/routes/groups/$id/index.tsx?tss-serverfn-split
5
+ var fetchGroup_createServerFn_handler = createServerRpc({
6
+ id: "c64d52cbb25600424729185370431bf1182e1058dad2eacd250820ca1d62dae0",
7
+ name: "fetchGroup",
8
+ filename: "src/routes/groups/$id/index.tsx"
9
+ }, (opts) => fetchGroup.__executeServer(opts));
10
+ var fetchGroup = createServerFn({ method: "POST" }).inputValidator((d) => d).handler(fetchGroup_createServerFn_handler, async ({ data }) => {
11
+ const c = daemonClient();
12
+ let group;
13
+ try {
14
+ group = await c.get(`/api/groups/${encodeURIComponent(data.id)}`);
15
+ } catch (err) {
16
+ if (err instanceof ApiClientError && err.status === 404) return null;
17
+ throw err;
18
+ }
19
+ const [all, profileGroups] = await Promise.all([c.get("/api/agents?includeArchived=true"), c.get("/api/profile-groups")]);
20
+ const members = all.filter((a) => a.groupId === group.id);
21
+ return {
22
+ group,
23
+ members,
24
+ profileGroups
25
+ };
26
+ });
27
+ //#endregion
28
+ export { fetchGroup_createServerFn_handler };
@@ -0,0 +1,38 @@
1
+ import { t as createServerFn } from "../server.js";
2
+ import { t as createServerRpc } from "./createServerRpc-CeKECg65.js";
3
+ import { n as daemonClient, r as ApiClientError } from "./daemon-client-2NRMzlTr.js";
4
+ //#region src/routes/agents/$id/index.tsx?tss-serverfn-split
5
+ var fetchAgent_createServerFn_handler = createServerRpc({
6
+ id: "846c9081aed17057351730985f133b0aab67a5dabfca9562552829a90ff30849",
7
+ name: "fetchAgent",
8
+ filename: "src/routes/agents/$id/index.tsx"
9
+ }, (opts) => fetchAgent.__executeServer(opts));
10
+ var fetchAgent = createServerFn({ method: "POST" }).inputValidator((d) => d).handler(fetchAgent_createServerFn_handler, async ({ data }) => {
11
+ const c = daemonClient();
12
+ let resolved;
13
+ try {
14
+ resolved = await c.get(`/api/agents/${encodeURIComponent(data.id)}`);
15
+ } catch (err) {
16
+ if (err instanceof ApiClientError && err.status === 404) return null;
17
+ throw err;
18
+ }
19
+ const [msgs, head, groups, skills, models, telegramConfig] = await Promise.all([
20
+ c.get(`/api/agents/${encodeURIComponent(resolved.agent.id)}/sessions/messages`),
21
+ c.get(`/api/agents/${encodeURIComponent(resolved.agent.id)}/sessions/head`),
22
+ c.get("/api/groups"),
23
+ c.get("/api/skills"),
24
+ c.get("/api/config/available-models"),
25
+ c.get("/api/config/telegram").catch(() => ({ configured: false }))
26
+ ]);
27
+ return {
28
+ resolved,
29
+ initialMessages: msgs.messages,
30
+ sessionHead: head,
31
+ groups,
32
+ skills,
33
+ modelGroups: models.groups,
34
+ telegramConfigured: telegramConfig.configured
35
+ };
36
+ });
37
+ //#endregion
38
+ export { fetchAgent_createServerFn_handler };