bazilion 0.15.0 → 0.17.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 (126) hide show
  1. package/dist/cli.js +1138 -687
  2. package/dist/cli.js.map +1 -1
  3. package/dist/daemon.js +8401 -4401
  4. package/dist/daemon.js.map +1 -1
  5. package/dist/migrations/0001_init.sql +109 -0
  6. package/dist/web/client/assets/ChatPane-BI3QVX2A.js +76 -0
  7. package/dist/web/client/assets/{ConfirmDialog-CGZzom9E.js → ConfirmDialog-Qam6Ut08.js} +1 -1
  8. package/dist/web/client/assets/{FieldRow-DYNU9gWb.js → FieldRow-swJ5qn2h.js} +1 -1
  9. package/dist/web/client/assets/ProductionTeamPolicyEditor-LGw1UuF-.js +7 -0
  10. package/dist/web/client/assets/ProfileCommunicationEditor-raoau_YB.js +1 -0
  11. package/dist/web/client/assets/{ResultSourceConversation-CGhKTSTD.js → ResultSourceConversation-BEwkhFog.js} +1 -1
  12. package/dist/web/client/assets/TeamTabs-BDdTLGIf.js +1 -0
  13. package/dist/web/client/assets/TemplatesTabs-BX5hhEJ7.js +1 -0
  14. package/dist/web/client/assets/{UnsavedChangesGuard-CFQcKsrf.js → UnsavedChangesGuard-CVJtmR1D.js} +1 -1
  15. package/dist/web/client/assets/{_id-D_eKokkd.js → _id-BQPOE3gj.js} +1 -1
  16. package/dist/web/client/assets/{_id-9nCIhbVd.js → _id-BkYrUP0R.js} +1 -1
  17. package/dist/web/client/assets/_id-CriixlZD.js +1 -0
  18. package/dist/web/client/assets/_id-DHqq2W34.js +1 -0
  19. package/dist/web/client/assets/{_id-BSu3AqKA.js → _id-DmEVZIlx.js} +1 -1
  20. package/dist/web/client/assets/activity-Bzr8R18n.js +1 -0
  21. package/dist/web/client/assets/{agents-NY3VrZgB.js → agents-13oafeOA.js} +1 -1
  22. package/dist/web/client/assets/{agents-CCmiZek6.js → agents-DF4NALmJ.js} +1 -1
  23. package/dist/web/client/assets/{approvals-CPDAPgrM.js → approvals-DsG0Ijls.js} +1 -1
  24. package/dist/web/client/assets/{attention-Qra_9_OI.js → attention-DG7K25mz.js} +1 -1
  25. package/dist/web/client/assets/chevron-right-DFqFHtLy.js +1 -0
  26. package/dist/web/client/assets/config-DAaDbFhS.js +3 -0
  27. package/dist/web/client/assets/createServerFn-Dzfjt7mA.js +3 -0
  28. package/dist/web/client/assets/git-review-presentation-CzHQulDk.js +1 -0
  29. package/dist/web/client/assets/{inbox-C5W-sm1q.js → inbox-C9e7QjsX.js} +1 -1
  30. package/dist/web/client/assets/index-Dsstm2hf.js +50 -0
  31. package/dist/web/client/assets/{learning-Dr-7_7J4.js → learning-23arTd21.js} +1 -1
  32. package/dist/web/client/assets/login-BIXnBsuj.js +1 -0
  33. package/dist/web/client/assets/{mcp-BueuwQiv.js → mcp-Cdx9qAl8.js} +1 -1
  34. package/dist/web/client/assets/{members-ZikuYNcy.js → members-fotOz4rR.js} +1 -1
  35. package/dist/web/client/assets/{memory-1JUJlPrn.js → memory-C7UznVot.js} +1 -1
  36. package/dist/web/client/assets/policy-CactLW1X.js +1 -0
  37. package/dist/web/client/assets/{results-mMr8Ar2u.js → results-DqEuYnQH.js} +1 -1
  38. package/dist/web/client/assets/review-CnBSYclb.js +1 -0
  39. package/dist/web/client/assets/routes-COxMuwVz.js +1 -0
  40. package/dist/web/client/assets/{services-kfQA9cpJ.js → services-xEANwZAu.js} +1 -1
  41. package/dist/web/client/assets/{skills-C6pcgxaC.js → skills-CamV6wYM.js} +1 -1
  42. package/dist/web/client/assets/styles-C6br2xxl.css +2 -0
  43. package/dist/web/client/assets/{teams-LB0KBXY9.js → teams-B12dMSjW.js} +1 -1
  44. package/dist/web/client/assets/{teams-C6_Noz5X.js → teams-CbH43zSG.js} +1 -1
  45. package/dist/web/client/assets/{telegram-A2jaI1QM.js → telegram-muIql4u-.js} +1 -1
  46. package/dist/web/client/assets/{tokens-BGlUpJcL.js → tokens-DGFmApdF.js} +1 -1
  47. package/dist/web/client/assets/{triggers-C54_feGg.js → triggers-D8n3sCBW.js} +1 -1
  48. package/dist/web/client/assets/welcome-CMHWRZhs.js +1 -0
  49. package/dist/web/client/assets/x-BGCHwZOH.js +1 -0
  50. package/dist/web/server/assets/{ChatPane-DJ30FdFG.js → ChatPane-DybH39WK.js} +524 -15
  51. package/dist/web/server/assets/{ResultSourceConversation-zYogeOWp.js → ResultSourceConversation-BmXTcEOA.js} +1 -1
  52. package/dist/web/server/assets/{TeamTabs-TCKjCvMA.js → TeamTabs-DQXh-3ij.js} +4 -0
  53. package/dist/web/server/assets/{_id-1LwoHhJg.js → _id-BN1BPEDI.js} +1 -1
  54. package/dist/web/server/assets/{_id-DFHB9JFQ.js → _id-BYKpT2Tu.js} +1 -1
  55. package/dist/web/server/assets/{_id-B_-CDHOi2.js → _id-BqWTB8Wl.js} +1 -1
  56. package/dist/web/server/assets/{_id-BvSWsPI5.js → _id-CPfILjMa.js} +1 -1
  57. package/dist/web/server/assets/{_id-1hTvnKLN2.js → _id-C_2er0_G.js} +3 -3
  58. package/dist/web/server/assets/{_id-B2EEyStS.js → _id-DDyA9CGX.js} +1 -1
  59. package/dist/web/server/assets/{_id-DxFLSIio.js → _id-DSPFJMzf.js} +1 -1
  60. package/dist/web/server/assets/_id-DtJn-yzu.js +779 -0
  61. package/dist/web/server/assets/{_id-DDNVQx3y.js → _id-Dw3gKOGv.js} +1 -1
  62. package/dist/web/server/assets/{_id-T_8btpbB.js → _id-XkxlX036.js} +1 -1
  63. package/dist/web/server/assets/{_tanstack-start-manifest_v-DP4ZUBw3.js → _tanstack-start-manifest_v-vOXRfKJD.js} +97 -84
  64. package/dist/web/server/assets/{activity-C88qrNqv.js → activity-BX1jZBPQ.js} +1 -1
  65. package/dist/web/server/assets/{activity-5fWKPDxj.js → activity-bozPMU2v.js} +2 -2
  66. package/dist/web/server/assets/{activity-D73w4mkZ.js → activity-pYQPT3QT.js} +1 -1
  67. package/dist/web/server/assets/{agents-DRSo7lRX.js → agents-BKBfW700.js} +1 -1
  68. package/dist/web/server/assets/{agents-DB5hCSAI.js → agents-CVCfxnE2.js} +1 -1
  69. package/dist/web/server/assets/{approvals-4y9bZF4r.js → approvals-C3ya6B6U.js} +1 -1
  70. package/dist/web/server/assets/{attention-BFx8ZkmH.js → attention-l28hGCHS.js} +1 -1
  71. package/dist/web/server/assets/{auth-_eaCwhyq.js → auth-AvDFNeOv.js} +1 -1
  72. package/dist/web/server/assets/{config-B7JIfv_7.js → config-BWKn4XII.js} +1 -1
  73. package/dist/web/server/assets/{daemon-client-B06W1Qa2.js → daemon-client-Cgx-YW4l.js} +35 -0
  74. package/dist/web/server/assets/git-review-BB3M9nYg.js +26 -0
  75. package/dist/web/server/assets/git-review-f_uta4Mx.js +179 -0
  76. package/dist/web/server/assets/git-review-presentation-TJiHJhen.js +81 -0
  77. package/dist/web/server/assets/{inbox-YRpDQcvp.js → inbox-BBZiOOQs.js} +1 -1
  78. package/dist/web/server/assets/{learning-UBZb6h6M.js → learning-CheVay1i.js} +1 -1
  79. package/dist/web/server/assets/{mcp-Dv6RXMaS.js → mcp-DCBDmNtQ.js} +1 -1
  80. package/dist/web/server/assets/{members-BFTKSlOe.js → members-C2He8mrU.js} +1 -1
  81. package/dist/web/server/assets/{members-CD3GiTfF.js → members-C5FQruRZ.js} +1 -1
  82. package/dist/web/server/assets/{members-cc5SeEaW.js → members-C_2xB9pr.js} +2 -2
  83. package/dist/web/server/assets/{memory-CVqnyUaM.js → memory-4tI-UbOf.js} +1 -1
  84. package/dist/web/server/assets/{memory-C5i_GxlY.js → memory-BTcmf0sD.js} +2 -2
  85. package/dist/web/server/assets/{memory-D0PQgZAn.js → memory-rmiFNj7T.js} +1 -1
  86. package/dist/web/server/assets/{policy-Dgjb0_gK.js → policy-BGILKGHz.js} +2 -2
  87. package/dist/web/server/assets/{policy-bLKwvnja.js → policy-C3D2Q1EA.js} +1 -1
  88. package/dist/web/server/assets/{policy-C-p8HIhA.js → policy-DS7LGe--.js} +1 -1
  89. package/dist/web/server/assets/{results-Cfev4KNt.js → results-C6H42tjq.js} +1 -1
  90. package/dist/web/server/assets/{results-Cj-Dlw3C.js → results-Cgx7SrFt.js} +3 -3
  91. package/dist/web/server/assets/{results-CwEQ5EUL.js → results-_6K_zXQS.js} +1 -1
  92. package/dist/web/server/assets/review-DHhiL-JQ.js +393 -0
  93. package/dist/web/server/assets/review-DSTMCwP4.js +14 -0
  94. package/dist/web/server/assets/{router-d3sTMpMX.js → router-ElARvZzI.js} +34 -27
  95. package/dist/web/server/assets/{routes-B765DVhj.js → routes-B6x3pEW8.js} +1 -1
  96. package/dist/web/server/assets/{routes-cW4MWU18.js → routes-BgMvLvS-.js} +1 -1
  97. package/dist/web/server/assets/{routes-MIZz6uMr.js → routes-DsUzzxk4.js} +2 -2
  98. package/dist/web/server/assets/{services-BCbdn3R9.js → services-yHZroxsi.js} +1 -1
  99. package/dist/web/server/assets/{skills-Bpoa8MIp.js → skills--bIKID1Q.js} +1 -1
  100. package/dist/web/server/assets/{teams-hWGjbpUA.js → teams--a956vWL.js} +1 -1
  101. package/dist/web/server/assets/{teams-CXzwqzcE.js → teams-BbRfuVXY.js} +1 -1
  102. package/dist/web/server/assets/{telegram-DhpvtGUc.js → telegram-4kMxRtVZ.js} +1 -1
  103. package/dist/web/server/assets/{tokens-Bjp19Vkn.js → tokens-BYwTN9JZ.js} +1 -1
  104. package/dist/web/server/assets/{triggers-DJlcvXzn.js → triggers-BM6mzLuH.js} +1 -1
  105. package/dist/web/server/server.js +56 -28
  106. package/dist/worker.js +2214 -1132
  107. package/dist/worker.js.map +1 -1
  108. package/package.json +3 -3
  109. package/dist/web/client/assets/ChatPane-55j13bBj.js +0 -74
  110. package/dist/web/client/assets/ProductionTeamPolicyEditor-DT5Sl8jd.js +0 -7
  111. package/dist/web/client/assets/ProfileCommunicationEditor-TyCU5vXX.js +0 -1
  112. package/dist/web/client/assets/TeamTabs-BZHyRnbd.js +0 -1
  113. package/dist/web/client/assets/TemplatesTabs-BHzkPMRC.js +0 -1
  114. package/dist/web/client/assets/_id-CGd21j3k.js +0 -1
  115. package/dist/web/client/assets/_id-SRMFlIgP.js +0 -1
  116. package/dist/web/client/assets/activity-Cn2-9PpZ.js +0 -1
  117. package/dist/web/client/assets/chevron-right-DXE4CWf2.js +0 -1
  118. package/dist/web/client/assets/config-D8EO0LPB.js +0 -3
  119. package/dist/web/client/assets/index-BUhhk_u9.js +0 -52
  120. package/dist/web/client/assets/login-Bu5UxbJh.js +0 -1
  121. package/dist/web/client/assets/policy-DbkhsFNA.js +0 -1
  122. package/dist/web/client/assets/routes-DJYB-MS9.js +0 -1
  123. package/dist/web/client/assets/styles-CcNf8jT_.css +0 -2
  124. package/dist/web/client/assets/welcome-DyUIswRi.js +0 -1
  125. package/dist/web/client/assets/x-BY2MPLr9.js +0 -1
  126. package/dist/web/server/assets/_id-CDBtO_jL.js +0 -381
