@burdenoff/microfe-atheletebridge 2026.801.2 → 2026.805.1

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 (63) hide show
  1. package/dist/atheletebridge/AthleteBridgeRoot.d.ts.map +1 -1
  2. package/dist/atheletebridge/AthleteBridgeRoot.js +53 -45
  3. package/dist/atheletebridge/AthleteBridgeRoot.js.map +1 -1
  4. package/dist/atheletebridge/AthleteBridgeRoutes.d.ts.map +1 -1
  5. package/dist/atheletebridge/AthleteBridgeRoutes.js +15 -7
  6. package/dist/atheletebridge/AthleteBridgeRoutes.js.map +1 -1
  7. package/dist/atheletebridge/components/StatusBadge.d.ts.map +1 -1
  8. package/dist/atheletebridge/components/StatusBadge.js +3 -1
  9. package/dist/atheletebridge/components/StatusBadge.js.map +1 -1
  10. package/dist/atheletebridge/components/ai/AgentRunFeed.d.ts +19 -0
  11. package/dist/atheletebridge/components/ai/AgentRunFeed.d.ts.map +1 -0
  12. package/dist/atheletebridge/components/ai/AgentRunFeed.js +124 -0
  13. package/dist/atheletebridge/components/ai/AgentRunFeed.js.map +1 -0
  14. package/dist/atheletebridge/components/ai/AiErrorNotice.d.ts +21 -0
  15. package/dist/atheletebridge/components/ai/AiErrorNotice.d.ts.map +1 -0
  16. package/dist/atheletebridge/components/ai/AiErrorNotice.js +114 -0
  17. package/dist/atheletebridge/components/ai/AiErrorNotice.js.map +1 -0
  18. package/dist/atheletebridge/components/ai/AiModelPicker.d.ts +19 -0
  19. package/dist/atheletebridge/components/ai/AiModelPicker.d.ts.map +1 -0
  20. package/dist/atheletebridge/components/ai/AiModelPicker.js +203 -0
  21. package/dist/atheletebridge/components/ai/AiModelPicker.js.map +1 -0
  22. package/dist/atheletebridge/components/ai/DecisionCard.d.ts +11 -0
  23. package/dist/atheletebridge/components/ai/DecisionCard.d.ts.map +1 -0
  24. package/dist/atheletebridge/components/ai/DecisionCard.js +343 -0
  25. package/dist/atheletebridge/components/ai/DecisionCard.js.map +1 -0
  26. package/dist/atheletebridge/components/ai/RunDecisionPanel.d.ts +21 -0
  27. package/dist/atheletebridge/components/ai/RunDecisionPanel.d.ts.map +1 -0
  28. package/dist/atheletebridge/components/ai/RunDecisionPanel.js +371 -0
  29. package/dist/atheletebridge/components/ai/RunDecisionPanel.js.map +1 -0
  30. package/dist/atheletebridge/components/ai/assessment.d.ts +14 -0
  31. package/dist/atheletebridge/components/ai/assessment.d.ts.map +1 -0
  32. package/dist/atheletebridge/components/ai/assessment.js +30 -0
  33. package/dist/atheletebridge/components/ai/assessment.js.map +1 -0
  34. package/dist/atheletebridge/components/ai/index.d.ts +11 -0
  35. package/dist/atheletebridge/components/ai/index.d.ts.map +1 -0
  36. package/dist/atheletebridge/components/index.d.ts +1 -0
  37. package/dist/atheletebridge/components/index.d.ts.map +1 -1
  38. package/dist/atheletebridge/hooks/index.d.ts +2 -2
  39. package/dist/atheletebridge/hooks/index.d.ts.map +1 -1
  40. package/dist/atheletebridge/hooks/useAthleteBridgeApi.d.ts +92 -1
  41. package/dist/atheletebridge/hooks/useAthleteBridgeApi.d.ts.map +1 -1
  42. package/dist/atheletebridge/hooks/useAthleteBridgeApi.js +274 -129
  43. package/dist/atheletebridge/hooks/useAthleteBridgeApi.js.map +1 -1
  44. package/dist/atheletebridge/index.d.ts +1 -1
  45. package/dist/atheletebridge/index.d.ts.map +1 -1
  46. package/dist/atheletebridge/pages/ai/AiOperationsPage.d.ts +23 -0
  47. package/dist/atheletebridge/pages/ai/AiOperationsPage.d.ts.map +1 -0
  48. package/dist/atheletebridge/pages/ai/AiOperationsPage.js +117 -0
  49. package/dist/atheletebridge/pages/ai/AiOperationsPage.js.map +1 -0
  50. package/dist/atheletebridge/types/index.d.ts +124 -1
  51. package/dist/atheletebridge/types/index.d.ts.map +1 -1
  52. package/dist/atheletebridge/utils/aiDecision.d.ts +73 -0
  53. package/dist/atheletebridge/utils/aiDecision.d.ts.map +1 -0
  54. package/dist/atheletebridge/utils/aiDecision.js +187 -0
  55. package/dist/atheletebridge/utils/aiDecision.js.map +1 -0
  56. package/dist/atheletebridge/utils/index.d.ts +2 -0
  57. package/dist/atheletebridge/utils/index.d.ts.map +1 -1
  58. package/dist/atheletebridge/utils/pageContext.d.ts.map +1 -1
  59. package/dist/atheletebridge/utils/pageContext.js +5 -0
  60. package/dist/atheletebridge/utils/pageContext.js.map +1 -1
  61. package/dist/generated/wspace-types.d.ts +68885 -33499
  62. package/dist/generated/wspace-types.d.ts.map +1 -1
  63. package/package.json +2 -2
