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,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/memory.tsx?tss-serverfn-split
5
+ var fetchMemory_createServerFn_handler = createServerRpc({
6
+ id: "457cdd4932d22a1e823c50781026fbabb2e9d4d6b5ac9a763bb74500f2b02538",
7
+ name: "fetchMemory",
8
+ filename: "src/routes/groups/$id/memory.tsx"
9
+ }, (opts) => fetchMemory.__executeServer(opts));
10
+ var fetchMemory = createServerFn({ method: "POST" }).inputValidator((d) => d).handler(fetchMemory_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 [entries, agents] = await Promise.all([c.get(`/api/groups/${encodeURIComponent(group.id)}/memory`), c.get("/api/agents?includeArchived=true")]);
20
+ const memberCount = agents.filter((a) => a.groupId === group.id).length;
21
+ return {
22
+ group,
23
+ memberCount,
24
+ entries
25
+ };
26
+ });
27
+ //#endregion
28
+ export { fetchMemory_createServerFn_handler };
@@ -0,0 +1,284 @@
1
+ import { t as Route } from "./memory-Ns2-Z31p.js";
2
+ import { useEffect, useRef, useState } from "react";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
+ //#region src/routes/groups/$id/memory.tsx?tsr-split=component
5
+ function encodeKey(key) {
6
+ return key.split("/").map(encodeURIComponent).join("/");
7
+ }
8
+ function MemoryPage() {
9
+ const { group, memberCount, entries: initialEntries } = Route.useLoaderData();
10
+ const groupId = group.id;
11
+ const [rows, setRows] = useState(() => initialEntries.map((e) => ({
12
+ key: e.key,
13
+ preview: e.content.slice(0, 80)
14
+ })));
15
+ const [isSearch, setIsSearch] = useState(false);
16
+ const [query, setQuery] = useState("");
17
+ const [selectedKey, setSelectedKey] = useState(null);
18
+ const [mode, setMode] = useState("none");
19
+ const [keyInput, setKeyInput] = useState("");
20
+ const [content, setContent] = useState("");
21
+ const [status, setStatus] = useState(null);
22
+ const searchTimer = useRef(null);
23
+ async function loadList(q) {
24
+ try {
25
+ const url = q.trim().length > 0 ? `/api/groups/${encodeURIComponent(groupId)}/memory/search?q=${encodeURIComponent(q)}&limit=50` : `/api/groups/${encodeURIComponent(groupId)}/memory`;
26
+ const res = await fetch(url);
27
+ if (!res.ok) {
28
+ const body = await res.json().catch(() => null);
29
+ throw new Error(body?.error ?? res.statusText);
30
+ }
31
+ const data = await res.json();
32
+ if (q.trim().length > 0) {
33
+ setRows(data.map((h) => ({
34
+ key: h.key,
35
+ preview: h.snippet,
36
+ score: h.score
37
+ })));
38
+ setIsSearch(true);
39
+ } else {
40
+ setRows(data.map((e) => ({
41
+ key: e.key,
42
+ preview: e.content.slice(0, 80)
43
+ })));
44
+ setIsSearch(false);
45
+ }
46
+ } catch (err) {
47
+ setStatus({
48
+ msg: `error: ${err.message}`,
49
+ kind: "error"
50
+ });
51
+ }
52
+ }
53
+ useEffect(() => {
54
+ if (searchTimer.current) clearTimeout(searchTimer.current);
55
+ searchTimer.current = setTimeout(() => {
56
+ loadList(query);
57
+ }, 200);
58
+ return () => {
59
+ if (searchTimer.current) clearTimeout(searchTimer.current);
60
+ };
61
+ }, [query]);
62
+ async function openEntry(key) {
63
+ setSelectedKey(key);
64
+ setMode("edit");
65
+ setStatus({
66
+ msg: "loading…",
67
+ kind: "info"
68
+ });
69
+ try {
70
+ const res = await fetch(`/api/groups/${encodeURIComponent(groupId)}/memory/${encodeKey(key)}`);
71
+ if (!res.ok) {
72
+ const body = await res.json().catch(() => null);
73
+ throw new Error(body?.error ?? res.statusText);
74
+ }
75
+ const entry = await res.json();
76
+ setKeyInput(entry.key);
77
+ setContent(entry.content ?? "");
78
+ setStatus({
79
+ msg: `loaded ${entry.key}`,
80
+ kind: "info"
81
+ });
82
+ } catch (err) {
83
+ setStatus({
84
+ msg: `error: ${err.message}`,
85
+ kind: "error"
86
+ });
87
+ }
88
+ }
89
+ function newEntry() {
90
+ setSelectedKey(null);
91
+ setMode("new");
92
+ setKeyInput("");
93
+ setContent("");
94
+ setStatus({
95
+ msg: "new entry — type a key and content, then save",
96
+ kind: "info"
97
+ });
98
+ }
99
+ async function save() {
100
+ const key = keyInput.trim();
101
+ if (!key) {
102
+ setStatus({
103
+ msg: "key is required",
104
+ kind: "error"
105
+ });
106
+ return;
107
+ }
108
+ try {
109
+ const res = await fetch(`/api/groups/${encodeURIComponent(groupId)}/memory/${encodeKey(key)}`, {
110
+ method: "PUT",
111
+ headers: { "content-type": "application/json" },
112
+ body: JSON.stringify({ content })
113
+ });
114
+ if (!res.ok) {
115
+ const body = await res.json().catch(() => null);
116
+ throw new Error(body?.error ?? res.statusText);
117
+ }
118
+ setSelectedKey(key);
119
+ setMode("edit");
120
+ setStatus({
121
+ msg: "saved",
122
+ kind: "info"
123
+ });
124
+ await loadList(query);
125
+ } catch (err) {
126
+ setStatus({
127
+ msg: `error: ${err.message}`,
128
+ kind: "error"
129
+ });
130
+ }
131
+ }
132
+ async function del() {
133
+ if (!selectedKey) return;
134
+ if (!confirm(`delete ${selectedKey}?`)) return;
135
+ try {
136
+ const res = await fetch(`/api/groups/${encodeURIComponent(groupId)}/memory/${encodeKey(selectedKey)}`, { method: "DELETE" });
137
+ if (!res.ok && res.status !== 204) {
138
+ const body = await res.json().catch(() => null);
139
+ throw new Error(body?.error ?? res.statusText);
140
+ }
141
+ setSelectedKey(null);
142
+ setMode("none");
143
+ setKeyInput("");
144
+ setContent("");
145
+ setStatus({
146
+ msg: "deleted",
147
+ kind: "info"
148
+ });
149
+ await loadList(query);
150
+ } catch (err) {
151
+ setStatus({
152
+ msg: `error: ${err.message}`,
153
+ kind: "error"
154
+ });
155
+ }
156
+ }
157
+ const canSave = mode !== "none" && keyInput.trim().length > 0;
158
+ const canDelete = mode === "edit" && selectedKey !== null;
159
+ return /* @__PURE__ */ jsxs("main", {
160
+ className: "mx-auto max-w-5xl px-6 py-8",
161
+ children: [/* @__PURE__ */ jsxs("header", {
162
+ className: "mb-6",
163
+ children: [/* @__PURE__ */ jsxs("h1", {
164
+ className: "font-serif text-3xl text-foreground",
165
+ children: [
166
+ group.name,
167
+ " ",
168
+ /* @__PURE__ */ jsx("span", {
169
+ className: "text-muted-foreground text-base",
170
+ children: "/ shared memory"
171
+ })
172
+ ]
173
+ }), /* @__PURE__ */ jsxs("p", {
174
+ className: "text-muted-foreground text-sm mt-1",
175
+ children: [
176
+ "BM25-indexed markdown notes shared by every agent in",
177
+ " ",
178
+ /* @__PURE__ */ jsx("a", {
179
+ href: `/groups/${encodeURIComponent(group.id)}`,
180
+ className: "font-mono underline",
181
+ children: group.id
182
+ }),
183
+ " ",
184
+ "(",
185
+ memberCount,
186
+ " member",
187
+ memberCount === 1 ? "" : "s",
188
+ "). Anything written here is visible to every member; per-agent notes belong in the agent's own",
189
+ " ",
190
+ /* @__PURE__ */ jsx("code", {
191
+ className: "font-mono",
192
+ children: "IDENTITY.md"
193
+ }),
194
+ " via ",
195
+ /* @__PURE__ */ jsx("code", { children: "home_write" }),
196
+ "."
197
+ ]
198
+ })]
199
+ }), /* @__PURE__ */ jsxs("div", {
200
+ className: "grid grid-cols-1 gap-6 lg:grid-cols-[320px_1fr]",
201
+ children: [/* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsxs("div", {
202
+ className: "overflow-hidden rounded-[16px] border border-frost bg-snow",
203
+ children: [/* @__PURE__ */ jsx("div", {
204
+ className: "border-b border-frost p-2",
205
+ children: /* @__PURE__ */ jsx("input", {
206
+ type: "text",
207
+ placeholder: "search (BM25)...",
208
+ autoComplete: "off",
209
+ value: query,
210
+ onChange: (e) => setQuery(e.target.value)
211
+ })
212
+ }), /* @__PURE__ */ jsx("div", {
213
+ className: "max-h-[520px] overflow-y-auto",
214
+ children: rows.length === 0 ? /* @__PURE__ */ jsx("div", {
215
+ className: "p-8 text-center text-mocha-light",
216
+ children: "no entries"
217
+ }) : rows.map((r) => {
218
+ return /* @__PURE__ */ jsxs("button", {
219
+ type: "button",
220
+ onClick: () => openEntry(r.key),
221
+ className: `unstyled block w-full cursor-pointer border-b border-frost/50 px-3.5 py-2 text-left font-mono text-[0.84em] transition-colors last:border-b-0 hover:bg-sapphire-glow ${r.key === selectedKey ? "bg-sapphire-glow font-medium text-sapphire-deep" : ""}`,
222
+ children: [
223
+ isSearch && r.score !== void 0 && /* @__PURE__ */ jsx("span", {
224
+ className: "float-right text-[0.75em] text-sapphire",
225
+ children: r.score.toFixed(2)
226
+ }),
227
+ r.key,
228
+ r.preview && /* @__PURE__ */ jsx("span", {
229
+ className: "mt-1 block text-[0.9em] font-normal text-mocha-light",
230
+ children: r.preview
231
+ })
232
+ ]
233
+ }, r.key);
234
+ })
235
+ })]
236
+ }), /* @__PURE__ */ jsx("button", {
237
+ type: "button",
238
+ className: "ghost-btn mt-3 w-full",
239
+ onClick: newEntry,
240
+ children: "+ new entry"
241
+ })] }), /* @__PURE__ */ jsxs("div", { children: [
242
+ /* @__PURE__ */ jsx("div", {
243
+ className: "mb-3 flex items-center gap-2",
244
+ children: /* @__PURE__ */ jsx("input", {
245
+ type: "text",
246
+ placeholder: "key (e.g. prefs/hiking.md)",
247
+ value: keyInput,
248
+ onChange: (e) => setKeyInput(e.target.value),
249
+ disabled: mode !== "new",
250
+ className: "flex-1 font-mono"
251
+ })
252
+ }),
253
+ /* @__PURE__ */ jsx("textarea", {
254
+ placeholder: "select an entry on the left, or create a new one.",
255
+ value: content,
256
+ onChange: (e) => setContent(e.target.value),
257
+ className: "min-h-[360px] w-full font-mono text-[0.9em] leading-[1.55]"
258
+ }),
259
+ /* @__PURE__ */ jsxs("div", {
260
+ className: "mt-3 flex gap-2",
261
+ children: [/* @__PURE__ */ jsx("button", {
262
+ type: "button",
263
+ className: "btn-primary",
264
+ onClick: save,
265
+ disabled: !canSave,
266
+ children: "save"
267
+ }), /* @__PURE__ */ jsx("button", {
268
+ type: "button",
269
+ className: "ghost-btn",
270
+ onClick: del,
271
+ disabled: !canDelete,
272
+ children: "delete"
273
+ })]
274
+ }),
275
+ status && /* @__PURE__ */ jsx("p", {
276
+ className: `mt-2 text-[0.9em] ${status.kind === "error" ? "text-[#9B3D3D]" : "text-mocha-light"}`,
277
+ children: status.msg
278
+ })
279
+ ] })]
280
+ })]
281
+ });
282
+ }
283
+ //#endregion
284
+ export { MemoryPage as component };
@@ -0,0 +1,16 @@
1
+ import { t as createServerFn } from "../server.js";
2
+ import { t as createSsrRpc } from "./createSsrRpc-ZBGxhl8t.js";
3
+ import { createFileRoute, lazyRouteComponent, redirect } from "@tanstack/react-router";
4
+ //#region src/routes/groups/$id/memory.tsx
5
+ var $$splitComponentImporter = () => import("./memory-CQaqWnyM.js");
6
+ var fetchMemory = createServerFn({ method: "POST" }).inputValidator((d) => d).handler(createSsrRpc("457cdd4932d22a1e823c50781026fbabb2e9d4d6b5ac9a763bb74500f2b02538"));
7
+ var Route = createFileRoute("/groups/$id/memory")({
8
+ loader: async ({ params }) => {
9
+ const data = await fetchMemory({ data: { id: params.id } });
10
+ if (!data) throw redirect({ to: "/groups" });
11
+ return data;
12
+ },
13
+ component: lazyRouteComponent($$splitComponentImporter, "component")
14
+ });
15
+ //#endregion
16
+ export { Route as t };
@@ -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 } from "./daemon-client-2NRMzlTr.js";
4
+ //#region src/routes/profile-groups/index.tsx?tss-serverfn-split
5
+ var fetchProfileGroupsData_createServerFn_handler = createServerRpc({
6
+ id: "be2ab9d2d20bd46baa655e08a8f6f0c2161b01657d0362564a58edeaf2195a31",
7
+ name: "fetchProfileGroupsData",
8
+ filename: "src/routes/profile-groups/index.tsx"
9
+ }, (opts) => fetchProfileGroupsData.__executeServer(opts));
10
+ var fetchProfileGroupsData = createServerFn({ method: "GET" }).handler(fetchProfileGroupsData_createServerFn_handler, async () => {
11
+ const c = daemonClient();
12
+ const [profileGroups, groups, profiles, models, templates] = await Promise.all([
13
+ c.get("/api/profile-groups"),
14
+ c.get("/api/groups"),
15
+ c.get("/api/profiles"),
16
+ c.get("/api/config/available-models"),
17
+ c.get("/api/profiles/_/templates")
18
+ ]);
19
+ return {
20
+ profileGroups,
21
+ groups,
22
+ profiles,
23
+ modelGroups: models.groups,
24
+ userMdDefault: templates.userMd
25
+ };
26
+ });
27
+ //#endregion
28
+ export { fetchProfileGroupsData_createServerFn_handler };
@@ -0,0 +1,208 @@
1
+ import { t as Route } from "./profile-groups-aoJleXHP.js";
2
+ import { t as Button } from "./Button-Dsnw22OF.js";
3
+ import { t as SpawnTeamModal } from "./SpawnTeamModal-dSN421k_.js";
4
+ import { t as MembersEditor } from "./MembersEditor-BWQztvrX.js";
5
+ import { t as TemplatesTabs } from "./TemplatesTabs---7h5GYa.js";
6
+ import { useState } from "react";
7
+ import { useRouter } from "@tanstack/react-router";
8
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
9
+ //#region src/routes/profile-groups/index.tsx?tsr-split=component
10
+ function ProfileGroupsPage() {
11
+ const { profileGroups, groups, profiles, modelGroups, userMdDefault } = Route.useLoaderData();
12
+ const router = useRouter();
13
+ const [spawningId, setSpawningId] = useState(null);
14
+ async function del(id) {
15
+ if (!confirm("delete this profile group? (does not affect spawned agents)")) return;
16
+ const res = await fetch(`/api/profile-groups/${id}`, { method: "DELETE" });
17
+ if (!res.ok && res.status !== 204) {
18
+ const e = await res.json().catch(() => null);
19
+ alert(e?.error ?? res.statusText);
20
+ return;
21
+ }
22
+ await router.invalidate();
23
+ }
24
+ return /* @__PURE__ */ jsxs("div", { children: [
25
+ /* @__PURE__ */ jsx(TemplatesTabs, {}),
26
+ /* @__PURE__ */ jsx("h1", { children: "profile groups" }),
27
+ /* @__PURE__ */ jsx("p", {
28
+ className: "muted",
29
+ children: "A profile group is a reusable team template. Each one holds an ordered list of members — profile + agent-name + optional overrides — that get replayed as a single transactional spawn into a target group."
30
+ }),
31
+ /* @__PURE__ */ jsx(CreateProfileGroupForm, {
32
+ profiles,
33
+ modelGroups,
34
+ userMdDefault,
35
+ onCreated: () => router.invalidate()
36
+ }),
37
+ /* @__PURE__ */ jsxs("table", { children: [/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [
38
+ /* @__PURE__ */ jsx("th", { children: "id" }),
39
+ /* @__PURE__ */ jsx("th", { children: "name" }),
40
+ /* @__PURE__ */ jsx("th", { children: "members" }),
41
+ /* @__PURE__ */ jsx("th", {})
42
+ ] }) }), /* @__PURE__ */ jsxs("tbody", { children: [profileGroups.length === 0 && /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx("td", {
43
+ colSpan: 4,
44
+ className: "muted",
45
+ children: "no profile groups yet"
46
+ }) }), profileGroups.map((g) => /* @__PURE__ */ jsxs("tr", { children: [
47
+ /* @__PURE__ */ jsx("td", { children: /* @__PURE__ */ jsx("a", {
48
+ href: `/profile-groups/${g.id}`,
49
+ children: /* @__PURE__ */ jsx("code", { children: g.id })
50
+ }) }),
51
+ /* @__PURE__ */ jsx("td", { children: g.name }),
52
+ /* @__PURE__ */ jsx("td", { children: g.memberCount }),
53
+ /* @__PURE__ */ jsxs("td", {
54
+ className: "flex gap-2",
55
+ children: [/* @__PURE__ */ jsx(Button, {
56
+ variant: "primary",
57
+ disabled: g.memberCount === 0,
58
+ title: g.memberCount === 0 ? "add at least one member before spawning" : void 0,
59
+ onClick: () => setSpawningId(g.id),
60
+ children: "spawn team"
61
+ }), /* @__PURE__ */ jsx(Button, {
62
+ variant: "danger",
63
+ onClick: () => del(g.id),
64
+ children: "delete"
65
+ })]
66
+ })
67
+ ] }, g.id))] })] }),
68
+ spawningId && /* @__PURE__ */ jsx(SpawnTeamModal, {
69
+ profileGroup: profileGroups.find((g) => g.id === spawningId),
70
+ groups,
71
+ onClose: () => setSpawningId(null),
72
+ onSpawned: (slug) => {
73
+ setSpawningId(null);
74
+ router.navigate({
75
+ to: "/groups/$id",
76
+ params: { id: slug }
77
+ });
78
+ }
79
+ })
80
+ ] });
81
+ }
82
+ function CreateProfileGroupForm({ profiles, modelGroups, userMdDefault, onCreated }) {
83
+ const [id, setId] = useState("");
84
+ const [name, setName] = useState("");
85
+ const [userMd, setUserMd] = useState(userMdDefault);
86
+ const [members, setMembers] = useState([]);
87
+ const [err, setErr] = useState(null);
88
+ const [submitting, setSubmitting] = useState(false);
89
+ async function submit(e) {
90
+ e.preventDefault();
91
+ setErr(null);
92
+ if (!id.trim()) {
93
+ setErr("id is required");
94
+ return;
95
+ }
96
+ setSubmitting(true);
97
+ try {
98
+ const createBody = { id: id.trim() };
99
+ if (name.trim()) createBody.name = name.trim();
100
+ if (userMd) createBody.userMd = userMd;
101
+ const createRes = await fetch("/api/profile-groups", {
102
+ method: "POST",
103
+ headers: { "content-type": "application/json" },
104
+ body: JSON.stringify(createBody)
105
+ });
106
+ if (!createRes.ok) {
107
+ const e2 = await createRes.json().catch(() => null);
108
+ throw new Error(e2?.error ?? createRes.statusText);
109
+ }
110
+ if (members.length > 0) {
111
+ const membersRes = await fetch(`/api/profile-groups/${id.trim()}/members`, {
112
+ method: "PUT",
113
+ headers: { "content-type": "application/json" },
114
+ body: JSON.stringify({ members })
115
+ });
116
+ if (!membersRes.ok) {
117
+ const e2 = await membersRes.json().catch(() => null);
118
+ throw new Error(`group created, member save failed: ${e2?.error ?? membersRes.statusText}`);
119
+ }
120
+ }
121
+ setId("");
122
+ setName("");
123
+ setUserMd(userMdDefault);
124
+ setMembers([]);
125
+ onCreated();
126
+ } catch (e2) {
127
+ setErr(e2.message);
128
+ } finally {
129
+ setSubmitting(false);
130
+ }
131
+ }
132
+ return /* @__PURE__ */ jsxs("form", {
133
+ className: "card",
134
+ onSubmit: submit,
135
+ children: [
136
+ /* @__PURE__ */ jsx("h3", { children: "create profile group" }),
137
+ err && /* @__PURE__ */ jsx("div", {
138
+ className: "err",
139
+ children: err
140
+ }),
141
+ /* @__PURE__ */ jsxs("div", {
142
+ className: "flex gap-4",
143
+ children: [/* @__PURE__ */ jsxs("label", {
144
+ className: "flex-1",
145
+ children: ["id (slug)", /* @__PURE__ */ jsx("input", {
146
+ value: id,
147
+ onChange: (e) => setId(e.target.value),
148
+ required: true,
149
+ placeholder: "platform-team"
150
+ })]
151
+ }), /* @__PURE__ */ jsxs("label", {
152
+ className: "flex-1",
153
+ children: ["name", /* @__PURE__ */ jsx("input", {
154
+ value: name,
155
+ onChange: (e) => setName(e.target.value),
156
+ placeholder: "Platform Team"
157
+ })]
158
+ })]
159
+ }),
160
+ /* @__PURE__ */ jsxs("label", { children: ["starter USER.md (seeded into freshly-created target groups; prefilled with the built-in default — edit to customise)", /* @__PURE__ */ jsx("textarea", {
161
+ rows: 3,
162
+ value: userMd,
163
+ onChange: (e) => setUserMd(e.target.value),
164
+ className: "font-mono text-[0.88em] leading-[1.55]"
165
+ })] }),
166
+ /* @__PURE__ */ jsxs("div", {
167
+ className: "mt-4",
168
+ children: [
169
+ /* @__PURE__ */ jsx("h4", {
170
+ className: "mb-1 text-[0.95em] font-medium",
171
+ children: "members"
172
+ }),
173
+ /* @__PURE__ */ jsxs("p", {
174
+ className: "muted mb-2 text-[0.88em]",
175
+ children: [
176
+ "Each member becomes one agent when the team is spawned. You can also configure members later from the detail page.",
177
+ " ",
178
+ profiles.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
179
+ "Available profiles:",
180
+ " ",
181
+ profiles.map((p, i) => /* @__PURE__ */ jsxs("span", { children: [i > 0 && ", ", /* @__PURE__ */ jsx("code", { children: p.id })] }, p.id)),
182
+ "."
183
+ ] })
184
+ ]
185
+ }),
186
+ /* @__PURE__ */ jsx(MembersEditor, {
187
+ members,
188
+ onChange: setMembers,
189
+ profiles,
190
+ modelGroups,
191
+ emptyHint: "No members configured yet — add one to pick a profile for each team member."
192
+ })
193
+ ]
194
+ }),
195
+ /* @__PURE__ */ jsx("div", {
196
+ className: "mt-4",
197
+ children: /* @__PURE__ */ jsx(Button, {
198
+ variant: "primary",
199
+ type: "submit",
200
+ disabled: submitting,
201
+ children: submitting ? "creating…" : "create"
202
+ })
203
+ })
204
+ ]
205
+ });
206
+ }
207
+ //#endregion
208
+ export { ProfileGroupsPage as component };
@@ -0,0 +1,12 @@
1
+ import { t as createServerFn } from "../server.js";
2
+ import { t as createSsrRpc } from "./createSsrRpc-ZBGxhl8t.js";
3
+ import { createFileRoute, lazyRouteComponent } from "@tanstack/react-router";
4
+ //#region src/routes/profile-groups/index.tsx
5
+ var $$splitComponentImporter = () => import("./profile-groups-D21MYoLM.js");
6
+ var fetchProfileGroupsData = createServerFn({ method: "GET" }).handler(createSsrRpc("be2ab9d2d20bd46baa655e08a8f6f0c2161b01657d0362564a58edeaf2195a31"));
7
+ var Route = createFileRoute("/profile-groups/")({
8
+ loader: () => fetchProfileGroupsData(),
9
+ component: lazyRouteComponent($$splitComponentImporter, "component")
10
+ });
11
+ //#endregion
12
+ export { Route as t };
@@ -0,0 +1,26 @@
1
+ import { t as createServerFn } from "../server.js";
2
+ import { t as createServerRpc } from "./createServerRpc-CeKECg65.js";
3
+ import { n as daemonClient } from "./daemon-client-2NRMzlTr.js";
4
+ //#region src/routes/profiles/index.tsx?tss-serverfn-split
5
+ var fetchProfiles_createServerFn_handler = createServerRpc({
6
+ id: "d3850ae8e275fc6af55540b50dd3cc6e84712ae5b9621a8a79b24514a1271cfb",
7
+ name: "fetchProfiles",
8
+ filename: "src/routes/profiles/index.tsx"
9
+ }, (opts) => fetchProfiles.__executeServer(opts));
10
+ var fetchProfiles = createServerFn({ method: "GET" }).handler(fetchProfiles_createServerFn_handler, async () => {
11
+ const c = daemonClient();
12
+ const [profiles, models, skills, templates] = await Promise.all([
13
+ c.get("/api/profiles"),
14
+ c.get("/api/config/available-models"),
15
+ c.get("/api/skills"),
16
+ c.get("/api/profiles/_/templates")
17
+ ]);
18
+ return {
19
+ profiles,
20
+ modelGroups: models.groups,
21
+ skills,
22
+ templates
23
+ };
24
+ });
25
+ //#endregion
26
+ export { fetchProfiles_createServerFn_handler };
@@ -0,0 +1,12 @@
1
+ import { t as createServerFn } from "../server.js";
2
+ import { t as createSsrRpc } from "./createSsrRpc-ZBGxhl8t.js";
3
+ import { createFileRoute, lazyRouteComponent } from "@tanstack/react-router";
4
+ //#region src/routes/profiles/index.tsx
5
+ var $$splitComponentImporter = () => import("./profiles-LxcC_L6n.js");
6
+ var fetchProfiles = createServerFn({ method: "GET" }).handler(createSsrRpc("d3850ae8e275fc6af55540b50dd3cc6e84712ae5b9621a8a79b24514a1271cfb"));
7
+ var Route = createFileRoute("/profiles/")({
8
+ loader: () => fetchProfiles(),
9
+ component: lazyRouteComponent($$splitComponentImporter, "component")
10
+ });
11
+ //#endregion
12
+ export { Route as t };