@@ -1,381 +0,0 @@
1
- import { t as Route } from "./_id-B2EEyStS.js";
2
- import { a as StatusBadge, i as SectionCard, r as PageShell } from "./Page-Bz-ydB8j.js";
3
- import { t as Button } from "./Button-Dsnw22OF.js";
4
- import { t as TeamTabs } from "./TeamTabs-TCKjCvMA.js";
5
- import { t as UnsavedChangesGuard } from "./UnsavedChangesGuard-CiStXyBI.js";
6
- import { useEffect, useState } from "react";
7
- import { useRouter } from "@tanstack/react-router";
8
- import { jsx, jsxs } from "react/jsx-runtime";
9
- //#region src/routes/teams/$id/index.tsx?tsr-split=component
10
- function TeamDetailPage() {
11
- const { team, members, profileGroups } = Route.useLoaderData();
12
- const router = useRouter();
13
- const [userMd, setUserMd] = useState(team.userMd);
14
- const [busy, setBusy] = useState(false);
15
- const [err, setErr] = useState(null);
16
- const [savedAt, setSavedAt] = useState(null);
17
- const [topicDirty, setTopicDirty] = useState(false);
18
- const contextDirty = userMd !== team.userMd || topicDirty;
19
- async function save() {
20
- setBusy(true);
21
- setErr(null);
22
- try {
23
- const res = await fetch(`/api/teams/${encodeURIComponent(team.id)}/user-md`, {
24
- method: "PUT",
25
- headers: { "content-type": "application/json" },
26
- body: JSON.stringify({ userMd })
27
- });
28
- if (!res.ok) {
29
- const e = await res.json().catch(() => ({}));
30
- throw new Error(e.error ?? `${res.status} ${res.statusText}`);
31
- }
32
- setSavedAt(Date.now());
33
- await router.invalidate();
34
- } catch (e) {
35
- setErr(e.message);
36
- } finally {
37
- setBusy(false);
38
- }
39
- }
40
- return /* @__PURE__ */ jsxs(PageShell, { children: [
41
- /* @__PURE__ */ jsx(UnsavedChangesGuard, {
42
- when: contextDirty,
43
- subject: "Team context"
44
- }),
45
- /* @__PURE__ */ jsxs("h1", {
46
- className: "font-serif text-3xl text-foreground",
47
- children: [
48
- team.name,
49
- " ",
50
- /* @__PURE__ */ jsxs("span", {
51
- className: "text-muted-foreground text-base",
52
- children: [
53
- "(",
54
- team.id,
55
- ")"
56
- ]
57
- })
58
- ]
59
- }),
60
- /* @__PURE__ */ jsxs("p", {
61
- className: "text-muted-foreground text-sm mb-6 mt-1",
62
- children: [
63
- /* @__PURE__ */ jsx("code", {
64
- className: "font-mono",
65
- children: team.path
66
- }),
67
- " · ",
68
- members.length,
69
- " ",
70
- "member",
71
- members.length === 1 ? "" : "s",
72
- " ·",
73
- " ",
74
- /* @__PURE__ */ jsx("a", {
75
- href: `/teams/${encodeURIComponent(team.id)}/memory`,
76
- className: "text-primary underline",
77
- children: "shared memory →"
78
- })
79
- ]
80
- }),
81
- /* @__PURE__ */ jsx(TeamTabs, { teamId: team.id }),
82
- /* @__PURE__ */ jsxs("section", {
83
- className: "rounded-lg border bg-card p-5 mb-6",
84
- children: [
85
- /* @__PURE__ */ jsx("h3", {
86
- className: "font-serif text-xl mb-1",
87
- children: "USER.md"
88
- }),
89
- /* @__PURE__ */ jsx("p", {
90
- className: "text-muted-foreground text-sm mb-3",
91
- children: "Read-only context about the human, injected into every member agent's system prompt. 12 KB cap. Agents cannot edit this file — only you can."
92
- }),
93
- /* @__PURE__ */ jsx("label", {
94
- htmlFor: "team-user-context",
95
- className: "sr-only",
96
- children: "USER.md Team context"
97
- }),
98
- /* @__PURE__ */ jsx("textarea", {
99
- id: "team-user-context",
100
- value: userMd,
101
- onChange: (e) => setUserMd(e.target.value),
102
- rows: 16,
103
- className: "w-full rounded-md border bg-background px-3 py-2 font-mono text-sm outline-none focus:ring-2 focus:ring-ring/30",
104
- placeholder: "What the agent should know about you in this team context…"
105
- }),
106
- /* @__PURE__ */ jsxs("div", {
107
- className: "flex items-center gap-3 mt-3",
108
- children: [
109
- /* @__PURE__ */ jsx(Button, {
110
- variant: "primary",
111
- onClick: save,
112
- disabled: busy || userMd === team.userMd,
113
- children: busy ? "saving…" : "save"
114
- }),
115
- /* @__PURE__ */ jsxs("span", {
116
- className: "text-xs text-muted-foreground",
117
- children: [userMd.length, " / 12000 chars"]
118
- }),
119
- savedAt && /* @__PURE__ */ jsx("span", {
120
- role: "status",
121
- className: "text-xs text-success",
122
- children: "Saved"
123
- }),
124
- err && /* @__PURE__ */ jsx("span", {
125
- role: "alert",
126
- className: "text-xs text-danger",
127
- children: err
128
- })
129
- ]
130
- })
131
- ]
132
- }),
133
- /* @__PURE__ */ jsx(TopicNameFormatCard, {
134
- team,
135
- sampleAgent: members[0]?.name ?? "researcher",
136
- onSaved: () => router.invalidate(),
137
- onDirtyChange: setTopicDirty
138
- }),
139
- members.length === 0 && /* @__PURE__ */ jsx(SpawnFromTemplateCard, {
140
- teamId: team.id,
141
- profileGroups,
142
- onSpawned: () => router.invalidate()
143
- }),
144
- /* @__PURE__ */ jsx(SectionCard, {
145
- title: "Roster",
146
- description: "Live Team membership has one canonical management view.",
147
- actions: /* @__PURE__ */ jsxs(StatusBadge, {
148
- variant: members.length > 0 ? "success" : "neutral",
149
- children: [
150
- members.length,
151
- " member",
152
- members.length === 1 ? "" : "s"
153
- ]
154
- }),
155
- children: /* @__PURE__ */ jsx("a", {
156
- href: `/teams/${encodeURIComponent(team.id)}/members`,
157
- className: "ghost-btn",
158
- children: "Manage Team members"
159
- })
160
- })
161
- ] });
162
- }
163
- function TopicNameFormatCard({ team, sampleAgent, onSaved, onDirtyChange }) {
164
- const [format, setFormat] = useState(team.telegramTopicNameFormat ?? "");
165
- const [busy, setBusy] = useState(false);
166
- const [err, setErr] = useState(null);
167
- const [savedAt, setSavedAt] = useState(null);
168
- const trimmed = format.trim();
169
- const preview = trimmed ? trimmed.replaceAll("{agent.name}", sampleAgent).replaceAll("{team.name}", team.name).replaceAll("{team.slug}", team.id) : team.id === "default" ? sampleAgent : `${team.id} › ${sampleAgent}`;
170
- const dirty = (team.telegramTopicNameFormat ?? "") !== format;
171
- useEffect(() => {
172
- onDirtyChange(dirty);
173
- return () => onDirtyChange(false);
174
- }, [dirty, onDirtyChange]);
175
- async function save(clear) {
176
- setBusy(true);
177
- setErr(null);
178
- try {
179
- const res = await fetch(`/api/teams/${encodeURIComponent(team.id)}/topic-format`, {
180
- method: "PUT",
181
- headers: { "content-type": "application/json" },
182
- body: JSON.stringify({ format: clear ? null : format })
183
- });
184
- if (!res.ok) {
185
- const e = await res.json().catch(() => ({}));
186
- throw new Error(e.error ?? `${res.status} ${res.statusText}`);
187
- }
188
- if (clear) setFormat("");
189
- setSavedAt(Date.now());
190
- onSaved();
191
- } catch (e) {
192
- setErr(e.message);
193
- } finally {
194
- setBusy(false);
195
- }
196
- }
197
- return /* @__PURE__ */ jsxs("section", {
198
- className: "rounded-lg border bg-card p-5 mb-6",
199
- children: [
200
- /* @__PURE__ */ jsx("h3", {
201
- className: "font-serif text-xl mb-1",
202
- children: "Telegram topic names"
203
- }),
204
- /* @__PURE__ */ jsxs("p", {
205
- className: "text-muted-foreground text-sm mb-3",
206
- children: [
207
- "Template for this team's Telegram forum-topic titles. Leave empty for built-in naming. Tokens: ",
208
- /* @__PURE__ */ jsx("code", {
209
- className: "font-mono",
210
- children: "{agent.name}"
211
- }),
212
- " ",
213
- /* @__PURE__ */ jsx("code", {
214
- className: "font-mono",
215
- children: "{team.name}"
216
- }),
217
- " ",
218
- /* @__PURE__ */ jsx("code", {
219
- className: "font-mono",
220
- children: "{team.slug}"
221
- }),
222
- " — must include",
223
- " ",
224
- /* @__PURE__ */ jsx("code", {
225
- className: "font-mono",
226
- children: "{agent.name}"
227
- }),
228
- ". Saving renames existing topics that you haven't manually renamed in Telegram."
229
- ]
230
- }),
231
- /* @__PURE__ */ jsx("label", {
232
- htmlFor: "team-telegram-topic-format",
233
- className: "sr-only",
234
- children: "Telegram topic name format"
235
- }),
236
- /* @__PURE__ */ jsx("input", {
237
- id: "team-telegram-topic-format",
238
- value: format,
239
- onChange: (e) => setFormat(e.target.value),
240
- placeholder: "{team.name} / {agent.name}",
241
- className: "w-full rounded-md border bg-background px-3 py-2 font-mono text-sm outline-none focus:ring-2 focus:ring-ring/30"
242
- }),
243
- /* @__PURE__ */ jsxs("p", {
244
- className: "text-xs text-muted-foreground mt-2",
245
- children: ["preview: ", /* @__PURE__ */ jsx("span", {
246
- className: "font-mono text-foreground",
247
- children: preview
248
- })]
249
- }),
250
- /* @__PURE__ */ jsxs("div", {
251
- className: "flex items-center gap-3 mt-3",
252
- children: [
253
- /* @__PURE__ */ jsx(Button, {
254
- variant: "primary",
255
- onClick: () => save(false),
256
- disabled: busy || !dirty || trimmed.length === 0,
257
- children: busy ? "saving…" : "save"
258
- }),
259
- team.telegramTopicNameFormat && /* @__PURE__ */ jsx(Button, {
260
- variant: "ghost",
261
- onClick: () => save(true),
262
- disabled: busy,
263
- children: "clear"
264
- }),
265
- savedAt && /* @__PURE__ */ jsx("span", {
266
- role: "status",
267
- className: "text-xs text-success",
268
- children: "Saved"
269
- }),
270
- err && /* @__PURE__ */ jsx("span", {
271
- role: "alert",
272
- className: "text-xs text-danger",
273
- children: err
274
- })
275
- ]
276
- })
277
- ]
278
- });
279
- }
280
- function SpawnFromTemplateCard({ teamId, profileGroups, onSpawned }) {
281
- const eligible = profileGroups.filter((g) => g.slotCount > 0 && !g.deletedAt);
282
- const [selected, setSelected] = useState(eligible[0]?.id ?? "");
283
- const [busy, setBusy] = useState(false);
284
- const [err, setErr] = useState(null);
285
- async function spawn() {
286
- if (!selected) return;
287
- setBusy(true);
288
- setErr(null);
289
- try {
290
- const template = eligible.find((item) => item.id === selected);
291
- if (!template) throw new Error("Team template is unavailable.");
292
- const policyResponse = await fetch(`/api/teams/${encodeURIComponent(teamId)}/policy`);
293
- if (!policyResponse.ok) throw new Error("The current Team policy is unavailable.");
294
- const current = await policyResponse.json();
295
- const res = await fetch(`/api/team-templates/${encodeURIComponent(selected)}/spawn`, {
296
- method: "POST",
297
- headers: { "content-type": "application/json" },
298
- body: JSON.stringify({
299
- templateExpectedRevision: template.currentRevision,
300
- teamId,
301
- teamExpectedRevision: current.teamPolicy.revision,
302
- mode: "initialize"
303
- })
304
- });
305
- if (!res.ok) {
306
- const e = await res.json().catch(() => ({}));
307
- throw new Error(e.error ?? `${res.status} ${res.statusText}`);
308
- }
309
- onSpawned();
310
- } catch (e) {
311
- setErr(e.message);
312
- } finally {
313
- setBusy(false);
314
- }
315
- }
316
- return /* @__PURE__ */ jsxs("section", {
317
- className: "rounded-lg border bg-card p-5 mb-6",
318
- children: [
319
- /* @__PURE__ */ jsx("h3", {
320
- className: "font-serif text-xl mb-1",
321
- children: "spawn a team into this team"
322
- }),
323
- /* @__PURE__ */ jsx("p", {
324
- className: "text-muted-foreground text-sm mb-3",
325
- children: "This Team is empty. Pick a canonical Team template to initialize its roster and policy at the current reviewed Team and Team revisions."
326
- }),
327
- eligible.length === 0 ? /* @__PURE__ */ jsxs("p", {
328
- className: "text-muted-foreground text-sm",
329
- children: [
330
- "No Team templates with slots yet. Build one on",
331
- " ",
332
- /* @__PURE__ */ jsx("a", {
333
- href: "/templates/teams",
334
- className: "text-primary underline",
335
- children: "Team templates"
336
- }),
337
- " ",
338
- "first."
339
- ]
340
- }) : /* @__PURE__ */ jsxs("div", {
341
- className: "flex flex-wrap items-end gap-3",
342
- children: [
343
- /* @__PURE__ */ jsxs("label", {
344
- className: "m-0 flex min-w-0 flex-1 flex-col gap-1 text-sm text-foreground",
345
- children: ["Team template", /* @__PURE__ */ jsx("select", {
346
- value: selected,
347
- onChange: (e) => setSelected(e.target.value),
348
- className: "min-w-0 rounded-md border bg-background px-3 py-2 text-sm outline-none focus:ring-2 focus:ring-ring/30",
349
- children: eligible.map((g) => /* @__PURE__ */ jsxs("option", {
350
- value: g.id,
351
- children: [
352
- g.name,
353
- " (",
354
- g.slotCount,
355
- " slot",
356
- g.slotCount === 1 ? "" : "s",
357
- ", r",
358
- g.currentRevision,
359
- ")"
360
- ]
361
- }, g.id))
362
- })]
363
- }),
364
- /* @__PURE__ */ jsx(Button, {
365
- variant: "primary",
366
- onClick: spawn,
367
- disabled: busy || !selected,
368
- children: busy ? "spawning…" : "spawn team"
369
- }),
370
- err && /* @__PURE__ */ jsx("span", {
371
- role: "alert",
372
- className: "basis-full text-xs text-danger",
373
- children: err
374
- })
375
- ]
376
- })
377
- ]
378
- });
379
- }
380
- //#endregion
381
- export { TeamDetailPage as component };