@@ -0,0 +1,371 @@
1
+ import { useAthleteBridge as e } from "../../context/AthleteBridgeContext.js";
2
+ import { StatusBadge as t } from "../StatusBadge.js";
3
+ import { PROGRAM_LEVEL_LABELS as n, SPORT_LABELS as r } from "../domain.js";
4
+ import { useAdjustPlanFromPerformance as i, useGenerateProgram as a, usePrograms as o, useTeams as s } from "../../hooks/useAthleteBridgeApi.js";
5
+ import { FormField as c, fieldInputClass as l } from "../form.js";
6
+ import { AiErrorNotice as u } from "./AiErrorNotice.js";
7
+ import { formatConfidence as d, formatLoadChange as f } from "../../utils/aiDecision.js";
8
+ import { ASSESSMENT_LABELS as p, ASSESSMENT_VARIANT as m } from "./assessment.js";
9
+ import { AthleteSelect as h } from "../AthleteSelect.js";
10
+ import { useState as g } from "react";
11
+ import { Activity as _, Loader2 as v, Sparkles as y, Wand2 as b } from "lucide-react";
12
+ import { jsx as x, jsxs as S } from "react/jsx-runtime";
13
+ import { Badge as C, GlassCard as w } from "@burdenoff/fe-libs/ui";
14
+ //#region src/atheletebridge/components/ai/RunDecisionPanel.tsx
15
+ var T = Object.keys(r), E = Object.keys(n);
16
+ function D({ result: e, onReview: t }) {
17
+ return /* @__PURE__ */ S("div", {
18
+ className: "rounded-lg border border-status-success-border bg-status-success-bg-subtle p-3",
19
+ children: [
20
+ /* @__PURE__ */ S("p", {
21
+ className: "text-sm font-medium text-status-success-text",
22
+ children: ["Draft program created: ", e.program.name]
23
+ }),
24
+ /* @__PURE__ */ S("p", {
25
+ className: "mt-1 text-xs text-text-secondary",
26
+ children: [
27
+ e.drillCount,
28
+ " drills · ",
29
+ e.sessionCount,
30
+ " sessions · ledger row",
31
+ " ",
32
+ /* @__PURE__ */ x("code", {
33
+ className: "font-mono",
34
+ children: e.agentRunId
35
+ })
36
+ ]
37
+ }),
38
+ /* @__PURE__ */ x("button", {
39
+ type: "button",
40
+ onClick: () => t(e.program.id),
41
+ className: "mt-2 rounded-lg border border-border-seam px-3 py-1.5 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken",
42
+ children: "Review the draft"
43
+ })
44
+ ]
45
+ });
46
+ }
47
+ function O() {
48
+ let { navigateTo: t } = e(), i = s({ pagination: { limit: 100 } }), o = a(), [d, f] = g("team"), [p, m] = g(""), [_, C] = g(""), [O, k] = g(""), [A, j] = g(""), [M, N] = g("OTHER"), [P, F] = g("BEGINNER"), [I, L] = g("4"), [R, z] = g(null);
49
+ return /* @__PURE__ */ S(w, {
50
+ treatment: "insight",
51
+ className: "p-5",
52
+ children: [/* @__PURE__ */ S("div", {
53
+ className: "flex items-start gap-3",
54
+ children: [/* @__PURE__ */ x("div", {
55
+ className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-xl bg-[var(--color-accent-soft)] text-text-primary",
56
+ children: /* @__PURE__ */ x(b, {
57
+ className: "h-5 w-5",
58
+ "aria-hidden": "true"
59
+ })
60
+ }), /* @__PURE__ */ S("div", {
61
+ className: "min-w-0",
62
+ children: [/* @__PURE__ */ x("h3", {
63
+ className: "text-base font-semibold text-text-primary",
64
+ children: "Generate a program"
65
+ }), /* @__PURE__ */ x("p", {
66
+ className: "mt-1 text-sm text-text-secondary",
67
+ children: "Writes a real DRAFT program with drills. Nothing reaches athletes until you publish it."
68
+ })]
69
+ })]
70
+ }), /* @__PURE__ */ S("form", {
71
+ onSubmit: (e) => {
72
+ if (e.preventDefault(), z(null), !O.trim()) {
73
+ z("Describe the goals the plan has to serve.");
74
+ return;
75
+ }
76
+ if (d === "team" && !p) {
77
+ z("Choose the team this plan is for.");
78
+ return;
79
+ }
80
+ if (d === "athlete" && !_) {
81
+ z("Choose the athlete this plan is for.");
82
+ return;
83
+ }
84
+ let t = Number.parseInt(I, 10);
85
+ if (Number.isNaN(t) || t < 1 || t > 12) {
86
+ z("Length must be between 1 and 12 weeks.");
87
+ return;
88
+ }
89
+ o.mutate({
90
+ ...d === "team" ? { teamId: p } : { athleteId: _ },
91
+ goals: O.trim(),
92
+ constraints: A.trim() || void 0,
93
+ sport: M,
94
+ level: P,
95
+ weeks: t
96
+ });
97
+ },
98
+ className: "mt-4 space-y-4",
99
+ children: [
100
+ /* @__PURE__ */ x(c, {
101
+ label: "Plan for",
102
+ htmlFor: "generate-target",
103
+ children: /* @__PURE__ */ S("select", {
104
+ id: "generate-target",
105
+ className: l,
106
+ value: d,
107
+ onChange: (e) => {
108
+ f(e.target.value === "athlete" ? "athlete" : "team"), z(null);
109
+ },
110
+ children: [/* @__PURE__ */ x("option", {
111
+ value: "team",
112
+ children: "A whole team"
113
+ }), /* @__PURE__ */ x("option", {
114
+ value: "athlete",
115
+ children: "A single athlete"
116
+ })]
117
+ })
118
+ }),
119
+ d === "team" ? /* @__PURE__ */ x(c, {
120
+ label: "Team",
121
+ htmlFor: "generate-team",
122
+ required: !0,
123
+ children: /* @__PURE__ */ S("select", {
124
+ id: "generate-team",
125
+ className: l,
126
+ value: p,
127
+ onChange: (e) => m(e.target.value),
128
+ children: [/* @__PURE__ */ x("option", {
129
+ value: "",
130
+ children: "Select a team…"
131
+ }), (i.data?.items ?? []).map((e) => /* @__PURE__ */ x("option", {
132
+ value: e.id,
133
+ children: e.name
134
+ }, e.id))]
135
+ })
136
+ }) : /* @__PURE__ */ x(h, {
137
+ idPrefix: "generate",
138
+ required: !0,
139
+ athleteId: _,
140
+ onSelect: (e) => C(e.athleteId)
141
+ }),
142
+ /* @__PURE__ */ x(c, {
143
+ label: "Goals",
144
+ htmlFor: "generate-goals",
145
+ required: !0,
146
+ children: /* @__PURE__ */ x("textarea", {
147
+ id: "generate-goals",
148
+ className: l,
149
+ rows: 3,
150
+ value: O,
151
+ onChange: (e) => k(e.target.value),
152
+ placeholder: "e.g. Build aerobic base and repeat-sprint ability before the league restarts."
153
+ })
154
+ }),
155
+ /* @__PURE__ */ x(c, {
156
+ label: "Constraints",
157
+ htmlFor: "generate-constraints",
158
+ children: /* @__PURE__ */ x("textarea", {
159
+ id: "generate-constraints",
160
+ className: l,
161
+ rows: 2,
162
+ value: A,
163
+ onChange: (e) => j(e.target.value),
164
+ placeholder: "Optional — equipment, availability, injuries to work around."
165
+ })
166
+ }),
167
+ /* @__PURE__ */ S("div", {
168
+ className: "grid grid-cols-1 gap-4 sm:grid-cols-3",
169
+ children: [
170
+ /* @__PURE__ */ x(c, {
171
+ label: "Sport",
172
+ htmlFor: "generate-sport",
173
+ children: /* @__PURE__ */ x("select", {
174
+ id: "generate-sport",
175
+ className: l,
176
+ value: M,
177
+ onChange: (e) => N(e.target.value),
178
+ children: T.map((e) => /* @__PURE__ */ x("option", {
179
+ value: e,
180
+ children: r[e]
181
+ }, e))
182
+ })
183
+ }),
184
+ /* @__PURE__ */ x(c, {
185
+ label: "Level",
186
+ htmlFor: "generate-level",
187
+ children: /* @__PURE__ */ x("select", {
188
+ id: "generate-level",
189
+ className: l,
190
+ value: P,
191
+ onChange: (e) => F(e.target.value),
192
+ children: E.map((e) => /* @__PURE__ */ x("option", {
193
+ value: e,
194
+ children: n[e]
195
+ }, e))
196
+ })
197
+ }),
198
+ /* @__PURE__ */ x(c, {
199
+ label: "Weeks",
200
+ htmlFor: "generate-weeks",
201
+ hint: "1–12",
202
+ children: /* @__PURE__ */ x("input", {
203
+ id: "generate-weeks",
204
+ inputMode: "numeric",
205
+ className: l,
206
+ value: I,
207
+ onChange: (e) => L(e.target.value)
208
+ })
209
+ })
210
+ ]
211
+ }),
212
+ R && /* @__PURE__ */ x("p", {
213
+ className: "text-sm text-status-error-text",
214
+ children: R
215
+ }),
216
+ o.isError && /* @__PURE__ */ x(u, { error: o.error }),
217
+ o.data && /* @__PURE__ */ x(D, {
218
+ result: o.data,
219
+ onReview: (e) => t(`/programs/${e}`)
220
+ }),
221
+ /* @__PURE__ */ S("button", {
222
+ type: "submit",
223
+ disabled: o.isPending,
224
+ className: "inline-flex w-full items-center justify-center gap-1.5 rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text transition-colors hover:bg-action-primary-bg/90 disabled:opacity-60",
225
+ children: [o.isPending ? /* @__PURE__ */ x(v, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ x(y, { className: "h-4 w-4" }), o.isPending ? "Asking the model…" : "Generate draft program"]
226
+ })
227
+ ]
228
+ })]
229
+ });
230
+ }
231
+ function k({ adjustment: e }) {
232
+ let n = d(e.confidence), r = f(e.recommendedWeeklyLoadChangePct);
233
+ return /* @__PURE__ */ S("div", {
234
+ className: "rounded-lg border border-border-seam bg-bg-sunken p-3",
235
+ children: [
236
+ /* @__PURE__ */ S("div", {
237
+ className: "flex flex-wrap items-center gap-2",
238
+ children: [
239
+ /* @__PURE__ */ x(t, {
240
+ status: p[e.assessment],
241
+ variant: m[e.assessment]
242
+ }),
243
+ /* @__PURE__ */ x(C, {
244
+ variant: "outline",
245
+ children: "Proposed"
246
+ }),
247
+ n && /* @__PURE__ */ S("span", {
248
+ className: "text-xs tabular-nums text-text-secondary",
249
+ children: ["Confidence ", n]
250
+ }),
251
+ r && /* @__PURE__ */ S("span", {
252
+ className: "text-xs tabular-nums text-text-secondary",
253
+ children: ["Weekly load ", r]
254
+ })
255
+ ]
256
+ }),
257
+ /* @__PURE__ */ x("p", {
258
+ className: "mt-2 text-sm text-text-secondary",
259
+ children: e.rationale
260
+ }),
261
+ e.flags.length > 0 && /* @__PURE__ */ x("div", {
262
+ className: "mt-2 flex flex-wrap gap-1.5",
263
+ children: e.flags.map((e) => /* @__PURE__ */ x("span", {
264
+ className: "inline-flex items-center rounded-full bg-status-warning-bg-subtle px-2 py-0.5 text-xs font-medium text-status-warning-text",
265
+ children: e
266
+ }, e))
267
+ }),
268
+ /* @__PURE__ */ S("p", {
269
+ className: "mt-2 text-xs text-text-muted",
270
+ children: [
271
+ "Nothing has changed on the athlete's plan.",
272
+ " ",
273
+ e.appliedToProgram ? "The proposal is recorded on the program — accept or override it from its decision card below." : "The proposal could not be written onto the program (it may have been archived), but the ledger row below is authoritative."
274
+ ]
275
+ })
276
+ ]
277
+ });
278
+ }
279
+ function A() {
280
+ let e = i(), t = o({ pagination: { limit: 100 } }), [n, r] = g(""), [a, s] = g(""), [d, f] = g(null);
281
+ return /* @__PURE__ */ S(w, {
282
+ treatment: "insight",
283
+ className: "p-5",
284
+ children: [/* @__PURE__ */ S("div", {
285
+ className: "flex items-start gap-3",
286
+ children: [/* @__PURE__ */ x("div", {
287
+ className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-xl bg-[var(--color-accent-soft)] text-text-primary",
288
+ children: /* @__PURE__ */ x(_, {
289
+ className: "h-5 w-5",
290
+ "aria-hidden": "true"
291
+ })
292
+ }), /* @__PURE__ */ S("div", {
293
+ className: "min-w-0",
294
+ children: [/* @__PURE__ */ x("h3", {
295
+ className: "text-base font-semibold text-text-primary",
296
+ children: "Assess an athlete"
297
+ }), /* @__PURE__ */ x("p", {
298
+ className: "mt-1 text-sm text-text-secondary",
299
+ children: "Reads their recent workout logs and metrics and proposes progress / maintain / deload / at-risk. A coach still decides."
300
+ })]
301
+ })]
302
+ }), /* @__PURE__ */ S("form", {
303
+ onSubmit: (t) => {
304
+ if (t.preventDefault(), f(null), !n) {
305
+ f("Choose the athlete to assess.");
306
+ return;
307
+ }
308
+ if (!a) {
309
+ f("Choose the program the proposal should land on.");
310
+ return;
311
+ }
312
+ e.mutate({
313
+ athleteId: n,
314
+ programId: a
315
+ });
316
+ },
317
+ className: "mt-4 space-y-4",
318
+ children: [
319
+ /* @__PURE__ */ x(h, {
320
+ idPrefix: "assess",
321
+ required: !0,
322
+ athleteId: n,
323
+ onSelect: (e) => r(e.athleteId)
324
+ }),
325
+ /* @__PURE__ */ x(c, {
326
+ label: "Program",
327
+ htmlFor: "assess-program",
328
+ required: !0,
329
+ children: /* @__PURE__ */ S("select", {
330
+ id: "assess-program",
331
+ className: l,
332
+ value: a,
333
+ onChange: (e) => s(e.target.value),
334
+ children: [/* @__PURE__ */ x("option", {
335
+ value: "",
336
+ children: "Select a program…"
337
+ }), (t.data?.items ?? []).map((e) => /* @__PURE__ */ x("option", {
338
+ value: e.id,
339
+ children: e.name
340
+ }, e.id))]
341
+ })
342
+ }),
343
+ d && /* @__PURE__ */ x("p", {
344
+ className: "text-sm text-status-error-text",
345
+ children: d
346
+ }),
347
+ e.isError && /* @__PURE__ */ x(u, { error: e.error }),
348
+ e.isSuccess && e.data && /* @__PURE__ */ x(k, { adjustment: e.data }),
349
+ /* @__PURE__ */ S("button", {
350
+ type: "submit",
351
+ disabled: e.isPending,
352
+ className: "inline-flex w-full items-center justify-center gap-1.5 rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text transition-colors hover:bg-action-primary-bg/90 disabled:opacity-60",
353
+ children: [e.isPending ? /* @__PURE__ */ x(v, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ x(y, { className: "h-4 w-4" }), e.isPending ? "Asking the model…" : "Run assessment"]
354
+ })
355
+ ]
356
+ })]
357
+ });
358
+ }
359
+ function j({ className: e }) {
360
+ return /* @__PURE__ */ x("div", {
361
+ className: e,
362
+ children: /* @__PURE__ */ S("div", {
363
+ className: "grid grid-cols-1 gap-6 lg:grid-cols-2",
364
+ children: [/* @__PURE__ */ x(O, {}), /* @__PURE__ */ x(A, {})]
365
+ })
366
+ });
367
+ }
368
+ //#endregion
369
+ export { j as RunDecisionPanel };
370
+
371
+ //# sourceMappingURL=RunDecisionPanel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RunDecisionPanel.js","names":[],"sources":["../../../../src/atheletebridge/components/ai/RunDecisionPanel.tsx"],"sourcesContent":["/**\n * Run a decision\n * @module atheletebridge/components/ai\n *\n * The two live model calls a coach can make from AI Operations:\n *\n * - `athGenerateProgram` — designs a multi-week plan and writes it into the\n * domain as a DRAFT `AthProgram` (+ drills, + sessions for a named athlete).\n * The coach reviews and publishes it through the normal program lifecycle.\n * - `athAdjustPlanFromPerformance` — reads an athlete's recent workout logs and\n * performance metrics and records a PROPOSED adjustment on a program. It\n * changes no prescribed load; a coach resolves it from the decision card.\n *\n * Both write a ledger row whether they succeed or fail, and both surface\n * `AI_PROVIDER_UNAVAILABLE` with the id of the FAILED row rather than a generic\n * toast.\n */\n\nimport { useState } from 'react';\nimport { Activity, Loader2, Sparkles, Wand2 } from 'lucide-react';\nimport { Badge, GlassCard } from '@burdenoff/fe-libs/ui';\nimport { AthleteSelect } from '../AthleteSelect';\nimport { FormField, fieldInputClass } from '../form';\nimport { PROGRAM_LEVEL_LABELS, SPORT_LABELS } from '../domain';\nimport { StatusBadge } from '../StatusBadge';\nimport { useAthleteBridge } from '../../context/AthleteBridgeContext';\nimport {\n useAdjustPlanFromPerformance,\n useGenerateProgram,\n usePrograms,\n useTeams,\n} from '../../hooks/useAthleteBridgeApi';\nimport type {\n AthGenerateProgramResult,\n AthPlanAdjustment,\n AthProgramLevel,\n AthSport,\n} from '../../types';\nimport { formatConfidence, formatLoadChange } from '../../utils/aiDecision';\nimport { ASSESSMENT_LABELS, ASSESSMENT_VARIANT } from './assessment';\nimport { AiErrorNotice } from './AiErrorNotice';\n\nconst SPORTS = Object.keys(SPORT_LABELS) as AthSport[];\nconst LEVELS = Object.keys(PROGRAM_LEVEL_LABELS) as AthProgramLevel[];\n\ntype GenerateTarget = 'team' | 'athlete';\n\n/** The DRAFT a successful generation produced, with a route into it. */\nfunction GenerateResult({\n result,\n onReview,\n}: {\n result: AthGenerateProgramResult;\n onReview: (programId: string) => void;\n}) {\n return (\n <div className=\"rounded-lg border border-status-success-border bg-status-success-bg-subtle p-3\">\n <p className=\"text-sm font-medium text-status-success-text\">\n Draft program created: {result.program.name}\n </p>\n <p className=\"mt-1 text-xs text-text-secondary\">\n {result.drillCount} drills · {result.sessionCount} sessions · ledger row{' '}\n <code className=\"font-mono\">{result.agentRunId}</code>\n </p>\n <button\n type=\"button\"\n onClick={() => onReview(result.program.id)}\n className=\"mt-2 rounded-lg border border-border-seam px-3 py-1.5 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken\"\n >\n Review the draft\n </button>\n </div>\n );\n}\n\nfunction GenerateProgramCard() {\n const { navigateTo } = useAthleteBridge();\n const teams = useTeams({ pagination: { limit: 100 } });\n const generate = useGenerateProgram();\n\n const [target, setTarget] = useState<GenerateTarget>('team');\n const [teamId, setTeamId] = useState('');\n const [athleteId, setAthleteId] = useState('');\n const [goals, setGoals] = useState('');\n const [constraints, setConstraints] = useState('');\n const [sport, setSport] = useState<AthSport>('OTHER');\n const [level, setLevel] = useState<AthProgramLevel>('BEGINNER');\n const [weeks, setWeeks] = useState('4');\n const [validationError, setValidationError] = useState<string | null>(null);\n\n const handleSubmit = (event: React.FormEvent) => {\n event.preventDefault();\n setValidationError(null);\n\n if (!goals.trim()) {\n setValidationError('Describe the goals the plan has to serve.');\n return;\n }\n if (target === 'team' && !teamId) {\n setValidationError('Choose the team this plan is for.');\n return;\n }\n if (target === 'athlete' && !athleteId) {\n setValidationError('Choose the athlete this plan is for.');\n return;\n }\n const parsedWeeks = Number.parseInt(weeks, 10);\n if (Number.isNaN(parsedWeeks) || parsedWeeks < 1 || parsedWeeks > 12) {\n setValidationError('Length must be between 1 and 12 weeks.');\n return;\n }\n\n generate.mutate({\n // Exactly one of teamId / athleteId, per the service contract.\n ...(target === 'team' ? { teamId } : { athleteId }),\n goals: goals.trim(),\n constraints: constraints.trim() || undefined,\n sport,\n level,\n weeks: parsedWeeks,\n });\n };\n\n return (\n <GlassCard treatment=\"insight\" className=\"p-5\">\n <div className=\"flex items-start gap-3\">\n <div className=\"flex h-10 w-10 shrink-0 items-center justify-center rounded-xl bg-[var(--color-accent-soft)] text-text-primary\">\n <Wand2 className=\"h-5 w-5\" aria-hidden=\"true\" />\n </div>\n <div className=\"min-w-0\">\n <h3 className=\"text-base font-semibold text-text-primary\">Generate a program</h3>\n <p className=\"mt-1 text-sm text-text-secondary\">\n Writes a real DRAFT program with drills. Nothing reaches athletes until you publish it.\n </p>\n </div>\n </div>\n\n <form onSubmit={handleSubmit} className=\"mt-4 space-y-4\">\n <FormField label=\"Plan for\" htmlFor=\"generate-target\">\n <select\n id=\"generate-target\"\n className={fieldInputClass}\n value={target}\n onChange={(event) => {\n setTarget(event.target.value === 'athlete' ? 'athlete' : 'team');\n setValidationError(null);\n }}\n >\n <option value=\"team\">A whole team</option>\n <option value=\"athlete\">A single athlete</option>\n </select>\n </FormField>\n\n {target === 'team' ? (\n <FormField label=\"Team\" htmlFor=\"generate-team\" required>\n <select\n id=\"generate-team\"\n className={fieldInputClass}\n value={teamId}\n onChange={(event) => setTeamId(event.target.value)}\n >\n <option value=\"\">Select a team…</option>\n {(teams.data?.items ?? []).map((team) => (\n <option key={team.id} value={team.id}>\n {team.name}\n </option>\n ))}\n </select>\n </FormField>\n ) : (\n <AthleteSelect\n idPrefix=\"generate\"\n required\n athleteId={athleteId}\n onSelect={(value) => setAthleteId(value.athleteId)}\n />\n )}\n\n <FormField label=\"Goals\" htmlFor=\"generate-goals\" required>\n <textarea\n id=\"generate-goals\"\n className={fieldInputClass}\n rows={3}\n value={goals}\n onChange={(event) => setGoals(event.target.value)}\n placeholder=\"e.g. Build aerobic base and repeat-sprint ability before the league restarts.\"\n />\n </FormField>\n\n <FormField label=\"Constraints\" htmlFor=\"generate-constraints\">\n <textarea\n id=\"generate-constraints\"\n className={fieldInputClass}\n rows={2}\n value={constraints}\n onChange={(event) => setConstraints(event.target.value)}\n placeholder=\"Optional — equipment, availability, injuries to work around.\"\n />\n </FormField>\n\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-3\">\n <FormField label=\"Sport\" htmlFor=\"generate-sport\">\n <select\n id=\"generate-sport\"\n className={fieldInputClass}\n value={sport}\n onChange={(event) => setSport(event.target.value as AthSport)}\n >\n {SPORTS.map((value) => (\n <option key={value} value={value}>\n {SPORT_LABELS[value]}\n </option>\n ))}\n </select>\n </FormField>\n <FormField label=\"Level\" htmlFor=\"generate-level\">\n <select\n id=\"generate-level\"\n className={fieldInputClass}\n value={level}\n onChange={(event) => setLevel(event.target.value as AthProgramLevel)}\n >\n {LEVELS.map((value) => (\n <option key={value} value={value}>\n {PROGRAM_LEVEL_LABELS[value]}\n </option>\n ))}\n </select>\n </FormField>\n <FormField label=\"Weeks\" htmlFor=\"generate-weeks\" hint=\"1–12\">\n <input\n id=\"generate-weeks\"\n inputMode=\"numeric\"\n className={fieldInputClass}\n value={weeks}\n onChange={(event) => setWeeks(event.target.value)}\n />\n </FormField>\n </div>\n\n {validationError && <p className=\"text-sm text-status-error-text\">{validationError}</p>}\n {generate.isError && <AiErrorNotice error={generate.error} />}\n\n {generate.data && (\n <GenerateResult result={generate.data} onReview={(id) => navigateTo(`/programs/${id}`)} />\n )}\n\n <button\n type=\"submit\"\n disabled={generate.isPending}\n className=\"inline-flex w-full items-center justify-center gap-1.5 rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text transition-colors hover:bg-action-primary-bg/90 disabled:opacity-60\"\n >\n {generate.isPending ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <Sparkles className=\"h-4 w-4\" />\n )}\n {generate.isPending ? 'Asking the model…' : 'Generate draft program'}\n </button>\n </form>\n </GlassCard>\n );\n}\n\n/** The proposal a successful assessment produced. */\nfunction AdjustmentResult({ adjustment }: { adjustment: AthPlanAdjustment }) {\n const confidence = formatConfidence(adjustment.confidence);\n const loadChange = formatLoadChange(adjustment.recommendedWeeklyLoadChangePct);\n\n return (\n <div className=\"rounded-lg border border-border-seam bg-bg-sunken p-3\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <StatusBadge\n status={ASSESSMENT_LABELS[adjustment.assessment]}\n variant={ASSESSMENT_VARIANT[adjustment.assessment]}\n />\n <Badge variant=\"outline\">Proposed</Badge>\n {confidence && (\n <span className=\"text-xs tabular-nums text-text-secondary\">Confidence {confidence}</span>\n )}\n {loadChange && (\n <span className=\"text-xs tabular-nums text-text-secondary\">Weekly load {loadChange}</span>\n )}\n </div>\n <p className=\"mt-2 text-sm text-text-secondary\">{adjustment.rationale}</p>\n {adjustment.flags.length > 0 && (\n <div className=\"mt-2 flex flex-wrap gap-1.5\">\n {adjustment.flags.map((flag) => (\n <span\n key={flag}\n className=\"inline-flex items-center rounded-full bg-status-warning-bg-subtle px-2 py-0.5 text-xs font-medium text-status-warning-text\"\n >\n {flag}\n </span>\n ))}\n </div>\n )}\n <p className=\"mt-2 text-xs text-text-muted\">\n Nothing has changed on the athlete&apos;s plan.{' '}\n {adjustment.appliedToProgram\n ? 'The proposal is recorded on the program — accept or override it from its decision card below.'\n : 'The proposal could not be written onto the program (it may have been archived), but the ledger row below is authoritative.'}\n </p>\n </div>\n );\n}\n\nfunction AssessAthleteCard() {\n const adjust = useAdjustPlanFromPerformance();\n const programs = usePrograms({ pagination: { limit: 100 } });\n\n const [athleteId, setAthleteId] = useState('');\n const [programId, setProgramId] = useState('');\n const [validationError, setValidationError] = useState<string | null>(null);\n\n const handleSubmit = (event: React.FormEvent) => {\n event.preventDefault();\n setValidationError(null);\n if (!athleteId) {\n setValidationError('Choose the athlete to assess.');\n return;\n }\n if (!programId) {\n setValidationError('Choose the program the proposal should land on.');\n return;\n }\n adjust.mutate({ athleteId, programId });\n };\n\n return (\n <GlassCard treatment=\"insight\" className=\"p-5\">\n <div className=\"flex items-start gap-3\">\n <div className=\"flex h-10 w-10 shrink-0 items-center justify-center rounded-xl bg-[var(--color-accent-soft)] text-text-primary\">\n <Activity className=\"h-5 w-5\" aria-hidden=\"true\" />\n </div>\n <div className=\"min-w-0\">\n <h3 className=\"text-base font-semibold text-text-primary\">Assess an athlete</h3>\n <p className=\"mt-1 text-sm text-text-secondary\">\n Reads their recent workout logs and metrics and proposes progress / maintain / deload /\n at-risk. A coach still decides.\n </p>\n </div>\n </div>\n\n <form onSubmit={handleSubmit} className=\"mt-4 space-y-4\">\n <AthleteSelect\n idPrefix=\"assess\"\n required\n athleteId={athleteId}\n onSelect={(value) => setAthleteId(value.athleteId)}\n />\n\n <FormField label=\"Program\" htmlFor=\"assess-program\" required>\n <select\n id=\"assess-program\"\n className={fieldInputClass}\n value={programId}\n onChange={(event) => setProgramId(event.target.value)}\n >\n <option value=\"\">Select a program…</option>\n {(programs.data?.items ?? []).map((program) => (\n <option key={program.id} value={program.id}>\n {program.name}\n </option>\n ))}\n </select>\n </FormField>\n\n {validationError && <p className=\"text-sm text-status-error-text\">{validationError}</p>}\n {adjust.isError && <AiErrorNotice error={adjust.error} />}\n {adjust.isSuccess && adjust.data && <AdjustmentResult adjustment={adjust.data} />}\n\n <button\n type=\"submit\"\n disabled={adjust.isPending}\n className=\"inline-flex w-full items-center justify-center gap-1.5 rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text transition-colors hover:bg-action-primary-bg/90 disabled:opacity-60\"\n >\n {adjust.isPending ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <Sparkles className=\"h-4 w-4\" />\n )}\n {adjust.isPending ? 'Asking the model…' : 'Run assessment'}\n </button>\n </form>\n </GlassCard>\n );\n}\n\nexport function RunDecisionPanel({ className }: { className?: string }) {\n return (\n <div className={className}>\n <div className=\"grid grid-cols-1 gap-6 lg:grid-cols-2\">\n <GenerateProgramCard />\n <AssessAthleteCard />\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { AthAiAssessment } from '../../types';
2
+
3
+ export declare const ASSESSMENT_LABELS: Record<AthAiAssessment, string>;
4
+ export declare const ASSESSMENT_DESCRIPTIONS: Record<AthAiAssessment, string>;
5
+ /** StatusBadge variant per assessment. */
6
+ export declare const ASSESSMENT_VARIANT: Record<AthAiAssessment, 'success' | 'info' | 'warning' | 'destructive'>;
7
+ /** Ordered options for the override form select. */
8
+ export declare const ASSESSMENT_OPTIONS: ReadonlyArray<AthAiAssessment>;
9
+ /**
10
+ * How the program's `lastAiAdjustment.status` reads. PROPOSED means nothing has
11
+ * been applied to the athlete's plan yet.
12
+ */
13
+ export declare const ADJUSTMENT_STATUS_LABELS: Record<string, string>;
14
+ //# sourceMappingURL=assessment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assessment.d.ts","sourceRoot":"","sources":["../../../../src/atheletebridge/components/ai/assessment.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,eAAe,EAAE,MAAM,CAK7D,CAAC;AAEF,eAAO,MAAM,uBAAuB,EAAE,MAAM,CAAC,eAAe,EAAE,MAAM,CAKnE,CAAC;AAEF,0CAA0C;AAC1C,eAAO,MAAM,kBAAkB,EAAE,MAAM,CACrC,eAAe,EACf,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,aAAa,CAM/C,CAAC;AAEF,oDAAoD;AACpD,eAAO,MAAM,kBAAkB,EAAE,aAAa,CAAC,eAAe,CAK7D,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,wBAAwB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAI3D,CAAC"}
@@ -0,0 +1,30 @@
1
+ //#region src/atheletebridge/components/ai/assessment.ts
2
+ var e = {
3
+ PROGRESSION: "Progress",
4
+ MAINTAIN: "Maintain",
5
+ DELOAD: "Deload",
6
+ AT_RISK: "At risk"
7
+ }, t = {
8
+ PROGRESSION: "The athlete is absorbing the work — increase the load.",
9
+ MAINTAIN: "Hold the current prescription.",
10
+ DELOAD: "Back the load off to let the athlete recover.",
11
+ AT_RISK: "The trend suggests overload or injury risk — escalate."
12
+ }, n = {
13
+ PROGRESSION: "success",
14
+ MAINTAIN: "info",
15
+ DELOAD: "warning",
16
+ AT_RISK: "destructive"
17
+ }, r = [
18
+ "PROGRESSION",
19
+ "MAINTAIN",
20
+ "DELOAD",
21
+ "AT_RISK"
22
+ ], i = {
23
+ PROPOSED: "Awaiting a coach",
24
+ ACCEPTED: "Accepted by a coach",
25
+ OVERRIDDEN: "Overridden by a coach"
26
+ };
27
+ //#endregion
28
+ export { i as ADJUSTMENT_STATUS_LABELS, t as ASSESSMENT_DESCRIPTIONS, e as ASSESSMENT_LABELS, r as ASSESSMENT_OPTIONS, n as ASSESSMENT_VARIANT };
29
+
30
+ //# sourceMappingURL=assessment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assessment.js","names":[],"sources":["../../../../src/atheletebridge/components/ai/assessment.ts"],"sourcesContent":["/**\n * Assessment display helpers\n * @module atheletebridge/components/ai\n *\n * `AthAiAssessment` is the coaching call an AI proposal (or a coach override)\n * lands on. Labels and badge tones live here so the feed, the decision cards\n * and the override form can never describe the same value differently.\n */\n\nimport type { AthAiAssessment } from '../../types';\n\nexport const ASSESSMENT_LABELS: Record<AthAiAssessment, string> = {\n PROGRESSION: 'Progress',\n MAINTAIN: 'Maintain',\n DELOAD: 'Deload',\n AT_RISK: 'At risk',\n};\n\nexport const ASSESSMENT_DESCRIPTIONS: Record<AthAiAssessment, string> = {\n PROGRESSION: 'The athlete is absorbing the work — increase the load.',\n MAINTAIN: 'Hold the current prescription.',\n DELOAD: 'Back the load off to let the athlete recover.',\n AT_RISK: 'The trend suggests overload or injury risk — escalate.',\n};\n\n/** StatusBadge variant per assessment. */\nexport const ASSESSMENT_VARIANT: Record<\n AthAiAssessment,\n 'success' | 'info' | 'warning' | 'destructive'\n> = {\n PROGRESSION: 'success',\n MAINTAIN: 'info',\n DELOAD: 'warning',\n AT_RISK: 'destructive',\n};\n\n/** Ordered options for the override form select. */\nexport const ASSESSMENT_OPTIONS: ReadonlyArray<AthAiAssessment> = [\n 'PROGRESSION',\n 'MAINTAIN',\n 'DELOAD',\n 'AT_RISK',\n];\n\n/**\n * How the program's `lastAiAdjustment.status` reads. PROPOSED means nothing has\n * been applied to the athlete's plan yet.\n */\nexport const ADJUSTMENT_STATUS_LABELS: Record<string, string> = {\n PROPOSED: 'Awaiting a coach',\n ACCEPTED: 'Accepted by a coach',\n OVERRIDDEN: 'Overridden by a coach',\n};\n"],"mappings":";AAWA,IAAa,IAAqD;CAChE,aAAa;CACb,UAAU;CACV,QAAQ;CACR,SAAS;AACX,GAEa,IAA2D;CACtE,aAAa;CACb,UAAU;CACV,QAAQ;CACR,SAAS;AACX,GAGa,IAGT;CACF,aAAa;CACb,UAAU;CACV,QAAQ;CACR,SAAS;AACX,GAGa,IAAqD;CAChE;CACA;CACA;CACA;AACF,GAMa,IAAmD;CAC9D,UAAU;CACV,UAAU;CACV,YAAY;AACd"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * AI components Index
3
+ * @module atheletebridge/components/ai
4
+ */
5
+ export { AiErrorNotice } from './AiErrorNotice';
6
+ export { AiModelPicker } from './AiModelPicker';
7
+ export { AgentRunFeed } from './AgentRunFeed';
8
+ export { DecisionCard } from './DecisionCard';
9
+ export { RunDecisionPanel } from './RunDecisionPanel';
10
+ export { ASSESSMENT_LABELS, ASSESSMENT_DESCRIPTIONS, ASSESSMENT_VARIANT, ASSESSMENT_OPTIONS, ADJUSTMENT_STATUS_LABELS, } from './assessment';
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/atheletebridge/components/ai/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EACL,iBAAiB,EACjB,uBAAuB,EACvB,kBAAkB,EAClB,kBAAkB,EAClB,wBAAwB,GACzB,MAAM,cAAc,CAAC"}
@@ -25,6 +25,7 @@ export type { AthleteSelectValue } from './AthleteSelect';
25
25
  export { UserSearchSelect } from './UserSearchSelect';
26
26
  export type { UserSelectValue } from './UserSearchSelect';
27
27
  export { DrillVideoLink } from './DrillVideoLink';
28
+ export * from './ai';
28
29
  export * from './viz';
29
30
  export { SPORT_ICONS, SPORT_LABELS, PROGRAM_LEVEL_LABELS, MEMBER_ROLE_LABELS, FIXTURE_TYPE_LABELS, SESSION_TYPE_LABELS, METRIC_TYPE_LABELS, SPORT_OPTIONS, PROGRAM_LEVEL_OPTIONS, MEMBER_ROLE_OPTIONS, FIXTURE_TYPE_OPTIONS, SESSION_TYPE_OPTIONS, humanizeEnum, } from './domain';
30
31
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/atheletebridge/components/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,KAAK,EAAE,KAAK,UAAU,EAAE,MAAM,SAAS,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AACrF,OAAO,EACL,UAAU,EACV,KAAK,eAAe,EACpB,WAAW,EACX,KAAK,gBAAgB,EACrB,WAAW,EACX,KAAK,gBAAgB,EACrB,cAAc,EACd,KAAK,OAAO,GACb,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,KAAK,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AACjG,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,YAAY,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,YAAY,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,YAAY,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,cAAc,OAAO,CAAC;AACtB,OAAO,EACL,WAAW,EACX,YAAY,EACZ,oBAAoB,EACpB,kBAAkB,EAClB,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,EAClB,aAAa,EACb,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,oBAAoB,EACpB,YAAY,GACb,MAAM,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/atheletebridge/components/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,KAAK,EAAE,KAAK,UAAU,EAAE,MAAM,SAAS,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AACrF,OAAO,EACL,UAAU,EACV,KAAK,eAAe,EACpB,WAAW,EACX,KAAK,gBAAgB,EACrB,WAAW,EACX,KAAK,gBAAgB,EACrB,cAAc,EACd,KAAK,OAAO,GACb,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,KAAK,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AACjG,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,YAAY,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,YAAY,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,YAAY,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,cAAc,MAAM,CAAC;AACrB,cAAc,OAAO,CAAC;AACtB,OAAO,EACL,WAAW,EACX,YAAY,EACZ,oBAAoB,EACpB,kBAAkB,EAClB,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,EAClB,aAAa,EACb,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,oBAAoB,EACpB,YAAY,GACb,MAAM,UAAU,CAAC"}
@@ -1,3 +1,3 @@
1
- export { useTeams, useTeam, useTeamMembers, useCreateTeam, useUpdateTeam, useArchiveTeam, useAddMember, useRemoveMember, useFixtures, useFixture, useStandings, useScheduleFixture, useRecordFixtureResult, usePrograms, useProgram, useCreateProgram, useUpdateProgram, useTransitionProgram, useArchiveProgram, useAddDrill, useRemoveDrill, useSessions, useSession, useBookSession, useConfirmSession, useCompleteSession, useCancelSession, useWorkoutLogs, usePerformanceMetrics, useLogWorkout, useRecordMetric, useUploadFile, useFile, useUserSearch, directoryUserName, useUsersByIds, useUserDirectory, useRecentActivity, useAthleteProfile, useCoachAnalytics, useHealth, } from './useAthleteBridgeApi';
2
- export type { TeamFilters, FixtureFilters, ProgramFilters, SessionFilters, WorkoutLogFilters, WorkspaceFileRef, DirectoryUser, ResolvedUser, UserDirectory, ActivityType, ActivityItem, RecentActivityInput, AthleteProfile, SessionStatusCount, RatingByCoach, AnalyticsTrendPoint, CoachAnalytics, CoachAnalyticsOptions, } from './useAthleteBridgeApi';
1
+ export { useTeams, useTeam, useTeamMembers, useCreateTeam, useUpdateTeam, useArchiveTeam, useAddMember, useRemoveMember, useFixtures, useFixture, useStandings, useScheduleFixture, useRecordFixtureResult, usePrograms, useProgram, useCreateProgram, useUpdateProgram, useTransitionProgram, useArchiveProgram, useAddDrill, useRemoveDrill, useSessions, useSession, useBookSession, useConfirmSession, useCompleteSession, useCancelSession, useWorkoutLogs, usePerformanceMetrics, useLogWorkout, useRecordMetric, useUploadFile, useFile, useUserSearch, directoryUserName, useUsersByIds, useUserDirectory, useAiModelCatalog, useWorkspaceAiConfig, useSetWorkspaceAiModel, useSetWorkspaceAutoPilot, useAgentRuns, useAgentRun, useProgramAiState, useGenerateProgram, useAdjustPlanFromPerformance, useOverrideAgentRun, AthApiError, AI_PROVIDER_UNAVAILABLE, isAiProviderUnavailable, useRecentActivity, useAthleteProfile, useCoachAnalytics, useHealth, } from './useAthleteBridgeApi';
2
+ export type { TeamFilters, FixtureFilters, ProgramFilters, SessionFilters, WorkoutLogFilters, AgentRunFilters, WorkspaceFileRef, DirectoryUser, ResolvedUser, UserDirectory, ActivityType, ActivityItem, RecentActivityInput, AthleteProfile, SessionStatusCount, RatingByCoach, AnalyticsTrendPoint, CoachAnalytics, CoachAnalyticsOptions, } from './useAthleteBridgeApi';
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/atheletebridge/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,QAAQ,EACR,OAAO,EACP,cAAc,EACd,aAAa,EACb,aAAa,EACb,cAAc,EACd,YAAY,EACZ,eAAe,EAEf,WAAW,EACX,UAAU,EACV,YAAY,EACZ,kBAAkB,EAClB,sBAAsB,EAEtB,WAAW,EACX,UAAU,EACV,gBAAgB,EAChB,gBAAgB,EAChB,oBAAoB,EACpB,iBAAiB,EACjB,WAAW,EACX,cAAc,EAEd,WAAW,EACX,UAAU,EACV,cAAc,EACd,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAEhB,cAAc,EACd,qBAAqB,EACrB,aAAa,EACb,eAAe,EAEf,aAAa,EACb,OAAO,EAEP,aAAa,EACb,iBAAiB,EACjB,aAAa,EACb,gBAAgB,EAEhB,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EAEjB,SAAS,GACV,MAAM,uBAAuB,CAAC;AAE/B,YAAY,EACV,WAAW,EACX,cAAc,EACd,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,aAAa,EACb,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,mBAAmB,EACnB,cAAc,EACd,kBAAkB,EAClB,aAAa,EACb,mBAAmB,EACnB,cAAc,EACd,qBAAqB,GACtB,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/atheletebridge/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,QAAQ,EACR,OAAO,EACP,cAAc,EACd,aAAa,EACb,aAAa,EACb,cAAc,EACd,YAAY,EACZ,eAAe,EAEf,WAAW,EACX,UAAU,EACV,YAAY,EACZ,kBAAkB,EAClB,sBAAsB,EAEtB,WAAW,EACX,UAAU,EACV,gBAAgB,EAChB,gBAAgB,EAChB,oBAAoB,EACpB,iBAAiB,EACjB,WAAW,EACX,cAAc,EAEd,WAAW,EACX,UAAU,EACV,cAAc,EACd,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAEhB,cAAc,EACd,qBAAqB,EACrB,aAAa,EACb,eAAe,EAEf,aAAa,EACb,OAAO,EAEP,aAAa,EACb,iBAAiB,EACjB,aAAa,EACb,gBAAgB,EAEhB,iBAAiB,EACjB,oBAAoB,EACpB,sBAAsB,EACtB,wBAAwB,EACxB,YAAY,EACZ,WAAW,EACX,iBAAiB,EACjB,kBAAkB,EAClB,4BAA4B,EAC5B,mBAAmB,EACnB,WAAW,EACX,uBAAuB,EACvB,uBAAuB,EAEvB,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EAEjB,SAAS,GACV,MAAM,uBAAuB,CAAC;AAE/B,YAAY,EACV,WAAW,EACX,cAAc,EACd,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,mBAAmB,EACnB,cAAc,EACd,kBAAkB,EAClB,aAAa,EACb,mBAAmB,EACnB,cAAc,EACd,qBAAqB,GACtB,MAAM,uBAAuB,CAAC"}
@@ -1,5 +1,27 @@
1
- import { AthAvailability, AthCompleteSessionInput, AthCreateFixtureInput, AthCreateProgramInput, AthCreateTeamInput, AthAddMemberInput, AthAddDrillInput, AthBookSessionInput, AthDrill, AthFixture, AthFixtureConnection, AthFixtureStatus, AthLogWorkoutInput, AthMember, AthMemberStatus, AthPerformanceMetric, AthProgram, AthProgramConnection, AthProgramLevel, AthProgramStatus, AthRecordMetricInput, AthRecordResultInput, AthSession, AthSessionConnection, AthSessionStatus, AthSetAvailabilityInput, AthSport, AthStanding, AthTeam, AthTeamConnection, AthTeamStatus, AthUpdateProgramInput, AthUpdateTeamInput, AthWorkoutLog, AthWorkoutLogConnection, PaginationInput } from '../types';
1
+ import { AthAgentRun, AthAgentRunConnection, AthAgentRunOverride, AthAiAssessment, AthAiModelInfo, AthAvailability, AthCompleteSessionInput, AthCreateFixtureInput, AthCreateProgramInput, AthCreateTeamInput, AthAddMemberInput, AthAddDrillInput, AthBookSessionInput, AthDrill, AthFixture, AthFixtureConnection, AthFixtureStatus, AthGenerateProgramInput, AthGenerateProgramResult, AthLogWorkoutInput, AthMember, AthMemberStatus, AthPerformanceMetric, AthPlanAdjustment, AthProgram, AthProgramConnection, AthProgramLevel, AthProgramStatus, AthRecordMetricInput, AthRecordResultInput, AthSession, AthSessionConnection, AthSessionStatus, AthSetAvailabilityInput, AthSport, AthStanding, AthTeam, AthTeamConnection, AthTeamStatus, AthUpdateProgramInput, AthUpdateTeamInput, AthWorkoutLog, AthWorkoutLogConnection, AthWorkspaceAiConfig, PaginationInput } from '../types';
2
2
 
3
+ /** `extensions.code` for an upstream AI provider that is down or unconfigured. */
4
+ export declare const AI_PROVIDER_UNAVAILABLE = "AI_PROVIDER_UNAVAILABLE";
5
+ /**
6
+ * A GraphQL error surfaced with its `extensions` intact.
7
+ *
8
+ * The svc throws stable, typed errors (`NOT_FOUND`, `CONFLICT`,
9
+ * `FAILED_PRECONDITION`, `AI_PROVIDER_UNAVAILABLE`, `BAD_USER_INPUT`) and, for
10
+ * AI failures, an `extensions.agentRunId` pointing at the FAILED ledger row
11
+ * that holds every attempt's raw upstream message. Flattening all of that into
12
+ * `new Error(message)` is what made an unconfigured provider indistinguishable
13
+ * from a crashed service, so the code and the run id are carried through to the
14
+ * UI instead.
15
+ */
16
+ export declare class AthApiError extends Error {
17
+ /** `extensions.code`, or null when the server did not send one. */
18
+ readonly code: string | null;
19
+ /** `extensions.agentRunId` — the ledger row to inspect, when present. */
20
+ readonly agentRunId: string | null;
21
+ constructor(message: string, extensions?: Record<string, unknown>);
22
+ }
23
+ /** Whether an unknown thrown value is an AI-provider outage we can explain. */
24
+ export declare const isAiProviderUnavailable: (error: unknown) => error is AthApiError;
3
25
  export interface TeamFilters {
4
26
  sport?: AthSport;
5
27
  status?: AthTeamStatus;
@@ -228,5 +250,74 @@ export interface CoachAnalyticsOptions {
228
250
  }
229
251
  /** Aggregate real coaching data for the analytics dashboard. */
230
252
  export declare const useCoachAnalytics: (options?: CoachAnalyticsOptions) => CoachAnalytics;
253
+ /** The selectable (provider, model) pairs, with the platform default marked. */
254
+ export declare const useAiModelCatalog: () => import('@tanstack/react-query').UseQueryResult<NoInfer<AthAiModelInfo[]>, Error>;
255
+ /**
256
+ * The workspace's saved AI config, or null when it has never overridden the
257
+ * platform default chain (the query is nullable by design — a null here means
258
+ * "using the platform default", not "failed").
259
+ */
260
+ export declare const useWorkspaceAiConfig: () => import('@tanstack/react-query').UseQueryResult<NoInfer<AthWorkspaceAiConfig | null>, Error>;
261
+ export declare const useSetWorkspaceAiModel: () => import('@tanstack/react-query').UseMutationResult<AthWorkspaceAiConfig, Error, {
262
+ provider: string;
263
+ model: string;
264
+ }, unknown>;
265
+ /**
266
+ * Opt this workspace into (or out of) the autonomous coaching loop. The loop is
267
+ * ALSO gated per deployment by `ATHELETEBRIDGE_AGENT_LOOP_ENABLED`, so enabling
268
+ * it here does not on its own start anything — and even when it does run it
269
+ * only ever records a PROPOSED adjustment for a coach to resolve.
270
+ */
271
+ export declare const useSetWorkspaceAutoPilot: () => import('@tanstack/react-query').UseMutationResult<AthWorkspaceAiConfig, Error, boolean, unknown>;
272
+ export interface AgentRunFilters {
273
+ /** Rows per page. */
274
+ limit?: number;
275
+ /** Rows to skip. Offset-based: the composed PaginationInput has no cursor. */
276
+ offset?: number;
277
+ }
278
+ /** The workspace's AI decision ledger, most recent first. */
279
+ export declare const useAgentRuns: (filters?: AgentRunFilters) => import('@tanstack/react-query').UseQueryResult<NoInfer<AthAgentRunConnection>, Error>;
280
+ /**
281
+ * A single ledger row by id. Used to resolve the `extensions.agentRunId` an
282
+ * `AI_PROVIDER_UNAVAILABLE` error carries, so the user sees the recorded
283
+ * failure instead of a generic toast.
284
+ */
285
+ export declare const useAgentRun: (id: string | undefined) => import('@tanstack/react-query').UseQueryResult<NoInfer<AthAgentRun | null>, Error>;
286
+ /**
287
+ * A program with its AI provenance (`context.lastAiAdjustment`). Kept separate
288
+ * from {@link useProgram} so the `context` selection — which only the AI
289
+ * Operations page needs — stays off every other program read.
290
+ */
291
+ export declare const useProgramAiState: (id: string | undefined) => import('@tanstack/react-query').UseQueryResult<NoInfer<(Pick<AthProgram, "status" | "id" | "name"> & {
292
+ context: unknown;
293
+ }) | null>, Error>;
294
+ /**
295
+ * Generate a DRAFT program from a live model call. Throws {@link AthApiError}
296
+ * with code `AI_PROVIDER_UNAVAILABLE` (and the FAILED ledger row's id) when no
297
+ * provider in the chain could answer.
298
+ */
299
+ export declare const useGenerateProgram: () => import('@tanstack/react-query').UseMutationResult<AthGenerateProgramResult, Error, AthGenerateProgramInput, unknown>;
300
+ /**
301
+ * Ask the AI to read an athlete's recent load/metric trend and PROPOSE an
302
+ * adjustment onto a program. It changes no prescribed training load by itself —
303
+ * a coach resolves it with {@link useOverrideAgentRun}.
304
+ */
305
+ export declare const useAdjustPlanFromPerformance: () => import('@tanstack/react-query').UseMutationResult<AthPlanAdjustment, Error, {
306
+ athleteId: string;
307
+ programId: string;
308
+ requestedProvider?: string;
309
+ }, unknown>;
310
+ /**
311
+ * A coach's review of a prior AI decision. Recorded as a NEW, append-only
312
+ * ledger row — never an edit of the original — which resolves the program's
313
+ * `lastAiAdjustment` to ACCEPTED (same assessment) or OVERRIDDEN (a different
314
+ * one).
315
+ */
316
+ export declare const useOverrideAgentRun: () => import('@tanstack/react-query').UseMutationResult<AthAgentRunOverride, Error, {
317
+ runId: string;
318
+ programId: string;
319
+ assessment: AthAiAssessment;
320
+ note: string;
321
+ }, unknown>;
231
322
  export declare const useHealth: () => import('@tanstack/react-query').UseQueryResult<string, Error>;
232
323
  //# sourceMappingURL=useAthleteBridgeApi.d.ts.map