@burdenoff/microfe-atheletebridge 2026.801.2 → 2026.801.3

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 +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"AthleteBridgeRoot.d.ts","sourceRoot":"","sources":["../../src/atheletebridge/AthleteBridgeRoot.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAkBhC,OAAO,KAAK,EAAE,sBAAsB,EAAW,MAAM,SAAS,CAAC;AAY/D,eAAO,MAAM,iBAAiB,EAAE,EAAE,CAAC,sBAAsB,CAgIxD,CAAC"}
1
+ {"version":3,"file":"AthleteBridgeRoot.d.ts","sourceRoot":"","sources":["../../src/atheletebridge/AthleteBridgeRoot.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAmBhC,OAAO,KAAK,EAAE,sBAAsB,EAAW,MAAM,SAAS,CAAC;AAY/D,eAAO,MAAM,iBAAiB,EAAE,EAAE,CAAC,sBAAsB,CAwIxD,CAAC"}
@@ -4,115 +4,123 @@ import { AthleteBridgeRoutes as n } from "./AthleteBridgeRoutes.js";
4
4
  import { useEffect as r } from "react";
5
5
  import { QueryClient as i, QueryClientProvider as a } from "@tanstack/react-query";
6
6
  import { FeatureFlagProvider as o } from "@burdenoff/fe-libs/shared/feature-flags";
7
- import { BarChart3 as s, CalendarDays as c, ClipboardCheck as l, Dumbbell as u, Gauge as d, LayoutDashboard as f, Swords as p, Trophy as m, Users as h } from "lucide-react";
8
- import { jsx as g } from "react/jsx-runtime";
7
+ import { BarChart3 as s, CalendarDays as c, ClipboardCheck as l, Cpu as u, Dumbbell as d, Gauge as f, LayoutDashboard as p, Swords as m, Trophy as h, Users as g } from "lucide-react";
8
+ import { jsx as _ } from "react/jsx-runtime";
9
9
  //#region src/atheletebridge/AthleteBridgeRoot.tsx
10
- var _ = new i({ defaultOptions: { queries: {
10
+ var v = new i({ defaultOptions: { queries: {
11
11
  staleTime: 300 * 1e3,
12
12
  retry: 1
13
- } } }), v = (i) => {
14
- let { registerNavItems: v, registerFooterItems: y, basePath: b = "/", workspaceId: x } = i, S = e(), C = (e, t) => (e.endsWith("/") ? e.slice(0, -1) : e) + (t.startsWith("/") ? t : `/${t}`);
13
+ } } }), y = (i) => {
14
+ let { registerNavItems: y, registerFooterItems: b, basePath: x = "/", workspaceId: S } = i, C = e(), w = (e, t) => (e.endsWith("/") ? e.slice(0, -1) : e) + (t.startsWith("/") ? t : `/${t}`);
15
15
  return r(() => {
16
- if (v) return v([
16
+ if (y) return y([
17
17
  {
18
18
  id: "atheletebridge-dashboard",
19
- label: S("atheletebridge.nav.dashboard", "Dashboard"),
20
- path: C(b, ""),
21
- icon: /* @__PURE__ */ g(f, { size: 20 }),
19
+ label: C("atheletebridge.nav.dashboard", "Dashboard"),
20
+ path: w(x, ""),
21
+ icon: /* @__PURE__ */ _(p, { size: 20 }),
22
22
  order: 1,
23
23
  group: "main"
24
24
  },
25
25
  {
26
26
  id: "atheletebridge-teams",
27
- label: S("atheletebridge.nav.teams", "Teams"),
28
- path: C(b, "teams"),
29
- icon: /* @__PURE__ */ g(h, { size: 20 }),
27
+ label: C("atheletebridge.nav.teams", "Teams"),
28
+ path: w(x, "teams"),
29
+ icon: /* @__PURE__ */ _(g, { size: 20 }),
30
30
  order: 10,
31
31
  group: "roster"
32
32
  },
33
33
  {
34
34
  id: "atheletebridge-fixtures",
35
- label: S("atheletebridge.nav.fixtures", "Fixtures"),
36
- path: C(b, "fixtures"),
37
- icon: /* @__PURE__ */ g(c, { size: 20 }),
35
+ label: C("atheletebridge.nav.fixtures", "Fixtures"),
36
+ path: w(x, "fixtures"),
37
+ icon: /* @__PURE__ */ _(c, { size: 20 }),
38
38
  order: 11,
39
39
  group: "roster"
40
40
  },
41
41
  {
42
42
  id: "atheletebridge-standings",
43
- label: S("atheletebridge.nav.standings", "Standings"),
44
- path: C(b, "standings"),
45
- icon: /* @__PURE__ */ g(m, { size: 20 }),
43
+ label: C("atheletebridge.nav.standings", "Standings"),
44
+ path: w(x, "standings"),
45
+ icon: /* @__PURE__ */ _(h, { size: 20 }),
46
46
  order: 12,
47
47
  group: "roster"
48
48
  },
49
49
  {
50
50
  id: "atheletebridge-tournaments",
51
- label: S("atheletebridge.nav.tournaments", "Tournaments"),
52
- path: C(b, "tournaments"),
53
- icon: /* @__PURE__ */ g(p, { size: 20 }),
51
+ label: C("atheletebridge.nav.tournaments", "Tournaments"),
52
+ path: w(x, "tournaments"),
53
+ icon: /* @__PURE__ */ _(m, { size: 20 }),
54
54
  order: 13,
55
55
  group: "roster"
56
56
  },
57
57
  {
58
58
  id: "atheletebridge-programs",
59
- label: S("atheletebridge.nav.programs", "Programs"),
60
- path: C(b, "programs"),
61
- icon: /* @__PURE__ */ g(u, { size: 20 }),
59
+ label: C("atheletebridge.nav.programs", "Programs"),
60
+ path: w(x, "programs"),
61
+ icon: /* @__PURE__ */ _(d, { size: 20 }),
62
62
  order: 20,
63
63
  group: "training"
64
64
  },
65
65
  {
66
66
  id: "atheletebridge-sessions",
67
- label: S("atheletebridge.nav.sessions", "Sessions"),
68
- path: C(b, "sessions"),
69
- icon: /* @__PURE__ */ g(l, { size: 20 }),
67
+ label: C("atheletebridge.nav.sessions", "Sessions"),
68
+ path: w(x, "sessions"),
69
+ icon: /* @__PURE__ */ _(l, { size: 20 }),
70
70
  order: 21,
71
71
  group: "training"
72
72
  },
73
73
  {
74
74
  id: "atheletebridge-performance",
75
- label: S("atheletebridge.nav.performance", "Performance"),
76
- path: C(b, "performance"),
77
- icon: /* @__PURE__ */ g(d, { size: 20 }),
75
+ label: C("atheletebridge.nav.performance", "Performance"),
76
+ path: w(x, "performance"),
77
+ icon: /* @__PURE__ */ _(f, { size: 20 }),
78
78
  order: 22,
79
79
  group: "training"
80
80
  },
81
81
  {
82
82
  id: "atheletebridge-analytics",
83
- label: S("atheletebridge.nav.analytics", "Analytics"),
84
- path: C(b, "analytics"),
85
- icon: /* @__PURE__ */ g(s, { size: 20 }),
83
+ label: C("atheletebridge.nav.analytics", "Analytics"),
84
+ path: w(x, "analytics"),
85
+ icon: /* @__PURE__ */ _(s, { size: 20 }),
86
86
  order: 23,
87
87
  group: "training"
88
+ },
89
+ {
90
+ id: "atheletebridge-ai",
91
+ label: C("atheletebridge.nav.ai", "AI Operations"),
92
+ path: w(x, "ai"),
93
+ icon: /* @__PURE__ */ _(u, { size: 20 }),
94
+ order: 24,
95
+ group: "training"
88
96
  }
89
97
  ]);
90
98
  }, [
91
- v,
92
- b,
93
- S
99
+ y,
100
+ x,
101
+ C
94
102
  ]), r(() => {
95
- if (y) return y([{
103
+ if (b) return b([{
96
104
  id: "atheletebridge-status",
97
- label: S("atheletebridge.footer.ready", "AthleteBridge Ready"),
105
+ label: C("atheletebridge.footer.ready", "AthleteBridge Ready"),
98
106
  type: "status",
99
107
  order: 10,
100
108
  section: "left"
101
109
  }]);
102
- }, [y, S]), /* @__PURE__ */ g(a, {
103
- client: _,
104
- children: /* @__PURE__ */ g(o, {
105
- workspaceId: x ?? null,
110
+ }, [b, C]), /* @__PURE__ */ _(a, {
111
+ client: v,
112
+ children: /* @__PURE__ */ _(o, {
113
+ workspaceId: S ?? null,
106
114
  gateway: "global",
107
115
  defaultEnabled: !0,
108
- children: /* @__PURE__ */ g(t, {
116
+ children: /* @__PURE__ */ _(t, {
109
117
  ...i,
110
- children: /* @__PURE__ */ g(n, {})
118
+ children: /* @__PURE__ */ _(n, {})
111
119
  })
112
120
  })
113
121
  });
114
122
  };
115
123
  //#endregion
116
- export { v as AthleteBridgeRoot };
124
+ export { y as AthleteBridgeRoot };
117
125
 
118
126
  //# sourceMappingURL=AthleteBridgeRoot.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AthleteBridgeRoot.js","names":[],"sources":["../../src/atheletebridge/AthleteBridgeRoot.tsx"],"sourcesContent":["/**\n * AthleteBridge Root Component\n * @module atheletebridge\n *\n * The single Root export consumed by the host app shell. The export name and\n * props (AthleteBridgeRootProps) are the host contract and must not change —\n * only the internal nav config, provider tree, and routes are product-specific.\n */\n\nimport type { FC } from 'react';\nimport { useEffect } from 'react';\nimport { QueryClient, QueryClientProvider } from '@tanstack/react-query';\nimport { useAbTranslate } from './i18n';\nimport { FeatureFlagProvider } from '@burdenoff/fe-libs/shared/feature-flags';\nimport {\n LayoutDashboard,\n Users,\n CalendarDays,\n Trophy,\n Dumbbell,\n ClipboardCheck,\n Gauge,\n BarChart3,\n Swords,\n} from 'lucide-react';\nimport { AthleteBridgeProvider } from './context/AthleteBridgeContext';\nimport { AthleteBridgeRoutes } from './AthleteBridgeRoutes';\nimport type { AthleteBridgeRootProps, NavItem } from './types';\n\n// Create a query client for this microfrontend\nconst queryClient = new QueryClient({\n defaultOptions: {\n queries: {\n staleTime: 5 * 60 * 1000,\n retry: 1,\n },\n },\n});\n\nexport const AthleteBridgeRoot: FC<AthleteBridgeRootProps> = (props) => {\n const { registerNavItems, registerFooterItems, basePath = '/', workspaceId } = props;\n const t = useAbTranslate();\n\n // Helper to join paths correctly\n const joinPath = (base: string, path: string): string => {\n const cleanBase = base.endsWith('/') ? base.slice(0, -1) : base;\n const cleanPath = path.startsWith('/') ? path : `/${path}`;\n return cleanBase + cleanPath;\n };\n\n // Register navigation items with shell on mount\n useEffect(() => {\n if (!registerNavItems) return;\n\n const navItems: NavItem[] = [\n {\n id: 'atheletebridge-dashboard',\n label: t('atheletebridge.nav.dashboard', 'Dashboard'),\n path: joinPath(basePath, ''),\n icon: <LayoutDashboard size={20} />,\n order: 1,\n group: 'main',\n },\n {\n id: 'atheletebridge-teams',\n label: t('atheletebridge.nav.teams', 'Teams'),\n path: joinPath(basePath, 'teams'),\n icon: <Users size={20} />,\n order: 10,\n group: 'roster',\n },\n {\n id: 'atheletebridge-fixtures',\n label: t('atheletebridge.nav.fixtures', 'Fixtures'),\n path: joinPath(basePath, 'fixtures'),\n icon: <CalendarDays size={20} />,\n order: 11,\n group: 'roster',\n },\n {\n id: 'atheletebridge-standings',\n label: t('atheletebridge.nav.standings', 'Standings'),\n path: joinPath(basePath, 'standings'),\n icon: <Trophy size={20} />,\n order: 12,\n group: 'roster',\n },\n {\n id: 'atheletebridge-tournaments',\n label: t('atheletebridge.nav.tournaments', 'Tournaments'),\n path: joinPath(basePath, 'tournaments'),\n icon: <Swords size={20} />,\n order: 13,\n group: 'roster',\n },\n {\n id: 'atheletebridge-programs',\n label: t('atheletebridge.nav.programs', 'Programs'),\n path: joinPath(basePath, 'programs'),\n icon: <Dumbbell size={20} />,\n order: 20,\n group: 'training',\n },\n {\n id: 'atheletebridge-sessions',\n label: t('atheletebridge.nav.sessions', 'Sessions'),\n path: joinPath(basePath, 'sessions'),\n icon: <ClipboardCheck size={20} />,\n order: 21,\n group: 'training',\n },\n {\n id: 'atheletebridge-performance',\n label: t('atheletebridge.nav.performance', 'Performance'),\n path: joinPath(basePath, 'performance'),\n icon: <Gauge size={20} />,\n order: 22,\n group: 'training',\n },\n {\n id: 'atheletebridge-analytics',\n label: t('atheletebridge.nav.analytics', 'Analytics'),\n path: joinPath(basePath, 'analytics'),\n icon: <BarChart3 size={20} />,\n order: 23,\n group: 'training',\n },\n ];\n\n const cleanup = registerNavItems(navItems);\n return cleanup;\n }, [registerNavItems, basePath, t]);\n\n // Register footer items\n useEffect(() => {\n if (!registerFooterItems) return;\n\n const footerItems = [\n {\n id: 'atheletebridge-status',\n label: t('atheletebridge.footer.ready', 'AthleteBridge Ready'),\n type: 'status' as const,\n order: 10,\n section: 'left' as const,\n },\n ];\n\n const cleanup = registerFooterItems(footerItems);\n return cleanup;\n }, [registerFooterItems, t]);\n\n return (\n <QueryClientProvider client={queryClient}>\n {/*\n * The host-supplied workspaceId MUST be forwarded: FeatureFlagProvider\n * skips the evaluation fetch entirely when it is null, which collapses\n * every gate onto its defaultValue and makes per-workspace/per-tenant\n * overrides unresolvable. defaultEnabled stays true so an outage of the\n * flag service degrades open rather than hiding shipped modules.\n */}\n <FeatureFlagProvider workspaceId={workspaceId ?? null} gateway=\"global\" defaultEnabled={true}>\n <AthleteBridgeProvider {...props}>\n <AthleteBridgeRoutes />\n </AthleteBridgeProvider>\n </FeatureFlagProvider>\n </QueryClientProvider>\n );\n};\n"],"mappings":";;;;;;;;;AA8BA,IAAM,IAAc,IAAI,EAAY,EAClC,gBAAgB,EACd,SAAS;CACP,WAAW,MAAS;CACpB,OAAO;AACT,EACF,EACF,CAAC,GAEY,KAAiD,MAAU;CACtE,IAAM,EAAE,qBAAkB,wBAAqB,cAAW,KAAK,mBAAgB,GACzE,IAAI,EAAe,GAGnB,KAAY,GAAc,OACZ,EAAK,SAAS,GAAG,IAAI,EAAK,MAAM,GAAG,EAAE,IAAI,MACzC,EAAK,WAAW,GAAG,IAAI,IAAO,IAAI;CAyGtD,OApGA,QAAgB;EACT,OA8EL,OADgB,EAAiB;GA1E/B;IACE,IAAI;IACJ,OAAO,EAAE,gCAAgC,WAAW;IACpD,MAAM,EAAS,GAAU,EAAE;IAC3B,MAAM,kBAAC,GAAD,EAAiB,MAAM,GAAK,CAAA;IAClC,OAAO;IACP,OAAO;GACT;GACA;IACE,IAAI;IACJ,OAAO,EAAE,4BAA4B,OAAO;IAC5C,MAAM,EAAS,GAAU,OAAO;IAChC,MAAM,kBAAC,GAAD,EAAO,MAAM,GAAK,CAAA;IACxB,OAAO;IACP,OAAO;GACT;GACA;IACE,IAAI;IACJ,OAAO,EAAE,+BAA+B,UAAU;IAClD,MAAM,EAAS,GAAU,UAAU;IACnC,MAAM,kBAAC,GAAD,EAAc,MAAM,GAAK,CAAA;IAC/B,OAAO;IACP,OAAO;GACT;GACA;IACE,IAAI;IACJ,OAAO,EAAE,gCAAgC,WAAW;IACpD,MAAM,EAAS,GAAU,WAAW;IACpC,MAAM,kBAAC,GAAD,EAAQ,MAAM,GAAK,CAAA;IACzB,OAAO;IACP,OAAO;GACT;GACA;IACE,IAAI;IACJ,OAAO,EAAE,kCAAkC,aAAa;IACxD,MAAM,EAAS,GAAU,aAAa;IACtC,MAAM,kBAAC,GAAD,EAAQ,MAAM,GAAK,CAAA;IACzB,OAAO;IACP,OAAO;GACT;GACA;IACE,IAAI;IACJ,OAAO,EAAE,+BAA+B,UAAU;IAClD,MAAM,EAAS,GAAU,UAAU;IACnC,MAAM,kBAAC,GAAD,EAAU,MAAM,GAAK,CAAA;IAC3B,OAAO;IACP,OAAO;GACT;GACA;IACE,IAAI;IACJ,OAAO,EAAE,+BAA+B,UAAU;IAClD,MAAM,EAAS,GAAU,UAAU;IACnC,MAAM,kBAAC,GAAD,EAAgB,MAAM,GAAK,CAAA;IACjC,OAAO;IACP,OAAO;GACT;GACA;IACE,IAAI;IACJ,OAAO,EAAE,kCAAkC,aAAa;IACxD,MAAM,EAAS,GAAU,aAAa;IACtC,MAAM,kBAAC,GAAD,EAAO,MAAM,GAAK,CAAA;IACxB,OAAO;IACP,OAAO;GACT;GACA;IACE,IAAI;IACJ,OAAO,EAAE,gCAAgC,WAAW;IACpD,MAAM,EAAS,GAAU,WAAW;IACpC,MAAM,kBAAC,GAAD,EAAW,MAAM,GAAK,CAAA;IAC5B,OAAO;IACP,OAAO;GACT;EAG+B,CAC1B;CACT,GAAG;EAAC;EAAkB;EAAU;CAAC,CAAC,GAGlC,QAAgB;EACT,OAaL,OADgB,EAAoB,CATlC;GACE,IAAI;GACJ,OAAO,EAAE,+BAA+B,qBAAqB;GAC7D,MAAM;GACN,OAAO;GACP,SAAS;EACX,CAGkC,CAC7B;CACT,GAAG,CAAC,GAAqB,CAAC,CAAC,GAGzB,kBAAC,GAAD;EAAqB,QAAQ;YAQ3B,kBAAC,GAAD;GAAqB,aAAa,KAAe;GAAM,SAAQ;GAAS,gBAAgB;aACtF,kBAAC,GAAD;IAAuB,GAAI;cACzB,kBAAC,GAAD,CAAsB,CAAA;GACD,CAAA;EACJ,CAAA;CACF,CAAA;AAEzB"}
1
+ {"version":3,"file":"AthleteBridgeRoot.js","names":[],"sources":["../../src/atheletebridge/AthleteBridgeRoot.tsx"],"sourcesContent":["/**\n * AthleteBridge Root Component\n * @module atheletebridge\n *\n * The single Root export consumed by the host app shell. The export name and\n * props (AthleteBridgeRootProps) are the host contract and must not change —\n * only the internal nav config, provider tree, and routes are product-specific.\n */\n\nimport type { FC } from 'react';\nimport { useEffect } from 'react';\nimport { QueryClient, QueryClientProvider } from '@tanstack/react-query';\nimport { useAbTranslate } from './i18n';\nimport { FeatureFlagProvider } from '@burdenoff/fe-libs/shared/feature-flags';\nimport {\n LayoutDashboard,\n Users,\n CalendarDays,\n Trophy,\n Dumbbell,\n ClipboardCheck,\n Gauge,\n BarChart3,\n Swords,\n Cpu,\n} from 'lucide-react';\nimport { AthleteBridgeProvider } from './context/AthleteBridgeContext';\nimport { AthleteBridgeRoutes } from './AthleteBridgeRoutes';\nimport type { AthleteBridgeRootProps, NavItem } from './types';\n\n// Create a query client for this microfrontend\nconst queryClient = new QueryClient({\n defaultOptions: {\n queries: {\n staleTime: 5 * 60 * 1000,\n retry: 1,\n },\n },\n});\n\nexport const AthleteBridgeRoot: FC<AthleteBridgeRootProps> = (props) => {\n const { registerNavItems, registerFooterItems, basePath = '/', workspaceId } = props;\n const t = useAbTranslate();\n\n // Helper to join paths correctly\n const joinPath = (base: string, path: string): string => {\n const cleanBase = base.endsWith('/') ? base.slice(0, -1) : base;\n const cleanPath = path.startsWith('/') ? path : `/${path}`;\n return cleanBase + cleanPath;\n };\n\n // Register navigation items with shell on mount\n useEffect(() => {\n if (!registerNavItems) return;\n\n const navItems: NavItem[] = [\n {\n id: 'atheletebridge-dashboard',\n label: t('atheletebridge.nav.dashboard', 'Dashboard'),\n path: joinPath(basePath, ''),\n icon: <LayoutDashboard size={20} />,\n order: 1,\n group: 'main',\n },\n {\n id: 'atheletebridge-teams',\n label: t('atheletebridge.nav.teams', 'Teams'),\n path: joinPath(basePath, 'teams'),\n icon: <Users size={20} />,\n order: 10,\n group: 'roster',\n },\n {\n id: 'atheletebridge-fixtures',\n label: t('atheletebridge.nav.fixtures', 'Fixtures'),\n path: joinPath(basePath, 'fixtures'),\n icon: <CalendarDays size={20} />,\n order: 11,\n group: 'roster',\n },\n {\n id: 'atheletebridge-standings',\n label: t('atheletebridge.nav.standings', 'Standings'),\n path: joinPath(basePath, 'standings'),\n icon: <Trophy size={20} />,\n order: 12,\n group: 'roster',\n },\n {\n id: 'atheletebridge-tournaments',\n label: t('atheletebridge.nav.tournaments', 'Tournaments'),\n path: joinPath(basePath, 'tournaments'),\n icon: <Swords size={20} />,\n order: 13,\n group: 'roster',\n },\n {\n id: 'atheletebridge-programs',\n label: t('atheletebridge.nav.programs', 'Programs'),\n path: joinPath(basePath, 'programs'),\n icon: <Dumbbell size={20} />,\n order: 20,\n group: 'training',\n },\n {\n id: 'atheletebridge-sessions',\n label: t('atheletebridge.nav.sessions', 'Sessions'),\n path: joinPath(basePath, 'sessions'),\n icon: <ClipboardCheck size={20} />,\n order: 21,\n group: 'training',\n },\n {\n id: 'atheletebridge-performance',\n label: t('atheletebridge.nav.performance', 'Performance'),\n path: joinPath(basePath, 'performance'),\n icon: <Gauge size={20} />,\n order: 22,\n group: 'training',\n },\n {\n id: 'atheletebridge-analytics',\n label: t('atheletebridge.nav.analytics', 'Analytics'),\n path: joinPath(basePath, 'analytics'),\n icon: <BarChart3 size={20} />,\n order: 23,\n group: 'training',\n },\n {\n id: 'atheletebridge-ai',\n label: t('atheletebridge.nav.ai', 'AI Operations'),\n path: joinPath(basePath, 'ai'),\n icon: <Cpu size={20} />,\n order: 24,\n group: 'training',\n },\n ];\n\n const cleanup = registerNavItems(navItems);\n return cleanup;\n }, [registerNavItems, basePath, t]);\n\n // Register footer items\n useEffect(() => {\n if (!registerFooterItems) return;\n\n const footerItems = [\n {\n id: 'atheletebridge-status',\n label: t('atheletebridge.footer.ready', 'AthleteBridge Ready'),\n type: 'status' as const,\n order: 10,\n section: 'left' as const,\n },\n ];\n\n const cleanup = registerFooterItems(footerItems);\n return cleanup;\n }, [registerFooterItems, t]);\n\n return (\n <QueryClientProvider client={queryClient}>\n {/*\n * The host-supplied workspaceId MUST be forwarded: FeatureFlagProvider\n * skips the evaluation fetch entirely when it is null, which collapses\n * every gate onto its defaultValue and makes per-workspace/per-tenant\n * overrides unresolvable. defaultEnabled stays true so an outage of the\n * flag service degrades open rather than hiding shipped modules.\n */}\n <FeatureFlagProvider workspaceId={workspaceId ?? null} gateway=\"global\" defaultEnabled={true}>\n <AthleteBridgeProvider {...props}>\n <AthleteBridgeRoutes />\n </AthleteBridgeProvider>\n </FeatureFlagProvider>\n </QueryClientProvider>\n );\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"AthleteBridgeRoutes.d.ts","sourceRoot":"","sources":["../../src/atheletebridge/AthleteBridgeRoutes.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,KAAK,EAAE,EAAkB,MAAM,OAAO,CAAC;AA4FhD,eAAO,MAAM,mBAAmB,EAAE,EAiNjC,CAAC"}
1
+ {"version":3,"file":"AthleteBridgeRoutes.d.ts","sourceRoot":"","sources":["../../src/atheletebridge/AthleteBridgeRoutes.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,KAAK,EAAE,EAAkB,MAAM,OAAO,CAAC;AAiGhD,eAAO,MAAM,mBAAmB,EAAE,EA2NjC,CAAC"}
@@ -7,15 +7,15 @@ import { Loader2 as o } from "lucide-react";
7
7
  import { Navigate as s, Route as c, Routes as l, useLocation as u } from "react-router";
8
8
  import { jsx as d, jsxs as f } from "react/jsx-runtime";
9
9
  //#region src/atheletebridge/AthleteBridgeRoutes.tsx
10
- var p = i(() => import("./pages/onboarding/OnboardingPage.js").then((e) => ({ default: e.OnboardingPage }))), m = i(() => import("./pages/teams/TeamsListPage.js").then((e) => ({ default: e.TeamsListPage }))), h = i(() => import("./pages/teams/TeamDetailPage.js").then((e) => ({ default: e.TeamDetailPage }))), g = i(() => import("./pages/teams/TeamFormPage.js").then((e) => ({ default: e.TeamFormPage }))), _ = i(() => import("./pages/fixtures/FixturesListPage.js").then((e) => ({ default: e.FixturesListPage }))), v = i(() => import("./pages/fixtures/FixtureDetailPage.js").then((e) => ({ default: e.FixtureDetailPage }))), y = i(() => import("./pages/fixtures/FixtureFormPage.js").then((e) => ({ default: e.FixtureFormPage }))), b = i(() => import("./pages/StandingsPage.js").then((e) => ({ default: e.StandingsPage }))), x = i(() => import("./pages/programs/ProgramsListPage.js").then((e) => ({ default: e.ProgramsListPage }))), S = i(() => import("./pages/programs/ProgramDetailPage.js").then((e) => ({ default: e.ProgramDetailPage }))), C = i(() => import("./pages/programs/ProgramFormPage.js").then((e) => ({ default: e.ProgramFormPage }))), w = i(() => import("./pages/sessions/SessionsListPage.js").then((e) => ({ default: e.SessionsListPage }))), T = i(() => import("./pages/sessions/SessionDetailPage.js").then((e) => ({ default: e.SessionDetailPage }))), E = i(() => import("./pages/sessions/SessionFormPage.js").then((e) => ({ default: e.SessionFormPage }))), D = i(() => import("./pages/performance/PerformancePage.js").then((e) => ({ default: e.PerformancePage }))), O = i(() => import("./pages/athletes/AthleteProfilePage.js").then((e) => ({ default: e.AthleteProfilePage }))), k = i(() => import("./pages/analytics/CoachAnalyticsPage.js").then((e) => ({ default: e.CoachAnalyticsPage }))), A = i(() => import("./pages/tournaments/TournamentBracketPage.js").then((e) => ({ default: e.TournamentBracketPage }))), j = () => /* @__PURE__ */ d("div", {
10
+ var p = i(() => import("./pages/onboarding/OnboardingPage.js").then((e) => ({ default: e.OnboardingPage }))), m = i(() => import("./pages/teams/TeamsListPage.js").then((e) => ({ default: e.TeamsListPage }))), h = i(() => import("./pages/teams/TeamDetailPage.js").then((e) => ({ default: e.TeamDetailPage }))), g = i(() => import("./pages/teams/TeamFormPage.js").then((e) => ({ default: e.TeamFormPage }))), _ = i(() => import("./pages/fixtures/FixturesListPage.js").then((e) => ({ default: e.FixturesListPage }))), v = i(() => import("./pages/fixtures/FixtureDetailPage.js").then((e) => ({ default: e.FixtureDetailPage }))), y = i(() => import("./pages/fixtures/FixtureFormPage.js").then((e) => ({ default: e.FixtureFormPage }))), b = i(() => import("./pages/StandingsPage.js").then((e) => ({ default: e.StandingsPage }))), x = i(() => import("./pages/programs/ProgramsListPage.js").then((e) => ({ default: e.ProgramsListPage }))), S = i(() => import("./pages/programs/ProgramDetailPage.js").then((e) => ({ default: e.ProgramDetailPage }))), C = i(() => import("./pages/programs/ProgramFormPage.js").then((e) => ({ default: e.ProgramFormPage }))), w = i(() => import("./pages/sessions/SessionsListPage.js").then((e) => ({ default: e.SessionsListPage }))), T = i(() => import("./pages/sessions/SessionDetailPage.js").then((e) => ({ default: e.SessionDetailPage }))), E = i(() => import("./pages/sessions/SessionFormPage.js").then((e) => ({ default: e.SessionFormPage }))), D = i(() => import("./pages/performance/PerformancePage.js").then((e) => ({ default: e.PerformancePage }))), O = i(() => import("./pages/athletes/AthleteProfilePage.js").then((e) => ({ default: e.AthleteProfilePage }))), k = i(() => import("./pages/analytics/CoachAnalyticsPage.js").then((e) => ({ default: e.CoachAnalyticsPage }))), A = i(() => import("./pages/ai/AiOperationsPage.js").then((e) => ({ default: e.AiOperationsPage }))), j = i(() => import("./pages/tournaments/TournamentBracketPage.js").then((e) => ({ default: e.TournamentBracketPage }))), M = () => /* @__PURE__ */ d("div", {
11
11
  className: "flex min-h-[400px] items-center justify-center",
12
12
  children: /* @__PURE__ */ d(o, { className: "h-8 w-8 animate-spin text-text-secondary" })
13
- }), M = () => {
14
- let { basePath: i, isStandalone: o } = e(), M = u(), N = i === "/" ? "" : (i ?? "").replace(/\/$/, "");
15
- return N && !o && !(M.pathname === N || M.pathname.startsWith(N + "/")) ? null : /* @__PURE__ */ d("div", {
13
+ }), N = () => {
14
+ let { basePath: i, isStandalone: o } = e(), N = u(), P = i === "/" ? "" : (i ?? "").replace(/\/$/, "");
15
+ return P && !o && !(N.pathname === P || N.pathname.startsWith(P + "/")) ? null : /* @__PURE__ */ d("div", {
16
16
  className: "flex min-h-full flex-col",
17
17
  children: /* @__PURE__ */ f(r, {
18
- fallback: /* @__PURE__ */ d(j, {}),
18
+ fallback: /* @__PURE__ */ d(M, {}),
19
19
  children: [/* @__PURE__ */ d(t, {}), /* @__PURE__ */ f(l, { children: [
20
20
  /* @__PURE__ */ d(c, {
21
21
  index: !0,
@@ -169,12 +169,20 @@ var p = i(() => import("./pages/onboarding/OnboardingPage.js").then((e) => ({ de
169
169
  children: /* @__PURE__ */ d(k, {})
170
170
  })
171
171
  }),
172
+ /* @__PURE__ */ d(c, {
173
+ path: "ai",
174
+ element: /* @__PURE__ */ d(a, {
175
+ flag: "atheletebridge.ai.enabled",
176
+ defaultValue: !0,
177
+ children: /* @__PURE__ */ d(A, {})
178
+ })
179
+ }),
172
180
  /* @__PURE__ */ d(c, {
173
181
  path: "tournaments",
174
182
  element: /* @__PURE__ */ d(a, {
175
183
  flag: "atheletebridge.tournaments.enabled",
176
184
  defaultValue: !0,
177
- children: /* @__PURE__ */ d(A, {})
185
+ children: /* @__PURE__ */ d(j, {})
178
186
  })
179
187
  }),
180
188
  /* @__PURE__ */ d(c, {
@@ -189,6 +197,6 @@ var p = i(() => import("./pages/onboarding/OnboardingPage.js").then((e) => ({ de
189
197
  });
190
198
  };
191
199
  //#endregion
192
- export { M as AthleteBridgeRoutes };
200
+ export { N as AthleteBridgeRoutes };
193
201
 
194
202
  //# sourceMappingURL=AthleteBridgeRoutes.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AthleteBridgeRoutes.js","names":[],"sources":["../../src/atheletebridge/AthleteBridgeRoutes.tsx"],"sourcesContent":["/**\n * AthleteBridge Routes\n * @module atheletebridge\n *\n * Real sports-domain routes wired to the deployed `wspace-atheletebridge-svc`\n * GraphQL contract. Dashboard is eager; entity pages are lazy.\n */\n\nimport { type FC, lazy, Suspense } from 'react';\nimport { Routes, Route, Navigate, useLocation } from 'react-router';\nimport { Loader2 } from 'lucide-react';\nimport { FeatureGate } from '@burdenoff/fe-libs/shared/feature-flags';\nimport { useAthleteBridge } from './context/AthleteBridgeContext';\nimport { RouteAnalytics } from './components/RouteAnalytics';\n\n// Eager — primary landing\nimport { DashboardPage } from './pages/DashboardPage';\n\n// Onboarding (first-run wizard: sport → team → role)\nconst OnboardingPage = lazy(() =>\n import('./pages/onboarding/OnboardingPage').then((m) => ({ default: m.OnboardingPage }))\n);\n\n// Teams\nconst TeamsListPage = lazy(() =>\n import('./pages/teams/TeamsListPage').then((m) => ({ default: m.TeamsListPage }))\n);\nconst TeamDetailPage = lazy(() =>\n import('./pages/teams/TeamDetailPage').then((m) => ({ default: m.TeamDetailPage }))\n);\nconst TeamFormPage = lazy(() =>\n import('./pages/teams/TeamFormPage').then((m) => ({ default: m.TeamFormPage }))\n);\n\n// Fixtures\nconst FixturesListPage = lazy(() =>\n import('./pages/fixtures/FixturesListPage').then((m) => ({ default: m.FixturesListPage }))\n);\nconst FixtureDetailPage = lazy(() =>\n import('./pages/fixtures/FixtureDetailPage').then((m) => ({ default: m.FixtureDetailPage }))\n);\nconst FixtureFormPage = lazy(() =>\n import('./pages/fixtures/FixtureFormPage').then((m) => ({ default: m.FixtureFormPage }))\n);\n\n// Standings\nconst StandingsPage = lazy(() =>\n import('./pages/StandingsPage').then((m) => ({ default: m.StandingsPage }))\n);\n\n// Programs\nconst ProgramsListPage = lazy(() =>\n import('./pages/programs/ProgramsListPage').then((m) => ({ default: m.ProgramsListPage }))\n);\nconst ProgramDetailPage = lazy(() =>\n import('./pages/programs/ProgramDetailPage').then((m) => ({ default: m.ProgramDetailPage }))\n);\nconst ProgramFormPage = lazy(() =>\n import('./pages/programs/ProgramFormPage').then((m) => ({ default: m.ProgramFormPage }))\n);\n\n// Sessions\nconst SessionsListPage = lazy(() =>\n import('./pages/sessions/SessionsListPage').then((m) => ({ default: m.SessionsListPage }))\n);\nconst SessionDetailPage = lazy(() =>\n import('./pages/sessions/SessionDetailPage').then((m) => ({ default: m.SessionDetailPage }))\n);\nconst SessionFormPage = lazy(() =>\n import('./pages/sessions/SessionFormPage').then((m) => ({ default: m.SessionFormPage }))\n);\n\n// Performance\nconst PerformancePage = lazy(() =>\n import('./pages/performance/PerformancePage').then((m) => ({ default: m.PerformancePage }))\n);\n\n// Athlete profile\nconst AthleteProfilePage = lazy(() =>\n import('./pages/athletes/AthleteProfilePage').then((m) => ({ default: m.AthleteProfilePage }))\n);\n\n// Coach analytics\nconst CoachAnalyticsPage = lazy(() =>\n import('./pages/analytics/CoachAnalyticsPage').then((m) => ({ default: m.CoachAnalyticsPage }))\n);\n\n// Tournaments (esports bracket)\nconst TournamentBracketPage = lazy(() =>\n import('./pages/tournaments/TournamentBracketPage').then((m) => ({\n default: m.TournamentBracketPage,\n }))\n);\n\nconst PageLoader: FC = () => (\n <div className=\"flex min-h-[400px] items-center justify-center\">\n <Loader2 className=\"h-8 w-8 animate-spin text-text-secondary\" />\n </div>\n);\n\nexport const AthleteBridgeRoutes: FC = () => {\n const { basePath, isStandalone } = useAthleteBridge();\n const location = useLocation();\n\n const normalizedBasePath = basePath === '/' ? '' : (basePath ?? '').replace(/\\/$/, '');\n\n // Guard: only render when the path matches basePath (integrated mode).\n if (normalizedBasePath && !isStandalone) {\n const pathMatches =\n location.pathname === normalizedBasePath ||\n location.pathname.startsWith(normalizedBasePath + '/');\n if (!pathMatches) {\n return null;\n }\n }\n\n return (\n <div className=\"flex min-h-full flex-col\">\n <Suspense fallback={<PageLoader />}>\n <RouteAnalytics />\n <Routes>\n {/* Dashboard */}\n <Route index element={<DashboardPage />} />\n\n {/*\n Onboarding — the first-run wizard. Intentionally NOT behind a\n FeatureGate: it only collects sport/team/role and writes through the\n same `athCreateTeam` / `athAddMember` the gated Teams pages use, so a\n flag here would gate nothing that `atheletebridge.teams.enabled` does\n not already gate at the destination.\n */}\n <Route path=\"onboarding\" element={<OnboardingPage />} />\n\n {/* Teams */}\n <Route\n path=\"teams\"\n element={\n <FeatureGate flag=\"atheletebridge.teams.enabled\" defaultValue={true}>\n <TeamsListPage />\n </FeatureGate>\n }\n />\n <Route\n path=\"teams/new\"\n element={\n <FeatureGate flag=\"atheletebridge.teams.enabled\" defaultValue={true}>\n <TeamFormPage />\n </FeatureGate>\n }\n />\n <Route\n path=\"teams/:id\"\n element={\n <FeatureGate flag=\"atheletebridge.teams.enabled\" defaultValue={true}>\n <TeamDetailPage />\n </FeatureGate>\n }\n />\n <Route\n path=\"teams/:id/edit\"\n element={\n <FeatureGate flag=\"atheletebridge.teams.enabled\" defaultValue={true}>\n <TeamFormPage />\n </FeatureGate>\n }\n />\n\n {/* Athlete profile (reached from a team roster) */}\n <Route\n path=\"teams/:teamId/athletes/:memberId\"\n element={\n <FeatureGate flag=\"atheletebridge.teams.enabled\" defaultValue={true}>\n <AthleteProfilePage />\n </FeatureGate>\n }\n />\n\n {/* Fixtures */}\n <Route\n path=\"fixtures\"\n element={\n <FeatureGate flag=\"atheletebridge.fixtures.enabled\" defaultValue={true}>\n <FixturesListPage />\n </FeatureGate>\n }\n />\n <Route\n path=\"fixtures/new\"\n element={\n <FeatureGate flag=\"atheletebridge.fixtures.enabled\" defaultValue={true}>\n <FixtureFormPage />\n </FeatureGate>\n }\n />\n <Route\n path=\"fixtures/:id\"\n element={\n <FeatureGate flag=\"atheletebridge.fixtures.enabled\" defaultValue={true}>\n <FixtureDetailPage />\n </FeatureGate>\n }\n />\n\n {/* Standings */}\n <Route\n path=\"standings\"\n element={\n <FeatureGate flag=\"atheletebridge.standings.enabled\" defaultValue={true}>\n <StandingsPage />\n </FeatureGate>\n }\n />\n\n {/* Programs */}\n <Route\n path=\"programs\"\n element={\n <FeatureGate flag=\"atheletebridge.programs.enabled\" defaultValue={true}>\n <ProgramsListPage />\n </FeatureGate>\n }\n />\n <Route\n path=\"programs/new\"\n element={\n <FeatureGate flag=\"atheletebridge.programs.enabled\" defaultValue={true}>\n <ProgramFormPage />\n </FeatureGate>\n }\n />\n <Route\n path=\"programs/:id\"\n element={\n <FeatureGate flag=\"atheletebridge.programs.enabled\" defaultValue={true}>\n <ProgramDetailPage />\n </FeatureGate>\n }\n />\n <Route\n path=\"programs/:id/edit\"\n element={\n <FeatureGate flag=\"atheletebridge.programs.enabled\" defaultValue={true}>\n <ProgramFormPage />\n </FeatureGate>\n }\n />\n\n {/* Sessions */}\n <Route\n path=\"sessions\"\n element={\n <FeatureGate flag=\"atheletebridge.sessions.enabled\" defaultValue={true}>\n <SessionsListPage />\n </FeatureGate>\n }\n />\n <Route\n path=\"sessions/new\"\n element={\n <FeatureGate flag=\"atheletebridge.sessions.enabled\" defaultValue={true}>\n <SessionFormPage />\n </FeatureGate>\n }\n />\n <Route\n path=\"sessions/:id\"\n element={\n <FeatureGate flag=\"atheletebridge.sessions.enabled\" defaultValue={true}>\n <SessionDetailPage />\n </FeatureGate>\n }\n />\n\n {/* Performance */}\n <Route\n path=\"performance\"\n element={\n <FeatureGate flag=\"atheletebridge.performance.enabled\" defaultValue={true}>\n <PerformancePage />\n </FeatureGate>\n }\n />\n\n {/* Analytics */}\n <Route\n path=\"analytics\"\n element={\n <FeatureGate flag=\"atheletebridge.analytics.enabled\" defaultValue={true}>\n <CoachAnalyticsPage />\n </FeatureGate>\n }\n />\n\n {/* Tournaments (esports bracket) */}\n <Route\n path=\"tournaments\"\n element={\n <FeatureGate flag=\"atheletebridge.tournaments.enabled\" defaultValue={true}>\n <TournamentBracketPage />\n </FeatureGate>\n }\n />\n\n {/* Fallback */}\n <Route path=\"*\" element={<Navigate to=\".\" replace />} />\n </Routes>\n </Suspense>\n </div>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"AthleteBridgeRoutes.js","names":[],"sources":["../../src/atheletebridge/AthleteBridgeRoutes.tsx"],"sourcesContent":["/**\n * AthleteBridge Routes\n * @module atheletebridge\n *\n * Real sports-domain routes wired to the deployed `wspace-atheletebridge-svc`\n * GraphQL contract. Dashboard is eager; entity pages are lazy.\n */\n\nimport { type FC, lazy, Suspense } from 'react';\nimport { Routes, Route, Navigate, useLocation } from 'react-router';\nimport { Loader2 } from 'lucide-react';\nimport { FeatureGate } from '@burdenoff/fe-libs/shared/feature-flags';\nimport { useAthleteBridge } from './context/AthleteBridgeContext';\nimport { RouteAnalytics } from './components/RouteAnalytics';\n\n// Eager — primary landing\nimport { DashboardPage } from './pages/DashboardPage';\n\n// Onboarding (first-run wizard: sport → team → role)\nconst OnboardingPage = lazy(() =>\n import('./pages/onboarding/OnboardingPage').then((m) => ({ default: m.OnboardingPage }))\n);\n\n// Teams\nconst TeamsListPage = lazy(() =>\n import('./pages/teams/TeamsListPage').then((m) => ({ default: m.TeamsListPage }))\n);\nconst TeamDetailPage = lazy(() =>\n import('./pages/teams/TeamDetailPage').then((m) => ({ default: m.TeamDetailPage }))\n);\nconst TeamFormPage = lazy(() =>\n import('./pages/teams/TeamFormPage').then((m) => ({ default: m.TeamFormPage }))\n);\n\n// Fixtures\nconst FixturesListPage = lazy(() =>\n import('./pages/fixtures/FixturesListPage').then((m) => ({ default: m.FixturesListPage }))\n);\nconst FixtureDetailPage = lazy(() =>\n import('./pages/fixtures/FixtureDetailPage').then((m) => ({ default: m.FixtureDetailPage }))\n);\nconst FixtureFormPage = lazy(() =>\n import('./pages/fixtures/FixtureFormPage').then((m) => ({ default: m.FixtureFormPage }))\n);\n\n// Standings\nconst StandingsPage = lazy(() =>\n import('./pages/StandingsPage').then((m) => ({ default: m.StandingsPage }))\n);\n\n// Programs\nconst ProgramsListPage = lazy(() =>\n import('./pages/programs/ProgramsListPage').then((m) => ({ default: m.ProgramsListPage }))\n);\nconst ProgramDetailPage = lazy(() =>\n import('./pages/programs/ProgramDetailPage').then((m) => ({ default: m.ProgramDetailPage }))\n);\nconst ProgramFormPage = lazy(() =>\n import('./pages/programs/ProgramFormPage').then((m) => ({ default: m.ProgramFormPage }))\n);\n\n// Sessions\nconst SessionsListPage = lazy(() =>\n import('./pages/sessions/SessionsListPage').then((m) => ({ default: m.SessionsListPage }))\n);\nconst SessionDetailPage = lazy(() =>\n import('./pages/sessions/SessionDetailPage').then((m) => ({ default: m.SessionDetailPage }))\n);\nconst SessionFormPage = lazy(() =>\n import('./pages/sessions/SessionFormPage').then((m) => ({ default: m.SessionFormPage }))\n);\n\n// Performance\nconst PerformancePage = lazy(() =>\n import('./pages/performance/PerformancePage').then((m) => ({ default: m.PerformancePage }))\n);\n\n// Athlete profile\nconst AthleteProfilePage = lazy(() =>\n import('./pages/athletes/AthleteProfilePage').then((m) => ({ default: m.AthleteProfilePage }))\n);\n\n// Coach analytics\nconst CoachAnalyticsPage = lazy(() =>\n import('./pages/analytics/CoachAnalyticsPage').then((m) => ({ default: m.CoachAnalyticsPage }))\n);\n\n// AI operations (model picker, decision ledger, decision cards)\nconst AiOperationsPage = lazy(() =>\n import('./pages/ai/AiOperationsPage').then((m) => ({ default: m.AiOperationsPage }))\n);\n\n// Tournaments (esports bracket)\nconst TournamentBracketPage = lazy(() =>\n import('./pages/tournaments/TournamentBracketPage').then((m) => ({\n default: m.TournamentBracketPage,\n }))\n);\n\nconst PageLoader: FC = () => (\n <div className=\"flex min-h-[400px] items-center justify-center\">\n <Loader2 className=\"h-8 w-8 animate-spin text-text-secondary\" />\n </div>\n);\n\nexport const AthleteBridgeRoutes: FC = () => {\n const { basePath, isStandalone } = useAthleteBridge();\n const location = useLocation();\n\n const normalizedBasePath = basePath === '/' ? '' : (basePath ?? '').replace(/\\/$/, '');\n\n // Guard: only render when the path matches basePath (integrated mode).\n if (normalizedBasePath && !isStandalone) {\n const pathMatches =\n location.pathname === normalizedBasePath ||\n location.pathname.startsWith(normalizedBasePath + '/');\n if (!pathMatches) {\n return null;\n }\n }\n\n return (\n <div className=\"flex min-h-full flex-col\">\n <Suspense fallback={<PageLoader />}>\n <RouteAnalytics />\n <Routes>\n {/* Dashboard */}\n <Route index element={<DashboardPage />} />\n\n {/*\n Onboarding — the first-run wizard. Intentionally NOT behind a\n FeatureGate: it only collects sport/team/role and writes through the\n same `athCreateTeam` / `athAddMember` the gated Teams pages use, so a\n flag here would gate nothing that `atheletebridge.teams.enabled` does\n not already gate at the destination.\n */}\n <Route path=\"onboarding\" element={<OnboardingPage />} />\n\n {/* Teams */}\n <Route\n path=\"teams\"\n element={\n <FeatureGate flag=\"atheletebridge.teams.enabled\" defaultValue={true}>\n <TeamsListPage />\n </FeatureGate>\n }\n />\n <Route\n path=\"teams/new\"\n element={\n <FeatureGate flag=\"atheletebridge.teams.enabled\" defaultValue={true}>\n <TeamFormPage />\n </FeatureGate>\n }\n />\n <Route\n path=\"teams/:id\"\n element={\n <FeatureGate flag=\"atheletebridge.teams.enabled\" defaultValue={true}>\n <TeamDetailPage />\n </FeatureGate>\n }\n />\n <Route\n path=\"teams/:id/edit\"\n element={\n <FeatureGate flag=\"atheletebridge.teams.enabled\" defaultValue={true}>\n <TeamFormPage />\n </FeatureGate>\n }\n />\n\n {/* Athlete profile (reached from a team roster) */}\n <Route\n path=\"teams/:teamId/athletes/:memberId\"\n element={\n <FeatureGate flag=\"atheletebridge.teams.enabled\" defaultValue={true}>\n <AthleteProfilePage />\n </FeatureGate>\n }\n />\n\n {/* Fixtures */}\n <Route\n path=\"fixtures\"\n element={\n <FeatureGate flag=\"atheletebridge.fixtures.enabled\" defaultValue={true}>\n <FixturesListPage />\n </FeatureGate>\n }\n />\n <Route\n path=\"fixtures/new\"\n element={\n <FeatureGate flag=\"atheletebridge.fixtures.enabled\" defaultValue={true}>\n <FixtureFormPage />\n </FeatureGate>\n }\n />\n <Route\n path=\"fixtures/:id\"\n element={\n <FeatureGate flag=\"atheletebridge.fixtures.enabled\" defaultValue={true}>\n <FixtureDetailPage />\n </FeatureGate>\n }\n />\n\n {/* Standings */}\n <Route\n path=\"standings\"\n element={\n <FeatureGate flag=\"atheletebridge.standings.enabled\" defaultValue={true}>\n <StandingsPage />\n </FeatureGate>\n }\n />\n\n {/* Programs */}\n <Route\n path=\"programs\"\n element={\n <FeatureGate flag=\"atheletebridge.programs.enabled\" defaultValue={true}>\n <ProgramsListPage />\n </FeatureGate>\n }\n />\n <Route\n path=\"programs/new\"\n element={\n <FeatureGate flag=\"atheletebridge.programs.enabled\" defaultValue={true}>\n <ProgramFormPage />\n </FeatureGate>\n }\n />\n <Route\n path=\"programs/:id\"\n element={\n <FeatureGate flag=\"atheletebridge.programs.enabled\" defaultValue={true}>\n <ProgramDetailPage />\n </FeatureGate>\n }\n />\n <Route\n path=\"programs/:id/edit\"\n element={\n <FeatureGate flag=\"atheletebridge.programs.enabled\" defaultValue={true}>\n <ProgramFormPage />\n </FeatureGate>\n }\n />\n\n {/* Sessions */}\n <Route\n path=\"sessions\"\n element={\n <FeatureGate flag=\"atheletebridge.sessions.enabled\" defaultValue={true}>\n <SessionsListPage />\n </FeatureGate>\n }\n />\n <Route\n path=\"sessions/new\"\n element={\n <FeatureGate flag=\"atheletebridge.sessions.enabled\" defaultValue={true}>\n <SessionFormPage />\n </FeatureGate>\n }\n />\n <Route\n path=\"sessions/:id\"\n element={\n <FeatureGate flag=\"atheletebridge.sessions.enabled\" defaultValue={true}>\n <SessionDetailPage />\n </FeatureGate>\n }\n />\n\n {/* Performance */}\n <Route\n path=\"performance\"\n element={\n <FeatureGate flag=\"atheletebridge.performance.enabled\" defaultValue={true}>\n <PerformancePage />\n </FeatureGate>\n }\n />\n\n {/* Analytics */}\n <Route\n path=\"analytics\"\n element={\n <FeatureGate flag=\"atheletebridge.analytics.enabled\" defaultValue={true}>\n <CoachAnalyticsPage />\n </FeatureGate>\n }\n />\n\n {/* AI operations */}\n <Route\n path=\"ai\"\n element={\n <FeatureGate flag=\"atheletebridge.ai.enabled\" defaultValue={true}>\n <AiOperationsPage />\n </FeatureGate>\n }\n />\n\n {/* Tournaments (esports bracket) */}\n <Route\n path=\"tournaments\"\n element={\n <FeatureGate flag=\"atheletebridge.tournaments.enabled\" defaultValue={true}>\n <TournamentBracketPage />\n </FeatureGate>\n }\n />\n\n {/* Fallback */}\n <Route path=\"*\" element={<Navigate to=\".\" replace />} />\n </Routes>\n </Suspense>\n </div>\n );\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"StatusBadge.d.ts","sourceRoot":"","sources":["../../../src/atheletebridge/components/StatusBadge.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAGhC,KAAK,YAAY,GAAG,SAAS,GAAG,SAAS,GAAG,aAAa,GAAG,WAAW,GAAG,MAAM,GAAG,SAAS,CAAC;AAE7F,UAAU,gBAAgB;IACxB,MAAM,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAwDD,eAAO,MAAM,WAAW,EAAE,EAAE,CAAC,gBAAgB,CA0B5C,CAAC"}
1
+ {"version":3,"file":"StatusBadge.d.ts","sourceRoot":"","sources":["../../../src/atheletebridge/components/StatusBadge.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAGhC,KAAK,YAAY,GAAG,SAAS,GAAG,SAAS,GAAG,aAAa,GAAG,WAAW,GAAG,MAAM,GAAG,SAAS,CAAC;AAE7F,UAAU,gBAAgB;IACxB,MAAM,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA8DD,eAAO,MAAM,WAAW,EAAE,EAAE,CAAC,gBAAgB,CA0B5C,CAAC"}
@@ -33,7 +33,9 @@ var r = {
33
33
  confirmed: "info",
34
34
  no_show: "destructive",
35
35
  planned: "info",
36
- skipped: "secondary"
36
+ skipped: "secondary",
37
+ succeeded: "success",
38
+ failed: "destructive"
37
39
  };
38
40
  function o(e) {
39
41
  return e.replace(/_/g, " ").toLowerCase().replace(/\b\w/g, (e) => e.toUpperCase());
@@ -1 +1 @@
1
- {"version":3,"file":"StatusBadge.js","names":[],"sources":["../../../src/atheletebridge/components/StatusBadge.tsx"],"sourcesContent":["/**\n * Status Badge Component\n * @module atheletebridge/components\n *\n * A colored badge based on a domain status value, with semantic-token color\n * mapping for the AthleteBridge lifecycle states (teams, members, fixtures,\n * programs, sessions, workouts). Uses semantic tokens only — never raw colors.\n */\n\nimport type { FC } from 'react';\nimport { cn } from '../utils/cn';\n\ntype BadgeVariant = 'success' | 'warning' | 'destructive' | 'secondary' | 'info' | 'outline';\n\ninterface StatusBadgeProps {\n status: string;\n /**\n * Force a specific variant, overriding the auto status→color mapping. Useful\n * where the same status string reads differently by context (e.g. a cancelled\n * coaching session shown grey rather than the default destructive red).\n */\n variant?: BadgeVariant;\n className?: string;\n}\n\nconst variantStyles: Record<BadgeVariant, string> = {\n success: 'bg-status-success-bg-subtle text-status-success-text',\n warning: 'bg-status-warning-bg-subtle text-status-warning-text',\n destructive: 'bg-status-error-bg-subtle text-status-error-text',\n secondary: 'bg-bg-sunken text-text-secondary',\n info: 'bg-[var(--color-accent-soft)] text-text-primary',\n outline: 'border border-border-seam text-text-primary',\n};\n\n// Statuses that represent a \"live\" / in-progress condition get a subtle,\n// opacity-only glow pulse (reduced-motion safe via motion-safe:).\nconst liveStatuses = new Set(['live', 'active', 'confirmed', 'in_progress']);\n\nconst statusVariantMap: Record<string, BadgeVariant> = {\n // Team status\n forming: 'warning',\n active: 'success',\n inactive: 'secondary',\n archived: 'secondary',\n\n // Member status\n trial: 'info',\n injured: 'warning',\n suspended: 'destructive',\n released: 'secondary',\n\n // Fixture status\n scheduled: 'info',\n live: 'success',\n completed: 'success',\n postponed: 'warning',\n cancelled: 'destructive',\n\n // Program status\n draft: 'secondary',\n published: 'success',\n\n // Session status\n requested: 'warning',\n confirmed: 'info',\n no_show: 'destructive',\n\n // Workout status\n planned: 'info',\n skipped: 'secondary',\n};\n\nfunction formatStatusLabel(status: string): string {\n return status\n .replace(/_/g, ' ')\n .toLowerCase()\n .replace(/\\b\\w/g, (char) => char.toUpperCase());\n}\n\nexport const StatusBadge: FC<StatusBadgeProps> = ({\n status,\n variant: variantOverride,\n className,\n}) => {\n const key = status.toLowerCase();\n const variant = variantOverride ?? statusVariantMap[key] ?? 'secondary';\n const isLive = liveStatuses.has(key);\n\n return (\n <span\n className={cn(\n 'inline-flex items-center gap-1.5 rounded-full px-2.5 py-0.5 text-xs font-medium',\n variantStyles[variant],\n className\n )}\n >\n {isLive && (\n <span\n aria-hidden=\"true\"\n className=\"size-1.5 rounded-full bg-current motion-safe:animate-vc-glow-pulse\"\n />\n )}\n {formatStatusLabel(status)}\n </span>\n );\n};\n"],"mappings":";;;AAyBA,IAAM,IAA8C;CAClD,SAAS;CACT,SAAS;CACT,aAAa;CACb,WAAW;CACX,MAAM;CACN,SAAS;AACX,GAIM,IAAe,IAAI,IAAI;CAAC;CAAQ;CAAU;CAAa;AAAa,CAAC,GAErE,IAAiD;CAErD,SAAS;CACT,QAAQ;CACR,UAAU;CACV,UAAU;CAGV,OAAO;CACP,SAAS;CACT,WAAW;CACX,UAAU;CAGV,WAAW;CACX,MAAM;CACN,WAAW;CACX,WAAW;CACX,WAAW;CAGX,OAAO;CACP,WAAW;CAGX,WAAW;CACX,WAAW;CACX,SAAS;CAGT,SAAS;CACT,SAAS;AACX;AAEA,SAAS,EAAkB,GAAwB;CACjD,OAAO,EACJ,QAAQ,MAAM,GAAG,EACjB,YAAY,EACZ,QAAQ,UAAU,MAAS,EAAK,YAAY,CAAC;AAClD;AAEA,IAAa,KAAqC,EAChD,WACA,SAAS,GACT,mBACI;CACJ,IAAM,IAAM,EAAO,YAAY,GACzB,IAAU,KAAmB,EAAiB,MAAQ,aACtD,IAAS,EAAa,IAAI,CAAG;CAEnC,OACE,kBAAC,QAAD;EACE,WAAW,EACT,mFACA,EAAc,IACd,CACF;YALF,CAOG,KACC,kBAAC,QAAD;GACE,eAAY;GACZ,WAAU;EACX,CAAA,GAEF,EAAkB,CAAM,CACrB;;AAEV"}
1
+ {"version":3,"file":"StatusBadge.js","names":[],"sources":["../../../src/atheletebridge/components/StatusBadge.tsx"],"sourcesContent":["/**\n * Status Badge Component\n * @module atheletebridge/components\n *\n * A colored badge based on a domain status value, with semantic-token color\n * mapping for the AthleteBridge lifecycle states (teams, members, fixtures,\n * programs, sessions, workouts). Uses semantic tokens only — never raw colors.\n */\n\nimport type { FC } from 'react';\nimport { cn } from '../utils/cn';\n\ntype BadgeVariant = 'success' | 'warning' | 'destructive' | 'secondary' | 'info' | 'outline';\n\ninterface StatusBadgeProps {\n status: string;\n /**\n * Force a specific variant, overriding the auto status→color mapping. Useful\n * where the same status string reads differently by context (e.g. a cancelled\n * coaching session shown grey rather than the default destructive red).\n */\n variant?: BadgeVariant;\n className?: string;\n}\n\nconst variantStyles: Record<BadgeVariant, string> = {\n success: 'bg-status-success-bg-subtle text-status-success-text',\n warning: 'bg-status-warning-bg-subtle text-status-warning-text',\n destructive: 'bg-status-error-bg-subtle text-status-error-text',\n secondary: 'bg-bg-sunken text-text-secondary',\n info: 'bg-[var(--color-accent-soft)] text-text-primary',\n outline: 'border border-border-seam text-text-primary',\n};\n\n// Statuses that represent a \"live\" / in-progress condition get a subtle,\n// opacity-only glow pulse (reduced-motion safe via motion-safe:).\nconst liveStatuses = new Set(['live', 'active', 'confirmed', 'in_progress']);\n\nconst statusVariantMap: Record<string, BadgeVariant> = {\n // Team status\n forming: 'warning',\n active: 'success',\n inactive: 'secondary',\n archived: 'secondary',\n\n // Member status\n trial: 'info',\n injured: 'warning',\n suspended: 'destructive',\n released: 'secondary',\n\n // Fixture status\n scheduled: 'info',\n live: 'success',\n completed: 'success',\n postponed: 'warning',\n cancelled: 'destructive',\n\n // Program status\n draft: 'secondary',\n published: 'success',\n\n // Session status\n requested: 'warning',\n confirmed: 'info',\n no_show: 'destructive',\n\n // Workout status\n planned: 'info',\n skipped: 'secondary',\n\n // AI agent-run status (AthAgentRunStatus). A failed run must never read as a\n // neutral grey chip — an invisible failure is how the last outage stayed\n // unnoticed for months.\n succeeded: 'success',\n failed: 'destructive',\n};\n\nfunction formatStatusLabel(status: string): string {\n return status\n .replace(/_/g, ' ')\n .toLowerCase()\n .replace(/\\b\\w/g, (char) => char.toUpperCase());\n}\n\nexport const StatusBadge: FC<StatusBadgeProps> = ({\n status,\n variant: variantOverride,\n className,\n}) => {\n const key = status.toLowerCase();\n const variant = variantOverride ?? statusVariantMap[key] ?? 'secondary';\n const isLive = liveStatuses.has(key);\n\n return (\n <span\n className={cn(\n 'inline-flex items-center gap-1.5 rounded-full px-2.5 py-0.5 text-xs font-medium',\n variantStyles[variant],\n className\n )}\n >\n {isLive && (\n <span\n aria-hidden=\"true\"\n className=\"size-1.5 rounded-full bg-current motion-safe:animate-vc-glow-pulse\"\n />\n )}\n {formatStatusLabel(status)}\n </span>\n );\n};\n"],"mappings":";;;AAyBA,IAAM,IAA8C;CAClD,SAAS;CACT,SAAS;CACT,aAAa;CACb,WAAW;CACX,MAAM;CACN,SAAS;AACX,GAIM,IAAe,IAAI,IAAI;CAAC;CAAQ;CAAU;CAAa;AAAa,CAAC,GAErE,IAAiD;CAErD,SAAS;CACT,QAAQ;CACR,UAAU;CACV,UAAU;CAGV,OAAO;CACP,SAAS;CACT,WAAW;CACX,UAAU;CAGV,WAAW;CACX,MAAM;CACN,WAAW;CACX,WAAW;CACX,WAAW;CAGX,OAAO;CACP,WAAW;CAGX,WAAW;CACX,WAAW;CACX,SAAS;CAGT,SAAS;CACT,SAAS;CAKT,WAAW;CACX,QAAQ;AACV;AAEA,SAAS,EAAkB,GAAwB;CACjD,OAAO,EACJ,QAAQ,MAAM,GAAG,EACjB,YAAY,EACZ,QAAQ,UAAU,MAAS,EAAK,YAAY,CAAC;AAClD;AAEA,IAAa,KAAqC,EAChD,WACA,SAAS,GACT,mBACI;CACJ,IAAM,IAAM,EAAO,YAAY,GACzB,IAAU,KAAmB,EAAiB,MAAQ,aACtD,IAAS,EAAa,IAAI,CAAG;CAEnC,OACE,kBAAC,QAAD;EACE,WAAW,EACT,mFACA,EAAc,IACd,CACF;YALF,CAOG,KACC,kBAAC,QAAD;GACE,eAAY;GACZ,WAAU;EACX,CAAA,GAEF,EAAkB,CAAM,CACrB;;AAEV"}
@@ -0,0 +1,19 @@
1
+ import { AthAgentRun } from '../../types';
2
+
3
+ interface AgentRunFeedProps {
4
+ runs: AthAgentRun[];
5
+ isLoading: boolean;
6
+ isError: boolean;
7
+ onRetry: () => void;
8
+ page: number;
9
+ hasMore: boolean;
10
+ onPrev: () => void;
11
+ onNext: () => void;
12
+ /** The run whose decision card is currently focused, if any. */
13
+ selectedRunId: string | null;
14
+ onSelect: (runId: string) => void;
15
+ className?: string;
16
+ }
17
+ export declare function AgentRunFeed({ runs, isLoading, isError, onRetry, page, hasMore, onPrev, onNext, selectedRunId, onSelect, className, }: AgentRunFeedProps): import("react").JSX.Element;
18
+ export {};
19
+ //# sourceMappingURL=AgentRunFeed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AgentRunFeed.d.ts","sourceRoot":"","sources":["../../../../src/atheletebridge/components/ai/AgentRunFeed.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AASH,OAAO,KAAK,EAAE,WAAW,EAAsB,MAAM,aAAa,CAAC;AAKnE,UAAU,iBAAiB;IACzB,IAAI,EAAE,WAAW,EAAE,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,gEAAgE;IAChE,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA6BD,wBAAgB,YAAY,CAAC,EAC3B,IAAI,EACJ,SAAS,EACT,OAAO,EACP,OAAO,EACP,IAAI,EACJ,OAAO,EACP,MAAM,EACN,MAAM,EACN,aAAa,EACb,QAAQ,EACR,SAAS,GACV,EAAE,iBAAiB,+BA6GnB"}
@@ -0,0 +1,124 @@
1
+ import { cn as e } from "../../utils/cn.js";
2
+ import { StatusBadge as t } from "../StatusBadge.js";
3
+ import { formatDate as n } from "../../utils/formatters.js";
4
+ import { EmptyState as r } from "../EmptyState.js";
5
+ import { ErrorState as i, LoadingState as a } from "../LoadingState.js";
6
+ import { timeAgo as o } from "../../utils/timeAgo.js";
7
+ import { CursorPager as s } from "../CursorPager.js";
8
+ import { Clock as c, Radio as l, Timer as u, User as d, Zap as f } from "lucide-react";
9
+ import { jsx as p, jsxs as m } from "react/jsx-runtime";
10
+ import { GlassCard as h } from "@burdenoff/fe-libs/ui";
11
+ //#region src/atheletebridge/components/ai/AgentRunFeed.tsx
12
+ var g = {
13
+ MANUAL: d,
14
+ SCHEDULED: c,
15
+ EVENT: f
16
+ }, _ = {
17
+ MANUAL: "Manual",
18
+ SCHEDULED: "Scheduled",
19
+ EVENT: "Event"
20
+ };
21
+ function v(e) {
22
+ return e === null ? "—" : e < 1e3 ? `${e}ms` : `${(e / 1e3).toFixed(1)}s`;
23
+ }
24
+ function y(e) {
25
+ return e.tokensIn === null && e.tokensOut === null ? "—" : `${e.tokensIn ?? 0} in / ${e.tokensOut ?? 0} out`;
26
+ }
27
+ function b({ runs: c, isLoading: d, isError: b, onRetry: x, page: S, hasMore: C, onPrev: w, onNext: T, selectedRunId: E, onSelect: D, className: O }) {
28
+ return d ? /* @__PURE__ */ p(a, {
29
+ className: O,
30
+ label: "Loading the decision ledger…"
31
+ }) : b ? /* @__PURE__ */ p(i, {
32
+ className: O,
33
+ title: "Decision ledger unavailable",
34
+ message: "We could not read this workspace's AI decision ledger. Please try again.",
35
+ onRetry: x
36
+ }) : c.length === 0 ? /* @__PURE__ */ p(r, {
37
+ className: O,
38
+ illustration: "empty-data",
39
+ icon: /* @__PURE__ */ p(l, { className: "h-10 w-10" }),
40
+ title: S > 0 ? "No more decisions on this page" : "No AI decisions recorded yet",
41
+ description: S > 0 ? "Go back a page to see earlier decisions." : "Generate a program or run a performance assessment above — every attempt, successful or not, is appended here.",
42
+ action: S > 0 ? /* @__PURE__ */ p("button", {
43
+ type: "button",
44
+ onClick: w,
45
+ className: "rounded-lg border border-border-seam px-4 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken",
46
+ children: "Previous page"
47
+ }) : void 0
48
+ }) : /* @__PURE__ */ m("div", {
49
+ className: O,
50
+ children: [/* @__PURE__ */ p(h, {
51
+ treatment: "insight",
52
+ className: "overflow-hidden p-0",
53
+ children: /* @__PURE__ */ p("ul", {
54
+ className: "divide-y divide-border-seam",
55
+ children: c.map((r) => {
56
+ let i = g[r.trigger] ?? f, a = r.id === E;
57
+ return /* @__PURE__ */ p("li", { children: /* @__PURE__ */ m("button", {
58
+ type: "button",
59
+ onClick: () => D(r.id),
60
+ "aria-pressed": a,
61
+ className: e("w-full px-5 py-4 text-left transition-colors hover:bg-bg-sunken", "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)]", a && "bg-bg-sunken"),
62
+ children: [
63
+ /* @__PURE__ */ m("span", {
64
+ className: "flex flex-wrap items-center gap-2",
65
+ children: [
66
+ /* @__PURE__ */ p(t, { status: r.status }),
67
+ /* @__PURE__ */ m("span", {
68
+ className: "inline-flex items-center gap-1 rounded-full border border-border-seam px-2 py-0.5 text-xs font-medium text-text-secondary",
69
+ children: [/* @__PURE__ */ p(i, { className: "h-3 w-3" }), _[r.trigger] ?? r.trigger]
70
+ }),
71
+ /* @__PURE__ */ p("span", {
72
+ className: "text-sm font-medium text-text-primary",
73
+ children: r.provider
74
+ }),
75
+ /* @__PURE__ */ p("span", {
76
+ className: "text-sm text-text-secondary",
77
+ children: r.model
78
+ }),
79
+ /* @__PURE__ */ p("span", {
80
+ className: "ml-auto text-xs text-text-muted",
81
+ title: n(r.createdAt),
82
+ children: o(r.createdAt)
83
+ })
84
+ ]
85
+ }),
86
+ /* @__PURE__ */ p("span", {
87
+ className: "mt-1.5 block text-sm text-text-secondary",
88
+ children: r.promptSummary
89
+ }),
90
+ /* @__PURE__ */ m("span", {
91
+ className: "mt-2 flex flex-wrap items-center gap-x-4 gap-y-1 text-xs tabular-nums text-text-muted",
92
+ children: [
93
+ /* @__PURE__ */ m("span", {
94
+ className: "inline-flex items-center gap-1",
95
+ children: [/* @__PURE__ */ p(u, {
96
+ className: "h-3 w-3",
97
+ "aria-hidden": "true"
98
+ }), v(r.latencyMs)]
99
+ }),
100
+ /* @__PURE__ */ m("span", { children: [y(r), " tokens"] }),
101
+ r.costUsd !== null && /* @__PURE__ */ m("span", { children: ["$", r.costUsd.toFixed(4)] })
102
+ ]
103
+ }),
104
+ r.status === "FAILED" && r.error && /* @__PURE__ */ p("span", {
105
+ className: "mt-2 block whitespace-pre-wrap break-words rounded-lg border border-status-error-border bg-status-error-bg-subtle px-3 py-2 font-mono text-xs leading-relaxed text-status-error-text",
106
+ children: r.error
107
+ })
108
+ ]
109
+ }) }, r.id);
110
+ })
111
+ })
112
+ }), /* @__PURE__ */ p(s, {
113
+ className: "mt-4",
114
+ page: S,
115
+ hasMore: C,
116
+ onPrev: w,
117
+ onNext: T
118
+ })]
119
+ });
120
+ }
121
+ //#endregion
122
+ export { b as AgentRunFeed };
123
+
124
+ //# sourceMappingURL=AgentRunFeed.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AgentRunFeed.js","names":[],"sources":["../../../../src/atheletebridge/components/ai/AgentRunFeed.tsx"],"sourcesContent":["/**\n * Agent activity feed\n * @module atheletebridge/components/ai\n *\n * The workspace's append-only AI decision ledger (`athAgentRuns`), newest\n * first, offset-paginated.\n *\n * FAILED runs are shown with the same weight as successful ones and their\n * `error` text is rendered inline, never behind a disclosure or filtered out. A\n * feed that only shows successes is how the last provider outage stayed\n * invisible for months.\n */\n\nimport type { FC } from 'react';\nimport { Clock, Radio, Timer, User, Zap } from 'lucide-react';\nimport { GlassCard } from '@burdenoff/fe-libs/ui';\nimport { CursorPager } from '../CursorPager';\nimport { EmptyState } from '../EmptyState';\nimport { LoadingState, ErrorState } from '../LoadingState';\nimport { StatusBadge } from '../StatusBadge';\nimport type { AthAgentRun, AthAgentRunTrigger } from '../../types';\nimport { cn } from '../../utils/cn';\nimport { formatDate } from '../../utils/formatters';\nimport { timeAgo } from '../../utils/timeAgo';\n\ninterface AgentRunFeedProps {\n runs: AthAgentRun[];\n isLoading: boolean;\n isError: boolean;\n onRetry: () => void;\n page: number;\n hasMore: boolean;\n onPrev: () => void;\n onNext: () => void;\n /** The run whose decision card is currently focused, if any. */\n selectedRunId: string | null;\n onSelect: (runId: string) => void;\n className?: string;\n}\n\nconst TRIGGER_ICON: Record<AthAgentRunTrigger, FC<{ className?: string }>> = {\n MANUAL: User,\n SCHEDULED: Clock,\n EVENT: Zap,\n};\n\nconst TRIGGER_LABEL: Record<AthAgentRunTrigger, string> = {\n MANUAL: 'Manual',\n SCHEDULED: 'Scheduled',\n EVENT: 'Event',\n};\n\n/** `1234` → `1.2s`; small values stay in ms so a fast run does not read as 0s. */\nfunction formatLatency(latencyMs: number | null): string {\n if (latencyMs === null) {\n return '—';\n }\n return latencyMs < 1000 ? `${latencyMs}ms` : `${(latencyMs / 1000).toFixed(1)}s`;\n}\n\nfunction formatTokens(run: AthAgentRun): string {\n if (run.tokensIn === null && run.tokensOut === null) {\n return '—';\n }\n return `${run.tokensIn ?? 0} in / ${run.tokensOut ?? 0} out`;\n}\n\nexport function AgentRunFeed({\n runs,\n isLoading,\n isError,\n onRetry,\n page,\n hasMore,\n onPrev,\n onNext,\n selectedRunId,\n onSelect,\n className,\n}: AgentRunFeedProps) {\n if (isLoading) {\n return <LoadingState className={className} label=\"Loading the decision ledger…\" />;\n }\n\n if (isError) {\n return (\n <ErrorState\n className={className}\n title=\"Decision ledger unavailable\"\n message=\"We could not read this workspace's AI decision ledger. Please try again.\"\n onRetry={onRetry}\n />\n );\n }\n\n if (runs.length === 0) {\n return (\n <EmptyState\n className={className}\n illustration=\"empty-data\"\n icon={<Radio className=\"h-10 w-10\" />}\n title={page > 0 ? 'No more decisions on this page' : 'No AI decisions recorded yet'}\n description={\n page > 0\n ? 'Go back a page to see earlier decisions.'\n : 'Generate a program or run a performance assessment above — every attempt, successful or not, is appended here.'\n }\n action={\n page > 0 ? (\n <button\n type=\"button\"\n onClick={onPrev}\n className=\"rounded-lg border border-border-seam px-4 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken\"\n >\n Previous page\n </button>\n ) : undefined\n }\n />\n );\n }\n\n return (\n <div className={className}>\n <GlassCard treatment=\"insight\" className=\"overflow-hidden p-0\">\n <ul className=\"divide-y divide-border-seam\">\n {runs.map((run) => {\n const TriggerIcon = TRIGGER_ICON[run.trigger] ?? Zap;\n const isSelected = run.id === selectedRunId;\n return (\n <li key={run.id}>\n <button\n type=\"button\"\n onClick={() => onSelect(run.id)}\n aria-pressed={isSelected}\n className={cn(\n 'w-full px-5 py-4 text-left transition-colors hover:bg-bg-sunken',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)]',\n isSelected && 'bg-bg-sunken'\n )}\n >\n {/*\n Phrasing content only inside the button: a <p>/<div> here is\n invalid nesting and React warns about it at runtime.\n */}\n <span className=\"flex flex-wrap items-center gap-2\">\n <StatusBadge status={run.status} />\n <span className=\"inline-flex items-center gap-1 rounded-full border border-border-seam px-2 py-0.5 text-xs font-medium text-text-secondary\">\n <TriggerIcon className=\"h-3 w-3\" />\n {TRIGGER_LABEL[run.trigger] ?? run.trigger}\n </span>\n <span className=\"text-sm font-medium text-text-primary\">{run.provider}</span>\n <span className=\"text-sm text-text-secondary\">{run.model}</span>\n <span\n className=\"ml-auto text-xs text-text-muted\"\n title={formatDate(run.createdAt)}\n >\n {timeAgo(run.createdAt)}\n </span>\n </span>\n\n <span className=\"mt-1.5 block text-sm text-text-secondary\">\n {run.promptSummary}\n </span>\n\n <span className=\"mt-2 flex flex-wrap items-center gap-x-4 gap-y-1 text-xs tabular-nums text-text-muted\">\n <span className=\"inline-flex items-center gap-1\">\n <Timer className=\"h-3 w-3\" aria-hidden=\"true\" />\n {formatLatency(run.latencyMs)}\n </span>\n <span>{formatTokens(run)} tokens</span>\n {run.costUsd !== null && <span>${run.costUsd.toFixed(4)}</span>}\n </span>\n\n {run.status === 'FAILED' && run.error && (\n <span className=\"mt-2 block whitespace-pre-wrap break-words rounded-lg border border-status-error-border bg-status-error-bg-subtle px-3 py-2 font-mono text-xs leading-relaxed text-status-error-text\">\n {run.error}\n </span>\n )}\n </button>\n </li>\n );\n })}\n </ul>\n </GlassCard>\n <CursorPager className=\"mt-4\" page={page} hasMore={hasMore} onPrev={onPrev} onNext={onNext} />\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;AAwCA,IAAM,IAAuE;CAC3E,QAAQ;CACR,WAAW;CACX,OAAO;AACT,GAEM,IAAoD;CACxD,QAAQ;CACR,WAAW;CACX,OAAO;AACT;AAGA,SAAS,EAAc,GAAkC;CAIvD,OAHI,MAAc,OACT,MAEF,IAAY,MAAO,GAAG,EAAU,MAAM,IAAI,IAAY,KAAM,QAAQ,CAAC,EAAE;AAChF;AAEA,SAAS,EAAa,GAA0B;CAI9C,OAHI,EAAI,aAAa,QAAQ,EAAI,cAAc,OACtC,MAEF,GAAG,EAAI,YAAY,EAAE,QAAQ,EAAI,aAAa,EAAE;AACzD;AAEA,SAAgB,EAAa,EAC3B,SACA,cACA,YACA,YACA,SACA,YACA,WACA,WACA,kBACA,aACA,gBACoB;CA2CpB,OA1CI,IACK,kBAAC,GAAD;EAAyB;EAAW,OAAM;CAAgC,CAAA,IAG/E,IAEA,kBAAC,GAAD;EACa;EACX,OAAM;EACN,SAAQ;EACC;CACV,CAAA,IAID,EAAK,WAAW,IAEhB,kBAAC,GAAD;EACa;EACX,cAAa;EACb,MAAM,kBAAC,GAAD,EAAO,WAAU,YAAa,CAAA;EACpC,OAAO,IAAO,IAAI,mCAAmC;EACrD,aACE,IAAO,IACH,6CACA;EAEN,QACE,IAAO,IACL,kBAAC,UAAD;GACE,MAAK;GACL,SAAS;GACT,WAAU;aACX;EAEO,CAAA,IACN,KAAA;CAEP,CAAA,IAKH,kBAAC,OAAD;EAAgB;YAAhB,CACE,kBAAC,GAAD;GAAW,WAAU;GAAU,WAAU;aACvC,kBAAC,MAAD;IAAI,WAAU;cACX,EAAK,KAAK,MAAQ;KACjB,IAAM,IAAc,EAAa,EAAI,YAAY,GAC3C,IAAa,EAAI,OAAO;KAC9B,OACE,kBAAC,MAAD,EAAA,UACE,kBAAC,UAAD;MACE,MAAK;MACL,eAAe,EAAS,EAAI,EAAE;MAC9B,gBAAc;MACd,WAAW,EACT,mEACA,gGACA,KAAc,cAChB;gBARF;OAcE,kBAAC,QAAD;QAAM,WAAU;kBAAhB;SACE,kBAAC,GAAD,EAAa,QAAQ,EAAI,OAAS,CAAA;SAClC,kBAAC,QAAD;UAAM,WAAU;oBAAhB,CACE,kBAAC,GAAD,EAAa,WAAU,UAAW,CAAA,GACjC,EAAc,EAAI,YAAY,EAAI,OAC/B;;SACN,kBAAC,QAAD;UAAM,WAAU;oBAAyC,EAAI;SAAe,CAAA;SAC5E,kBAAC,QAAD;UAAM,WAAU;oBAA+B,EAAI;SAAY,CAAA;SAC/D,kBAAC,QAAD;UACE,WAAU;UACV,OAAO,EAAW,EAAI,SAAS;oBAE9B,EAAQ,EAAI,SAAS;SAClB,CAAA;QACF;;OAEN,kBAAC,QAAD;QAAM,WAAU;kBACb,EAAI;OACD,CAAA;OAEN,kBAAC,QAAD;QAAM,WAAU;kBAAhB;SACE,kBAAC,QAAD;UAAM,WAAU;oBAAhB,CACE,kBAAC,GAAD;WAAO,WAAU;WAAU,eAAY;UAAQ,CAAA,GAC9C,EAAc,EAAI,SAAS,CACxB;;SACN,kBAAC,QAAD,EAAA,UAAA,CAAO,EAAa,CAAG,GAAE,SAAa,EAAA,CAAA;SACrC,EAAI,YAAY,QAAQ,kBAAC,QAAD,EAAA,UAAA,CAAM,KAAE,EAAI,QAAQ,QAAQ,CAAC,CAAQ,EAAA,CAAA;QAC1D;;OAEL,EAAI,WAAW,YAAY,EAAI,SAC9B,kBAAC,QAAD;QAAM,WAAU;kBACb,EAAI;OACD,CAAA;MAEF;QACN,GAlDK,EAAI,EAkDT;IAER,CAAC;GACC,CAAA;EACK,CAAA,GACX,kBAAC,GAAD;GAAa,WAAU;GAAa;GAAe;GAAiB;GAAgB;EAAS,CAAA,CAC1F;;AAET"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * AI error notice
3
+ * @module atheletebridge/components/ai
4
+ *
5
+ * Renders a failed AI action honestly (BOFF-3574).
6
+ *
7
+ * The svc answers an unconfigured/unreachable provider with
8
+ * `AI_PROVIDER_UNAVAILABLE` and an `extensions.agentRunId` pointing at the
9
+ * FAILED ledger row that holds every attempt's raw upstream message. Collapsing
10
+ * that into a generic "something went wrong" toast is what made an outage
11
+ * indistinguishable from a crashed service, so the code, the message and the
12
+ * ledger row are all shown — and the row itself can be opened inline.
13
+ */
14
+ interface AiErrorNoticeProps {
15
+ /** Anything thrown by a mutation; non-errors render nothing. */
16
+ error: unknown;
17
+ className?: string;
18
+ }
19
+ export declare function AiErrorNotice({ error, className }: AiErrorNoticeProps): import("react").JSX.Element | null;
20
+ export {};
21
+ //# sourceMappingURL=AiErrorNotice.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AiErrorNotice.d.ts","sourceRoot":"","sources":["../../../../src/atheletebridge/components/ai/AiErrorNotice.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAQH,UAAU,kBAAkB;IAC1B,gEAAgE;IAChE,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA4DD,wBAAgB,aAAa,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,kBAAkB,sCAkDrE"}