loki-mode 9.53.0 → 9.54.2

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 (119) hide show
  1. package/SKILL.md +2 -2
  2. package/VERSION +1 -1
  3. package/autonomy/completion-council.sh +28 -5
  4. package/autonomy/council-v2.sh +13 -7
  5. package/autonomy/lib/done-recognition.sh +24 -16
  6. package/autonomy/lib/proof-check.sh +11 -3
  7. package/autonomy/lib/proof-generator.py +36 -5
  8. package/autonomy/lib/voter-agents.sh +8 -3
  9. package/autonomy/lib/workspace_diff.py +106 -12
  10. package/autonomy/prd-checklist.sh +19 -11
  11. package/autonomy/run.sh +503 -52
  12. package/dashboard/__init__.py +1 -1
  13. package/dashboard/api_v2.py +4 -0
  14. package/dashboard/audit.py +9 -1
  15. package/dashboard/auth.py +16 -4
  16. package/dashboard/registry.py +34 -12
  17. package/dashboard/rigour_integration.py +25 -17
  18. package/dashboard/server.py +252 -104
  19. package/dashboard/static/cost.html +55 -26
  20. package/dashboard/static/index.html +475 -1544
  21. package/dashboard/static/proofs.html +1 -1
  22. package/docs/INSTALLATION.md +1 -1
  23. package/docs/air-gapped.md +7 -2
  24. package/docs/image-provenance.md +4 -2
  25. package/docs/v10/BACKLOG.md +82 -2
  26. package/docs/v10/BOARD.md +105 -0
  27. package/docs/v10/DECISIONS.md +71 -0
  28. package/docs/v10/METRICS.md +2 -1
  29. package/docs/v10/PROGRESS.md +60 -0
  30. package/docs/v10/SWARM-PROMPT.md +98 -0
  31. package/docs/v10/SWARM.md +237 -0
  32. package/loki-ts/dist/loki.js +323 -322
  33. package/mcp/__init__.py +1 -1
  34. package/package.json +1 -1
  35. package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
  36. package/providers/aider.sh +8 -0
  37. package/providers/cline.sh +8 -0
  38. package/providers/codex.sh +9 -0
  39. package/providers/opencode.sh +9 -0
  40. package/web-app/dist/assets/AdminPage-CZrBkzRF.js +32 -0
  41. package/web-app/dist/assets/Avatar-gQIp6FBI.js +11 -0
  42. package/web-app/dist/assets/{Badge-BF3mhT57.js → Badge-D2_fBTFY.js} +1 -1
  43. package/web-app/dist/assets/{Button-BDp9aJ9q.js → Button-D5qDd2ef.js} +1 -1
  44. package/web-app/dist/assets/CockpitPage-DVMk2RUK.js +47 -0
  45. package/web-app/dist/assets/ComparePage-NMLyE1xL.js +1 -0
  46. package/web-app/dist/assets/{ErrorBoundary-ut3wrUmu.js → ErrorBoundary-BRABI-BT.js} +1 -1
  47. package/web-app/dist/assets/EvidenceReceiptPanel-D2LNKqUx.js +1 -0
  48. package/web-app/dist/assets/GitHubIssuesPanel-BC5GzKUN.js +7 -0
  49. package/web-app/dist/assets/{GitHubPRsPanel-DurZgSaj.js → GitHubPRsPanel-BSlmoVTS.js} +3 -3
  50. package/web-app/dist/assets/HomePage-D_CDMoen.js +12 -0
  51. package/web-app/dist/assets/{LoginPage-HeRGJeZy.js → LoginPage-BBNA_N9t.js} +1 -1
  52. package/web-app/dist/assets/{MagicPage-CUKrqsZs.js → MagicPage-CnFRZCMx.js} +1 -1
  53. package/web-app/dist/assets/MetricsPage-CPfLMRlh.js +6 -0
  54. package/web-app/dist/assets/{NotFoundPage-BZDZ-B77.js → NotFoundPage-lA0XSGTz.js} +1 -1
  55. package/web-app/dist/assets/ProjectPage-CNAPbr9z.js +256 -0
  56. package/web-app/dist/assets/ProjectsPage-CMtm8goN.js +6 -0
  57. package/web-app/dist/assets/SettingsPage-BhIjVMYE.js +10 -0
  58. package/web-app/dist/assets/{ShowcasePage-BGS2jTGH.js → ShowcasePage-BndtGeYo.js} +1 -1
  59. package/web-app/dist/assets/SystemSettingsPage-euXI-KXE.js +1 -0
  60. package/web-app/dist/assets/TeamsPage-ClUKecun.js +11 -0
  61. package/web-app/dist/assets/TemplatesPage-BWHWVk0L.js +29 -0
  62. package/web-app/dist/assets/{TerminalOutput-togzv9Zl.js → TerminalOutput-Cv3N3Szf.js} +1 -1
  63. package/web-app/dist/assets/{activity-Dreyb_Kr.js → activity-dEhz-bXR.js} +1 -1
  64. package/web-app/dist/assets/{bell-DWH0drES.js → bell-B3XUMq1t.js} +1 -1
  65. package/web-app/dist/assets/{bot-78MoCuDl.js → bot-X-ssNlwR.js} +1 -1
  66. package/web-app/dist/assets/{check-ikfylPst.js → check-C_9Nx7kb.js} +1 -1
  67. package/web-app/dist/assets/{chevron-left-DXUqkd8J.js → chevron-left-tvNswo3A.js} +1 -1
  68. package/web-app/dist/assets/{circle-alert-Da74VO8P.js → circle-alert-CSB88nEs.js} +1 -1
  69. package/web-app/dist/assets/{clock-mlGCFq8l.js → clock-C8p2e4NI.js} +1 -1
  70. package/web-app/dist/assets/{cloud-B_Y5ZrIO.js → cloud-CKp2ZvhG.js} +1 -1
  71. package/web-app/dist/assets/{code-xml-Bbom7YWV.js → code-xml-dY70LCHD.js} +1 -1
  72. package/web-app/dist/assets/{database-CLcofiVp.js → database-DObn5fmn.js} +1 -1
  73. package/web-app/dist/assets/{dollar-sign-C5mkjXIM.js → dollar-sign-DSu6n3K3.js} +1 -1
  74. package/web-app/dist/assets/{file-code-corner-CVrkaOQP.js → file-code-corner-DpCnS73z.js} +1 -1
  75. package/web-app/dist/assets/{file-plus-BV9240gX.js → file-plus-D3IPKCf1.js} +1 -1
  76. package/web-app/dist/assets/{globe-aZ0Zso4I.js → globe-C9QXkgH_.js} +1 -1
  77. package/web-app/dist/assets/{hammer-EgOQNukG.js → hammer-D_FtWe1y.js} +1 -1
  78. package/web-app/dist/assets/index-CI54rara.css +1 -0
  79. package/web-app/dist/assets/{index-DvZ0Kk2x.js → index-Cz7q1bvC.js} +2 -2
  80. package/web-app/dist/assets/{layers-BOVKmepE.js → layers-DsW7jnJX.js} +1 -1
  81. package/web-app/dist/assets/{loader-circle-0K8yLgHl.js → loader-circle-B3HspjKR.js} +1 -1
  82. package/web-app/dist/assets/{lock-XzlDMy8M.js → lock-DSI29pct.js} +1 -1
  83. package/web-app/dist/assets/{package-BtXTKusI.js → package-CLNxtA2x.js} +1 -1
  84. package/web-app/dist/assets/{plus-PxeiD8ju.js → plus-DyI4WC4_.js} +1 -1
  85. package/web-app/dist/assets/{refresh-cw-CjqzYczt.js → refresh-cw-D2dv0xA0.js} +1 -1
  86. package/web-app/dist/assets/{rotate-ccw-CY0os4DH.js → rotate-ccw-CBvihA-a.js} +1 -1
  87. package/web-app/dist/assets/scroll-text-DvoOvAl_.js +6 -0
  88. package/web-app/dist/assets/{server-pIIs9vNp.js → server-DenWvSUt.js} +1 -1
  89. package/web-app/dist/assets/{shield-alert-CsDqKXwA.js → shield-alert-40cX_FvG.js} +1 -1
  90. package/web-app/dist/assets/{thumbs-up-CAh3HVzH.js → thumbs-up-BrjZ6QuV.js} +12 -7
  91. package/web-app/dist/assets/trash-2-C6evwkEH.js +16 -0
  92. package/web-app/dist/assets/{trending-down-DrtBd_C9.js → trending-down-CfbZis3O.js} +1 -1
  93. package/web-app/dist/assets/{trending-up-D-DbCHXm.js → trending-up-DWuEK3WC.js} +1 -1
  94. package/web-app/dist/assets/{upload-D4l6DCOt.js → upload-B9DFBcPG.js} +1 -1
  95. package/web-app/dist/assets/{usePolling-D0aoTX80.js → usePolling-BryVC-T1.js} +1 -1
  96. package/web-app/dist/assets/{user-BQf_XJO_.js → user-DMRXwZiw.js} +1 -1
  97. package/web-app/dist/index.html +2 -2
  98. package/web-app/server.py +122 -47
  99. package/web-app/dist/assets/AdminPage-y6_b2Xo4.js +0 -32
  100. package/web-app/dist/assets/Avatar-BFPkXhIJ.js +0 -6
  101. package/web-app/dist/assets/CockpitPage-5TKICCoA.js +0 -47
  102. package/web-app/dist/assets/ComparePage-BSuNsUHy.js +0 -1
  103. package/web-app/dist/assets/EvidenceReceiptPanel-CcaBwEI-.js +0 -1
  104. package/web-app/dist/assets/GitHubIssuesPanel-DJeYgzAa.js +0 -12
  105. package/web-app/dist/assets/HomePage-Bs451LAy.js +0 -28
  106. package/web-app/dist/assets/MetricsPage-DvY1csgz.js +0 -6
  107. package/web-app/dist/assets/ProjectPage-CqHkEZkl.js +0 -257
  108. package/web-app/dist/assets/ProjectsPage-CLvCK1Y8.js +0 -6
  109. package/web-app/dist/assets/SettingsPage-DP7OmdwP.js +0 -10
  110. package/web-app/dist/assets/SystemSettingsPage-P_rlLh0x.js +0 -1
  111. package/web-app/dist/assets/TeamsPage-DxtBDcBC.js +0 -11
  112. package/web-app/dist/assets/TemplatesPage-5e-faH3W.js +0 -29
  113. package/web-app/dist/assets/folder-open-D_6yV78G.js +0 -11
  114. package/web-app/dist/assets/index-BSgmPwC0.css +0 -1
  115. package/web-app/dist/assets/lightbulb-DdASgqOG.js +0 -6
  116. package/web-app/dist/assets/mail-COu670_W.js +0 -6
  117. package/web-app/dist/assets/minus-bQpUt9ff.js +0 -6
  118. package/web-app/dist/assets/save-v8qep5cY.js +0 -6
  119. package/web-app/dist/assets/trash-2-Dt6urTyY.js +0 -6
package/mcp/__init__.py CHANGED
@@ -75,4 +75,4 @@ try:
75
75
  except ImportError:
76
76
  __all__ = ['mcp']
77
77
 
78
- __version__ = '9.53.0'
78
+ __version__ = '9.54.2'
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "loki-mode",
3
3
  "mcpName": "io.github.asklokesh/loki-mode",
4
- "version": "9.53.0",
4
+ "version": "9.54.2",
5
5
  "description": "Loki Mode by Autonomi. Autonomous spec-to-product system: takes a PRD, GitHub issue, OpenAPI/JSON/YAML, or one-line brief to a deployed app via the RARV-C closure loop with 8 quality gates. Provider-agnostic (Claude Code, OpenAI Codex, Cline, Aider, opencode).",
6
6
  "keywords": [
7
7
  "agent",
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
3
3
  "name": "loki-mode",
4
4
  "displayName": "Loki Mode",
5
- "version": "9.53.0",
5
+ "version": "9.54.2",
6
6
  "description": "Autonomous spec-to-product build system with a built-in trust layer (RARV-C closure loop, 8 quality gates, completion council). Ships Loki's spec-hardening, drift-detection, and deterministic PR verification commands plus the Loki MCP server.",
7
7
  "author": {
8
8
  "name": "Autonomi",
@@ -109,6 +109,12 @@ provider_version() {
109
109
  aider --version 2>/dev/null | head -1
110
110
  }
111
111
 
112
+ # Commit hygiene, the sentence providers/claude.sh (and the Bun
113
+ # AUTONOMY_OVERRIDE_TEXT) puts in Claude's system prompt. Aider takes no
114
+ # system prompt here, so it leads every prompt the functions below send
115
+ # (BACKLOG 74: an agent's own `git add -A` commits the user's files).
116
+ PROVIDER_COMMIT_HYGIENE='Commit hygiene still applies: git checkpoints are LOCAL only. Never push or force-push. Stage files by explicit path, never `git add -A` or `git add .`, and never commit secrets, credentials, .env files, or untracked files you did not author this session.'
117
+
112
118
  # Invocation function
113
119
  # --message: single instruction mode (process and exit)
114
120
  # --yes-always: auto-approve all prompts
@@ -116,6 +122,7 @@ provider_version() {
116
122
  provider_invoke() {
117
123
  local prompt="$1"
118
124
  shift
125
+ prompt="$PROVIDER_COMMIT_HYGIENE"$'\n\n'"$prompt"
119
126
  local model="$AIDER_DEFAULT_MODEL"
120
127
  local extra_flags="${LOKI_AIDER_FLAGS:-}"
121
128
  # shellcheck disable=SC2086
@@ -150,6 +157,7 @@ resolve_model_for_tier() {
150
157
  provider_invoke_argv() {
151
158
  local tier="${1:-development}"
152
159
  local prompt="${2:-}"
160
+ prompt="$PROVIDER_COMMIT_HYGIENE"$'\n\n'"$prompt"
153
161
  local model
154
162
  model="$(provider_get_tier_param "$tier" 2>/dev/null || printf '%s' "")"
155
163
  _LOKI_INVOKE_ARGV=(aider --yes-always --no-auto-commits)
@@ -107,6 +107,12 @@ provider_version() {
107
107
  cline --version 2>/dev/null | head -1
108
108
  }
109
109
 
110
+ # Commit hygiene, the sentence providers/claude.sh (and the Bun
111
+ # AUTONOMY_OVERRIDE_TEXT) puts in Claude's system prompt. Cline takes no
112
+ # system prompt here, so it leads every prompt the functions below send
113
+ # (BACKLOG 74: an agent's own `git add -A` commits the user's files).
114
+ PROVIDER_COMMIT_HYGIENE='Commit hygiene still applies: git checkpoints are LOCAL only. Never push or force-push. Stage files by explicit path, never `git add -A` or `git add .`, and never commit secrets, credentials, .env files, or untracked files you did not author this session.'
115
+
110
116
  # Invocation function
111
117
  # Uses -y (YOLO) for autonomous mode, positional prompt
112
118
  # BUG-PROV-009 fix: build model flag as array to prevent word-splitting on model
@@ -114,6 +120,7 @@ provider_version() {
114
120
  provider_invoke() {
115
121
  local prompt="$1"
116
122
  shift
123
+ prompt="$PROVIDER_COMMIT_HYGIENE"$'\n\n'"$prompt"
117
124
  local model="${LOKI_CLINE_MODEL:-}"
118
125
  local model_args=()
119
126
  [[ -n "$model" ]] && model_args=("-m" "$model")
@@ -148,6 +155,7 @@ resolve_model_for_tier() {
148
155
  provider_invoke_argv() {
149
156
  local tier="${1:-development}"
150
157
  local prompt="${2:-}"
158
+ prompt="$PROVIDER_COMMIT_HYGIENE"$'\n\n'"$prompt"
151
159
  local model
152
160
  model="$(provider_get_tier_param "$tier" 2>/dev/null || printf '%s' "")"
153
161
  _LOKI_INVOKE_ARGV=(cline -y)
@@ -209,9 +209,16 @@ _codex_model_flag() {
209
209
  return 0
210
210
  }
211
211
 
212
+ # Commit hygiene, the sentence providers/claude.sh (and the Bun
213
+ # AUTONOMY_OVERRIDE_TEXT) puts in Claude's system prompt. Codex takes no
214
+ # system prompt here, so it leads every prompt the functions below send
215
+ # (BACKLOG 74: an agent's own `git add -A` commits the user's files).
216
+ PROVIDER_COMMIT_HYGIENE='Commit hygiene still applies: git checkpoints are LOCAL only. Never push or force-push. Stage files by explicit path, never `git add -A` or `git add .`, and never commit secrets, credentials, .env files, or untracked files you did not author this session.'
217
+
212
218
  provider_invoke() {
213
219
  local prompt="$1"
214
220
  shift
221
+ prompt="$PROVIDER_COMMIT_HYGIENE"$'\n\n'"$prompt"
215
222
  local model_flag=()
216
223
  while IFS= read -r _mf; do
217
224
  [ -n "$_mf" ] && model_flag+=("$_mf")
@@ -302,6 +309,7 @@ provider_invoke_with_tier() {
302
309
  local tier="$1"
303
310
  local prompt="$2"
304
311
  shift 2
312
+ prompt="$PROVIDER_COMMIT_HYGIENE"$'\n\n'"$prompt"
305
313
  local effort
306
314
  effort=$(resolve_model_for_tier "$tier")
307
315
 
@@ -360,6 +368,7 @@ provider_invoke_with_tier() {
360
368
  provider_invoke_argv() {
361
369
  local tier="${1:-development}"
362
370
  local prompt="${2:-}"
371
+ prompt="$PROVIDER_COMMIT_HYGIENE"$'\n\n'"$prompt"
363
372
 
364
373
  # DO NOT pass provider_get_tier_param to --model. For Codex that function
365
374
  # returns an EFFORT LEVEL (xhigh/high/low), not a model name -- the note at
@@ -117,6 +117,12 @@ provider_get_tier_param() {
117
117
  esac
118
118
  }
119
119
 
120
+ # Commit hygiene, the sentence providers/claude.sh (and the Bun
121
+ # AUTONOMY_OVERRIDE_TEXT) puts in Claude's system prompt. opencode takes no
122
+ # system prompt here, so it leads every prompt the functions below send
123
+ # (BACKLOG 74: an agent's own `git add -A` commits the user's files).
124
+ PROVIDER_COMMIT_HYGIENE='Commit hygiene still applies: git checkpoints are LOCAL only. Never push or force-push. Stage files by explicit path, never `git add -A` or `git add .`, and never commit secrets, credentials, .env files, or untracked files you did not author this session.'
125
+
120
126
  # provider_invoke <prompt> -- run one non-interactive turn.
121
127
  provider_invoke() {
122
128
  # CONTRACT: prompt is $1, and EXTRA ARGS MUST PASS THROUGH. The first cut of
@@ -130,6 +136,7 @@ provider_invoke() {
130
136
  local prompt="$1"
131
137
  shift
132
138
  [ -n "$prompt" ] || return 1
139
+ prompt="$PROVIDER_COMMIT_HYGIENE"$'\n\n'"$prompt"
133
140
  command -v opencode >/dev/null 2>&1 || return 127
134
141
  opencode run --auto --model "$PROVIDER_MODEL_DEVELOPMENT" "$prompt" "$@"
135
142
  }
@@ -143,6 +150,7 @@ provider_invoke_with_tier() {
143
150
  shift 2
144
151
  [ -n "$tier" ] || tier="development"
145
152
  [ -n "$prompt" ] || return 1
153
+ prompt="$PROVIDER_COMMIT_HYGIENE"$'\n\n'"$prompt"
146
154
  command -v opencode >/dev/null 2>&1 || return 127
147
155
  local model
148
156
  model="$(provider_get_tier_param "$tier")"
@@ -153,6 +161,7 @@ provider_invoke_with_tier() {
153
161
  provider_invoke_argv() {
154
162
  local tier="${1:-development}"
155
163
  local prompt="${2:-}"
164
+ prompt="$PROVIDER_COMMIT_HYGIENE"$'\n\n'"$prompt"
156
165
  local model
157
166
  model="$(provider_get_tier_param "$tier")"
158
167
  _LOKI_INVOKE_ARGV=(opencode run --auto --model "$model" "$prompt")
@@ -0,0 +1,32 @@
1
+ import{c as L,r as x,j as e,w as re,Z as ne,m as le,h as ie,p as P,F as ye,U as I,X as ce,L as de,x as oe,M as Ae,T as Z,S as we,l as xe,k as me,y as Ce,E as Fe,a0 as Se,a as U,a2 as he}from"./index-Cz7q1bvC.js";import{B as C}from"./Button-D5qDd2ef.js";import{T as $e}from"./trending-up-DWuEK3WC.js";import{C as z}from"./clock-C8p2e4NI.js";import{A as Be,U as ue,M as De}from"./Avatar-gQIp6FBI.js";import{A as J}from"./activity-dEhz-bXR.js";import{R as pe}from"./refresh-cw-D2dv0xA0.js";import{G as ze}from"./globe-C9QXkgH_.js";import{C as Le}from"./chevron-left-tvNswo3A.js";import{C as je}from"./check-C_9Nx7kb.js";import{D as Y}from"./dollar-sign-DSu6n3K3.js";import{U as Te}from"./user-DMRXwZiw.js";import{D as Me}from"./database-DObn5fmn.js";import{L as Ue}from"./lock-DSI29pct.js";import{S as Re}from"./scroll-text-DvoOvAl_.js";import{S as Ie}from"./shield-alert-40cX_FvG.js";/**
2
+ * @license lucide-react v0.577.0 - ISC
3
+ *
4
+ * This source code is licensed under the ISC license.
5
+ * See the LICENSE file in the root directory of this source tree.
6
+ */const Oe=[["path",{d:"M16 20V4a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16",key:"jecpp"}],["rect",{width:"20",height:"14",x:"2",y:"6",rx:"2",key:"i6l2r4"}]],_e=L("briefcase",Oe);/**
7
+ * @license lucide-react v0.577.0 - ISC
8
+ *
9
+ * This source code is licensed under the ISC license.
10
+ * See the LICENSE file in the root directory of this source tree.
11
+ */const Pe=[["path",{d:"M21 12c.552 0 1.005-.449.95-.998a10 10 0 0 0-8.953-8.951c-.55-.055-.998.398-.998.95v8a1 1 0 0 0 1 1z",key:"pzmjnu"}],["path",{d:"M21.21 15.89A10 10 0 1 1 8 2.83",key:"k2fpak"}]],Ge=L("chart-pie",Pe);/**
12
+ * @license lucide-react v0.577.0 - ISC
13
+ *
14
+ * This source code is licensed under the ISC license.
15
+ * See the LICENSE file in the root directory of this source tree.
16
+ */const He=[["path",{d:"M12 15V3",key:"m9g1x1"}],["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}],["path",{d:"m7 10 5 5 5-5",key:"brsn70"}]],K=L("download",He);/**
17
+ * @license lucide-react v0.577.0 - ISC
18
+ *
19
+ * This source code is licensed under the ISC license.
20
+ * See the LICENSE file in the root directory of this source tree.
21
+ */const Ve=[["path",{d:"M10 20a1 1 0 0 0 .553.895l2 1A1 1 0 0 0 14 21v-7a2 2 0 0 1 .517-1.341L21.74 4.67A1 1 0 0 0 21 3H3a1 1 0 0 0-.742 1.67l7.225 7.989A2 2 0 0 1 10 14z",key:"sc7q7i"}]],We=L("funnel",Ve);/**
22
+ * @license lucide-react v0.577.0 - ISC
23
+ *
24
+ * This source code is licensed under the ISC license.
25
+ * See the LICENSE file in the root directory of this source tree.
26
+ */const qe=[["circle",{cx:"9",cy:"12",r:"3",key:"u3jwor"}],["rect",{width:"20",height:"14",x:"2",y:"5",rx:"7",key:"g7kal2"}]],Ze=L("toggle-left",qe);/**
27
+ * @license lucide-react v0.577.0 - ISC
28
+ *
29
+ * This source code is licensed under the ISC license.
30
+ * See the LICENSE file in the root directory of this source tree.
31
+ */const Je=[["circle",{cx:"15",cy:"12",r:"3",key:"1afu0r"}],["rect",{width:"20",height:"14",x:"2",y:"5",rx:"7",key:"g7kal2"}]],Ye=L("toggle-right",Je);function R({children:s}){return e.jsxs("p",{className:"text-sm text-[#939084] py-4",children:[e.jsx("span",{className:"font-medium text-[#6B6960]",children:"Not recorded."})," ",s]})}function Ke({data:s}){const[r,c]=x.useState(null);if(s.length===0)return null;const n=600,a=200,t={top:20,right:20,bottom:30,left:60},j=n-t.left-t.right,o=a-t.top-t.bottom,b=Math.max(...s.map(i=>i.tokens)),h=0,m=b-h||1,E=s.map((i,N)=>({x:t.left+N/(s.length-1)*j,y:t.top+o-(i.tokens-h)/m*o,...i})),v=E.map((i,N)=>`${N===0?"M":"L"} ${i.x} ${i.y}`).join(" "),u=`${v} L ${E[E.length-1].x} ${t.top+o} L ${E[0].x} ${t.top+o} Z`,p=i=>i>=1e6?`${(i/1e6).toFixed(1)}M`:i>=1e3?`${(i/1e3).toFixed(0)}K`:String(i),k=Array.from({length:5},(i,N)=>({value:h+m*N/4,y:t.top+o-N/4*o}));return e.jsxs("svg",{viewBox:`0 0 ${n} ${a}`,className:"w-full",preserveAspectRatio:"xMidYMid meet",children:[k.map((i,N)=>e.jsxs("g",{children:[e.jsx("line",{x1:t.left,y1:i.y,x2:n-t.right,y2:i.y,stroke:"currentColor",strokeOpacity:"0.08",strokeDasharray:"4 4"}),e.jsx("text",{x:t.left-8,y:i.y+4,textAnchor:"end",className:"text-[10px] fill-[#939084]",children:p(i.value)})]},N)),e.jsx("path",{d:u,fill:"url(#tokenGradient)",opacity:"0.15"}),e.jsx("path",{d:v,fill:"none",stroke:"#553DE9",strokeWidth:"2",strokeLinejoin:"round"}),e.jsx("defs",{children:e.jsxs("linearGradient",{id:"tokenGradient",x1:"0",y1:"0",x2:"0",y2:"1",children:[e.jsx("stop",{offset:"0%",stopColor:"#553DE9"}),e.jsx("stop",{offset:"100%",stopColor:"#553DE9",stopOpacity:"0"})]})}),E.map((i,N)=>e.jsxs("g",{children:[e.jsx("circle",{cx:i.x,cy:i.y,r:r===N?5:3,fill:r===N?"#553DE9":"white",stroke:"#553DE9",strokeWidth:"2",className:"cursor-pointer transition-all",onMouseEnter:()=>c(N),onMouseLeave:()=>c(null)}),r===N&&e.jsxs("g",{children:[e.jsx("rect",{x:i.x-50,y:i.y-36,width:"100",height:"24",rx:"4",fill:"#36342E"}),e.jsxs("text",{x:i.x,y:i.y-20,textAnchor:"middle",className:"text-[10px] fill-white font-mono",children:[p(i.tokens)," | ",i.date.slice(5)]})]})]},N)),[0,Math.floor(s.length/2),s.length-1].map(i=>e.jsx("text",{x:E[i].x,y:a-4,textAnchor:"middle",className:"text-[10px] fill-[#939084]",children:s[i].date.slice(5)},i))]})}function Xe({data:s}){const[r,c]=x.useState(null),n=s.reduce((m,E)=>m+E.cost,0),a=160,t=a/2,j=60,o=40;let b=-90;const h=s.map((m,E)=>{const v=m.percentage/100*360,u=b,p=b+v;b=p;const k=u*Math.PI/180,i=p*Math.PI/180,N=v>180?1:0,g=r===E?j+4:j,F=[`M ${t+o*Math.cos(k)} ${t+o*Math.sin(k)}`,`L ${t+g*Math.cos(k)} ${t+g*Math.sin(k)}`,`A ${g} ${g} 0 ${N} 1 ${t+g*Math.cos(i)} ${t+g*Math.sin(i)}`,`L ${t+o*Math.cos(i)} ${t+o*Math.sin(i)}`,`A ${o} ${o} 0 ${N} 0 ${t+o*Math.cos(k)} ${t+o*Math.sin(k)}`,"Z"].join(" ");return{...m,path:F,index:E}});return e.jsxs("div",{className:"flex items-center gap-6",children:[e.jsxs("svg",{width:a,height:a,viewBox:`0 0 ${a} ${a}`,children:[h.map(m=>e.jsx("path",{d:m.path,fill:m.color,opacity:r!==null&&r!==m.index?.4:1,className:"cursor-pointer transition-opacity",onMouseEnter:()=>c(m.index),onMouseLeave:()=>c(null)},m.index)),e.jsx("text",{x:t,y:t-6,textAnchor:"middle",className:"text-xs fill-[#939084]",children:"Total"}),e.jsxs("text",{x:t,y:t+12,textAnchor:"middle",className:"text-sm fill-[#36342E] dark:fill-[#E8E6E3] font-semibold",children:["$",n.toFixed(2)]})]}),e.jsx("div",{className:"flex flex-col gap-2",children:s.map((m,E)=>e.jsxs("div",{className:"flex items-center gap-2 text-sm",onMouseEnter:()=>c(E),onMouseLeave:()=>c(null),children:[e.jsx("span",{className:"w-3 h-3 rounded-sm flex-shrink-0",style:{backgroundColor:m.color}}),e.jsx("span",{className:"text-[#36342E] dark:text-[#E8E6E3]",children:m.provider}),e.jsxs("span",{className:"text-[#939084] ml-auto font-mono",children:["$",m.cost.toFixed(2)]})]},E))})]})}function Qe({data:s}){const r=["Mon","Tue","Wed","Thu","Fri","Sat","Sun"],c=Math.max(...s.flat()),n=a=>{const t=c>0?a/c:0;return t===0?"bg-[#F8F4F0] dark:bg-[#1A1A1E]":t<.25?"bg-[#553DE9]/10":t<.5?"bg-[#553DE9]/25":t<.75?"bg-[#553DE9]/50":"bg-[#553DE9]/80"};return e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("div",{className:"inline-block",children:[e.jsx("div",{className:"flex gap-0.5 mb-1 ml-10",children:Array.from({length:24},(a,t)=>e.jsx("div",{className:"w-4 text-center text-[9px] text-[#939084]",children:t%6===0?`${t}`:""},t))}),s.map((a,t)=>e.jsxs("div",{className:"flex items-center gap-0.5 mb-0.5",children:[e.jsx("span",{className:"w-8 text-right text-[10px] text-[#939084] mr-1",children:r[t]}),a.map((j,o)=>e.jsx("div",{className:`w-4 h-4 rounded-sm ${n(j)} transition-colors`,title:`${r[t]} ${o}:00 - ${j} builds`},o))]},t)),e.jsxs("div",{className:"flex items-center gap-1 mt-2 ml-10",children:[e.jsx("span",{className:"text-[10px] text-[#939084]",children:"Less"}),["bg-[#F8F4F0] dark:bg-[#1A1A1E]","bg-[#553DE9]/10","bg-[#553DE9]/25","bg-[#553DE9]/50","bg-[#553DE9]/80"].map((a,t)=>e.jsx("div",{className:`w-3 h-3 rounded-sm ${a}`},t)),e.jsx("span",{className:"text-[10px] text-[#939084]",children:"More"})]})]})})}function es({data:s={},className:r=""}){var t,j,o,b;const c=Object.values(s).some(h=>h!=null),n=x.useCallback(()=>{const h=new Blob([JSON.stringify(s,null,2)],{type:"application/json"}),m=URL.createObjectURL(h),E=document.createElement("a");E.href=m,E.download=`usage-analytics-${new Date().toISOString().split("T")[0]}.json`,E.click(),URL.revokeObjectURL(m)},[s]),a=s.buildSuccessRate;return e.jsxs("div",{className:`space-y-6 ${r}`,children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(re,{size:18,className:"text-[#553DE9]"}),e.jsx("h3",{className:"text-sm font-semibold text-[#201515] dark:text-[#E8E6E3] uppercase tracking-wider",children:"Usage Analytics"})]}),c&&e.jsx(C,{size:"sm",variant:"ghost",icon:K,onClick:n,children:"Export"})]}),e.jsxs("div",{className:"card p-4",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-3",children:[e.jsx($e,{size:14,className:"text-[#553DE9]"}),e.jsx("h4",{className:"text-sm font-medium text-[#36342E] dark:text-[#E8E6E3]",children:"Token Usage (30 Days)"})]}),(t=s.tokenUsage)!=null&&t.length?e.jsx(Ke,{data:s.tokenUsage}):e.jsx(R,{children:"No endpoint on this server reports daily token usage."})]}),e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[e.jsxs("div",{className:"card p-4",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-3",children:[e.jsx(Ge,{size:14,className:"text-[#553DE9]"}),e.jsx("h4",{className:"text-sm font-medium text-[#36342E] dark:text-[#E8E6E3]",children:"Cost by Model"})]}),(j=s.costBreakdown)!=null&&j.length?e.jsx(Xe,{data:s.costBreakdown}):e.jsx(R,{children:"No run on this project has recorded a cost yet."})]}),e.jsxs("div",{className:"card p-4",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-3",children:[e.jsx(ne,{size:14,className:"text-[#553DE9]"}),e.jsx("h4",{className:"text-sm font-medium text-[#36342E] dark:text-[#E8E6E3]",children:"Build Success Rate"})]}),a!=null?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex items-center gap-4 mb-4",children:[e.jsxs("span",{className:"text-3xl font-bold text-[#36342E] dark:text-[#E8E6E3]",children:[a,"%"]}),e.jsxs("div",{className:"text-xs text-[#939084]",children:[e.jsxs("div",{children:[s.successfulBuilds," passed"]}),e.jsxs("div",{children:[s.failedBuilds," failed"]}),e.jsxs("div",{children:[s.totalBuilds," total"]})]})]}),e.jsx("div",{className:"h-3 bg-[#F8F4F0] dark:bg-[#1A1A1E] rounded-full overflow-hidden",children:e.jsx("div",{className:"h-full rounded-full transition-all",style:{width:`${a}%`,background:a>=80?"#1FC5A8":a>=60?"#F59E0B":"#C45B5B"}})})]}):e.jsx(R,{children:"Build outcomes are not tracked here. Verified outcomes appear as Evidence Receipts on the Metrics page."}),e.jsxs("div",{className:"mt-6",children:[e.jsx("h4",{className:"text-xs font-medium text-[#939084] uppercase tracking-wider mb-2",children:"Top Templates"}),(o=s.templateUsage)!=null&&o.length?e.jsx("div",{className:"space-y-2",children:s.templateUsage.slice(0,5).map((h,m)=>e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("span",{className:"text-sm text-[#36342E] dark:text-[#E8E6E3]",children:[m+1,". ",h.name]}),e.jsxs("span",{className:"text-xs font-mono text-[#939084]",children:[h.count," builds"]})]},m))}):e.jsx(R,{children:"Template usage is not recorded."})]})]})]}),e.jsxs("div",{className:"card p-4",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-3",children:[e.jsx(z,{size:14,className:"text-[#553DE9]"}),e.jsx("h4",{className:"text-sm font-medium text-[#36342E] dark:text-[#E8E6E3]",children:"Peak Usage Hours"})]}),(b=s.peakHours)!=null&&b.length?e.jsx(Qe,{data:s.peakHours}):e.jsx(R,{children:"Build start times are not aggregated by hour on this server."})]})]})}const se={auth:"#553DE9",project:"#1FC5A8",admin:"#F59E0B",deploy:"#C45B5B",api:"#6366F1",system:"#939084"};function ss({category:s}){return e.jsx("span",{className:"px-1.5 py-0.5 rounded text-[10px] font-medium uppercase tracking-wide",style:{backgroundColor:`${se[s]}15`,color:se[s]},children:s})}function ts({events:s,onFetch:r,pollInterval:c=3e4,className:n=""}){const[a,t]=x.useState(s??[]),[j,o]=x.useState(null),[b,h]=x.useState(""),[m,E]=x.useState(""),[v,u]=x.useState(""),[p,k]=x.useState(""),[i,N]=x.useState(""),[g,F]=x.useState(!1),[d,f]=x.useState(null),[y,w]=x.useState(1),[T,X]=x.useState(!1),G=x.useRef(null),M=15;x.useEffect(()=>{if(!r)return;const l=async()=>{try{const A=await r({search:b,user:m,actionType:v,dateFrom:p,dateTo:i});t(A),o(null)}catch(A){o(A instanceof Error?A.message:"request failed")}};if(l(),!(c<=0))return G.current=setInterval(l,c),()=>{G.current&&clearInterval(G.current)}},[r,c,b,m,v,p,i]);const fe=[...new Set(a.map(l=>l.user))].sort(),Ee=[...new Set(a.map(l=>l.action))].sort(),B=a.filter(l=>{if(b){const A=b.toLowerCase();if(!(l.action.toLowerCase().includes(A)||l.user.toLowerCase().includes(A)||l.target.toLowerCase().includes(A)||l.details.toLowerCase().includes(A)||l.ip.includes(A)))return!1}return!(m&&l.user!==m||v&&l.action!==v||p&&l.timestamp<p||i&&l.timestamp>i+"T23:59:59")}),D=Math.ceil(B.length/M),Q=B.slice((y-1)*M,y*M);x.useEffect(()=>{w(1)},[b,m,v,p,i]);const be=x.useCallback(()=>{const l=["Timestamp","User","Action","Target","Details","IP","Category"],A=B.map($=>[$.timestamp,$.user,$.action,$.target,`"${$.details.replace(/"/g,'""')}"`,$.ip,$.category]),S=[l.join(","),...A.map($=>$.join(","))].join(`
32
+ `),ke=new Blob([S],{type:"text/csv"}),ee=URL.createObjectURL(ke),H=document.createElement("a");H.href=ee,H.download=`audit-log-${new Date().toISOString().split("T")[0]}.csv`,H.click(),URL.revokeObjectURL(ee)},[B]),ve=x.useCallback(async()=>{if(r){X(!0);try{const l=await r({search:b,user:m,actionType:v,dateFrom:p,dateTo:i});t(l),o(null)}catch(l){o(l instanceof Error?l.message:"request failed")}finally{X(!1)}}},[r,b,m,v,p,i]),Ne=l=>new Date(l).toLocaleString("en-US",{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit",hour12:!1});return e.jsxs("div",{className:`space-y-4 ${n}`,children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(J,{size:18,className:"text-[#553DE9]"}),e.jsx("h3",{className:"text-sm font-semibold text-[#201515] dark:text-[#E8E6E3] uppercase tracking-wider",children:"Audit Trail"}),!j&&e.jsxs("span",{className:"text-xs text-[#939084] ml-1",children:[B.length," event",B.length!==1?"s":""]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(C,{size:"sm",variant:"ghost",icon:pe,onClick:ve,loading:T,children:"Refresh"}),e.jsx(C,{size:"sm",variant:"ghost",icon:K,onClick:be,children:"CSV"})]})]}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("div",{className:"relative flex-1",children:[e.jsx(le,{size:14,className:"absolute left-3 top-1/2 -translate-y-1/2 text-[#939084]"}),e.jsx("input",{type:"text",value:b,onChange:l=>h(l.target.value),placeholder:"Search events...",className:"w-full pl-9 pr-3 py-2 text-sm rounded-lg border border-[#ECEAE3] dark:border-[#2A2A30] bg-white dark:bg-[#1A1A1E] text-[#201515] dark:text-[#E8E6E3] placeholder-[#939084]"})]}),e.jsx(C,{size:"sm",variant:g?"secondary":"ghost",icon:We,onClick:()=>F(!g),children:"Filters"})]}),g&&e.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-3 p-3 border border-[#ECEAE3] dark:border-[#2A2A30] rounded-lg bg-[#F8F4F0] dark:bg-[#222228]",children:[e.jsxs("div",{children:[e.jsx("label",{className:"block text-xs font-medium text-[#6B6960] mb-1",children:"User"}),e.jsxs("select",{value:m,onChange:l=>E(l.target.value),className:"w-full px-2 py-1.5 text-sm rounded-lg border border-[#ECEAE3] dark:border-[#2A2A30] bg-white dark:bg-[#1A1A1E] text-[#201515] dark:text-[#E8E6E3]",children:[e.jsx("option",{value:"",children:"All Users"}),fe.map(l=>e.jsx("option",{value:l,children:l},l))]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-xs font-medium text-[#6B6960] mb-1",children:"Action"}),e.jsxs("select",{value:v,onChange:l=>u(l.target.value),className:"w-full px-2 py-1.5 text-sm rounded-lg border border-[#ECEAE3] dark:border-[#2A2A30] bg-white dark:bg-[#1A1A1E] text-[#201515] dark:text-[#E8E6E3]",children:[e.jsx("option",{value:"",children:"All Actions"}),Ee.map(l=>e.jsx("option",{value:l,children:l},l))]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-xs font-medium text-[#6B6960] mb-1",children:"From"}),e.jsx("input",{type:"date",value:p,onChange:l=>k(l.target.value),className:"w-full px-2 py-1.5 text-sm rounded-lg border border-[#ECEAE3] dark:border-[#2A2A30] bg-white dark:bg-[#1A1A1E] text-[#201515] dark:text-[#E8E6E3]"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-xs font-medium text-[#6B6960] mb-1",children:"To"}),e.jsx("input",{type:"date",value:i,onChange:l=>N(l.target.value),className:"w-full px-2 py-1.5 text-sm rounded-lg border border-[#ECEAE3] dark:border-[#2A2A30] bg-white dark:bg-[#1A1A1E] text-[#201515] dark:text-[#E8E6E3]"})]})]})]}),e.jsx("div",{className:"border border-[#ECEAE3] dark:border-[#2A2A30] rounded-lg overflow-hidden",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"bg-[#F8F4F0] dark:bg-[#222228]",children:[e.jsx("th",{className:"w-8 px-2 py-2.5"}),e.jsx("th",{className:"text-left px-3 py-2.5 text-xs font-medium text-[#6B6960]",children:"Timestamp"}),e.jsx("th",{className:"text-left px-3 py-2.5 text-xs font-medium text-[#6B6960]",children:"User"}),e.jsx("th",{className:"text-left px-3 py-2.5 text-xs font-medium text-[#6B6960]",children:"Action"}),e.jsx("th",{className:"text-left px-3 py-2.5 text-xs font-medium text-[#6B6960]",children:"Target"}),e.jsx("th",{className:"text-left px-3 py-2.5 text-xs font-medium text-[#6B6960] hidden md:table-cell",children:"IP"})]})}),e.jsxs("tbody",{children:[Q.map(l=>e.jsxs(e.Fragment,{children:[e.jsxs("tr",{className:"border-t border-[#ECEAE3] dark:border-[#2A2A30] hover:bg-[#F8F4F0] dark:hover:bg-[#222228] transition-colors cursor-pointer",onClick:()=>f(d===l.id?null:l.id),children:[e.jsx("td",{className:"px-2 py-2.5 text-center",children:d===l.id?e.jsx(ie,{size:12,className:"text-[#939084]"}):e.jsx(P,{size:12,className:"text-[#939084]"})}),e.jsx("td",{className:"px-3 py-2.5",children:e.jsxs("div",{className:"flex items-center gap-1.5 text-xs text-[#939084]",children:[e.jsx(z,{size:12}),e.jsx("span",{className:"font-mono",children:Ne(l.timestamp)})]})}),e.jsx("td",{className:"px-3 py-2.5",children:e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx(Be,{name:l.user.split("@")[0],size:"sm"}),e.jsx("span",{className:"text-[#201515] dark:text-[#E8E6E3] truncate max-w-[150px]",children:l.user})]})}),e.jsx("td",{className:"px-3 py-2.5",children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(ss,{category:l.category}),e.jsx("span",{className:"text-[#201515] dark:text-[#E8E6E3] font-medium",children:l.action})]})}),e.jsx("td",{className:"px-3 py-2.5",children:e.jsx("span",{className:"text-[#6B6960] truncate max-w-[120px] block",children:l.target||"--"})}),e.jsx("td",{className:"px-3 py-2.5 hidden md:table-cell",children:e.jsxs("div",{className:"flex items-center gap-1 text-xs text-[#939084]",children:[e.jsx(ze,{size:12}),e.jsx("span",{className:"font-mono",children:l.ip||"--"})]})})]},l.id),d===l.id&&e.jsx("tr",{className:"bg-[#F8F4F0] dark:bg-[#222228]",children:e.jsx("td",{colSpan:6,className:"px-6 py-3",children:e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx(ye,{size:14,className:"text-[#939084] flex-shrink-0 mt-0.5"}),e.jsxs("div",{className:"text-sm text-[#6B6960]",children:[e.jsx("p",{className:"font-medium text-[#201515] dark:text-[#E8E6E3] mb-1",children:"Details"}),e.jsx("p",{children:l.details}),e.jsxs("div",{className:"flex items-center gap-4 mt-2 text-xs text-[#939084]",children:[e.jsxs("span",{children:["Event ID: ",l.id]}),e.jsxs("span",{children:["Full timestamp: ",new Date(l.timestamp).toISOString()]}),e.jsxs("span",{children:["IP: ",l.ip||"not recorded"]})]})]})]})})},`${l.id}-details`)]})),Q.length===0&&e.jsx("tr",{children:e.jsx("td",{colSpan:6,className:"px-4 py-8 text-center text-sm text-[#939084]",children:j?`Could not load the audit log (${j}). Nothing is shown rather than a guess.`:a.length===0?"No audit events recorded yet.":"No events match your filters."})})]})]})}),D>1&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("span",{className:"text-xs text-[#939084]",children:["Showing ",(y-1)*M+1,"-",Math.min(y*M,B.length)," of ",B.length]}),e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx("button",{onClick:()=>w(l=>Math.max(1,l-1)),disabled:y===1,className:"p-1.5 rounded-lg text-[#939084] hover:bg-[#F8F4F0] dark:hover:bg-[#222228] disabled:opacity-40 transition-colors",children:e.jsx(Le,{size:16})}),Array.from({length:Math.min(D,5)},(l,A)=>{let S;return D<=5||y<=3?S=A+1:y>=D-2?S=D-4+A:S=y-2+A,e.jsx("button",{onClick:()=>w(S),className:`w-8 h-8 rounded-lg text-xs font-medium transition-colors ${y===S?"bg-[#553DE9] text-white":"text-[#939084] hover:bg-[#F8F4F0] dark:hover:bg-[#222228]"}`,children:S},S)}),e.jsx("button",{onClick:()=>w(l=>Math.min(D,l+1)),disabled:y===D,className:"p-1.5 rounded-lg text-[#939084] hover:bg-[#F8F4F0] dark:hover:bg-[#222228] disabled:opacity-40 transition-colors",children:e.jsx(P,{size:16})})]})]})]})}const V={admin:{label:"Admin",color:"#553DE9"},editor:{label:"Editor",color:"#1FC5A8"},viewer:{label:"Viewer",color:"#939084"}},te={active:{label:"Active",color:"#1FC5A8"},inactive:{label:"Inactive",color:"#939084"},invited:{label:"Invited",color:"#F59E0B"}};function q(s){if(!s)return"Never";const r=Date.now()-new Date(s).getTime(),c=Math.floor(r/6e4);if(c<1)return"Just now";if(c<60)return`${c}m ago`;const n=Math.floor(c/60);if(n<24)return`${n}h ago`;const a=Math.floor(n/24);return a<30?`${a}d ago`:`${Math.floor(a/30)}mo ago`}function ge(s){return s.split(" ").map(r=>r[0]).join("").toUpperCase().slice(0,2)}function as({onSubmit:s,onCancel:r}){const[c,n]=x.useState(""),[a,t]=x.useState("editor");return e.jsxs("div",{className:"border border-[#553DE9]/20 bg-[#553DE9]/5 dark:bg-[#553DE9]/10 rounded-lg p-4 space-y-3",children:[e.jsx("h4",{className:"text-sm font-semibold text-[#201515] dark:text-[#E8E6E3]",children:"Invite New User"}),e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-3",children:[e.jsxs("div",{className:"md:col-span-2",children:[e.jsx("label",{className:"block text-xs font-medium text-[#6B6960] mb-1",children:"Email"}),e.jsxs("div",{className:"relative",children:[e.jsx(De,{size:14,className:"absolute left-3 top-1/2 -translate-y-1/2 text-[#939084]"}),e.jsx("input",{type:"email",value:c,onChange:j=>n(j.target.value),placeholder:"colleague@company.com",className:"w-full pl-9 pr-3 py-2 text-sm rounded-lg border border-[#ECEAE3] dark:border-[#2A2A30] bg-white dark:bg-[#1A1A1E] text-[#201515] dark:text-[#E8E6E3] placeholder-[#939084]",autoFocus:!0})]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-xs font-medium text-[#6B6960] mb-1",children:"Role"}),e.jsxs("select",{value:a,onChange:j=>t(j.target.value),className:"w-full px-3 py-2 text-sm rounded-lg border border-[#ECEAE3] dark:border-[#2A2A30] bg-white dark:bg-[#1A1A1E] text-[#201515] dark:text-[#E8E6E3]",children:[e.jsx("option",{value:"admin",children:"Admin"}),e.jsx("option",{value:"editor",children:"Editor"}),e.jsx("option",{value:"viewer",children:"Viewer"})]})]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(C,{size:"sm",icon:ue,onClick:()=>s(c,a),disabled:!c.trim()||!c.includes("@"),children:"Send Invite"}),e.jsx(C,{size:"sm",variant:"ghost",onClick:r,children:"Cancel"})]})]})}function rs({user:s,onClose:r,onChangeRole:c,onToggleStatus:n}){return e.jsxs("div",{className:"border border-[#ECEAE3] dark:border-[#2A2A30] rounded-lg p-4 space-y-4",children:[e.jsxs("div",{className:"flex items-start justify-between",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[s.avatar_url?e.jsx("img",{src:s.avatar_url,alt:"",className:"w-10 h-10 rounded-full"}):e.jsx("div",{className:"w-10 h-10 rounded-full bg-[#553DE9] flex items-center justify-center text-white text-sm font-bold",children:ge(s.name)}),e.jsxs("div",{children:[e.jsx("p",{className:"text-sm font-medium text-[#201515] dark:text-[#E8E6E3]",children:s.name}),e.jsx("p",{className:"text-xs text-[#939084]",children:s.email})]})]}),e.jsx("button",{onClick:r,className:"p-1 rounded-lg text-[#939084] hover:bg-[#F8F4F0] dark:hover:bg-[#222228]",children:e.jsx(ce,{size:16})})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-4 text-sm",children:[e.jsxs("div",{children:[e.jsx("label",{className:"block text-xs font-medium text-[#6B6960] mb-1",children:"Role"}),e.jsxs("select",{value:s.role,onChange:a=>c(a.target.value),className:"w-full px-3 py-2 text-sm rounded-lg border border-[#ECEAE3] dark:border-[#2A2A30] bg-white dark:bg-[#1A1A1E] text-[#201515] dark:text-[#E8E6E3]",children:[e.jsx("option",{value:"admin",children:"Admin"}),e.jsx("option",{value:"editor",children:"Editor"}),e.jsx("option",{value:"viewer",children:"Viewer"})]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-xs font-medium text-[#6B6960] mb-1",children:"Status"}),e.jsx("button",{onClick:n,className:"flex items-center gap-2 px-3 py-2 w-full rounded-lg border border-[#ECEAE3] dark:border-[#2A2A30] bg-white dark:bg-[#1A1A1E] text-sm text-left hover:bg-[#F8F4F0] dark:hover:bg-[#222228] transition-colors",children:s.status==="active"?e.jsxs(e.Fragment,{children:[e.jsx(Ye,{size:16,className:"text-[#1FC5A8]"}),e.jsx("span",{className:"text-[#1FC5A8]",children:"Active"})]}):e.jsxs(e.Fragment,{children:[e.jsx(Ze,{size:16,className:"text-[#939084]"}),e.jsx("span",{className:"text-[#939084]",children:"Inactive"})]})})]})]}),e.jsxs("div",{className:"flex items-center gap-6 text-xs text-[#939084] pt-2 border-t border-[#ECEAE3] dark:border-[#2A2A30]",children:[e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx(z,{size:12}),e.jsxs("span",{children:["Last active: ",q(s.lastActive)]})]}),e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx(z,{size:12}),e.jsxs("span",{children:["Joined: ",q(s.joinedAt)]})]})]})]})}function ns({users:s,onChangeRole:r,onToggleStatus:c,onInviteUser:n,className:a=""}){const[t,j]=x.useState(s??[]),[o,b]=x.useState(""),[h,m]=x.useState(""),[E,v]=x.useState(!1),[u,p]=x.useState(null),k=t.filter(d=>{if(o){const f=o.toLowerCase();if(!d.name.toLowerCase().includes(f)&&!d.email.toLowerCase().includes(f))return!1}return!(h&&d.role!==h)}),i=t.find(d=>d.id===u)||null,N=x.useCallback(async(d,f)=>{if(!n)return;await n(d,f);const y={id:`u-${Date.now()}`,name:d.split("@")[0],email:d,role:f,status:"invited",lastActive:null,joinedAt:new Date().toISOString()};j(w=>[...w,y]),v(!1)},[n]),g=x.useCallback(async(d,f)=>{r&&(await r(d,f),j(y=>y.map(w=>w.id===d?{...w,role:f}:w)))},[r]),F=x.useCallback(async d=>{const f=t.find(w=>w.id===d);if(!f||!c)return;const y=f.status!=="active";await c(d,y),j(w=>w.map(T=>T.id===d?{...T,status:y?"active":"inactive"}:T))},[t,c]);return s?e.jsxs("div",{className:`space-y-4 ${a}`,children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(I,{size:18,className:"text-[#553DE9]"}),e.jsx("h3",{className:"text-sm font-semibold text-[#201515] dark:text-[#E8E6E3] uppercase tracking-wider",children:"User Management"}),e.jsxs("span",{className:"text-xs text-[#939084]",children:[t.length," users"]})]}),!E&&n&&e.jsx(C,{size:"sm",variant:"secondary",icon:ue,onClick:()=>v(!0),children:"Invite User"})]}),E&&e.jsx(as,{onSubmit:N,onCancel:()=>v(!1)}),i&&e.jsx(rs,{user:i,onClose:()=>p(null),onChangeRole:d=>g(i.id,d),onToggleStatus:()=>F(i.id)}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("div",{className:"relative flex-1",children:[e.jsx(le,{size:14,className:"absolute left-3 top-1/2 -translate-y-1/2 text-[#939084]"}),e.jsx("input",{type:"text",value:o,onChange:d=>b(d.target.value),placeholder:"Search users...",className:"w-full pl-9 pr-3 py-2 text-sm rounded-lg border border-[#ECEAE3] dark:border-[#2A2A30] bg-white dark:bg-[#1A1A1E] text-[#201515] dark:text-[#E8E6E3] placeholder-[#939084]"})]}),e.jsxs("select",{value:h,onChange:d=>m(d.target.value),className:"px-3 py-2 text-sm rounded-lg border border-[#ECEAE3] dark:border-[#2A2A30] bg-white dark:bg-[#1A1A1E] text-[#201515] dark:text-[#E8E6E3]",children:[e.jsx("option",{value:"",children:"All Roles"}),e.jsx("option",{value:"admin",children:"Admin"}),e.jsx("option",{value:"editor",children:"Editor"}),e.jsx("option",{value:"viewer",children:"Viewer"})]})]}),e.jsxs("div",{className:"border border-[#ECEAE3] dark:border-[#2A2A30] rounded-lg overflow-hidden divide-y divide-[#ECEAE3] dark:divide-[#2A2A30]",children:[k.map(d=>e.jsxs("button",{type:"button",onClick:()=>p(u===d.id?null:d.id),className:`w-full flex items-center gap-3 px-4 py-3 text-left hover:bg-[#F8F4F0] dark:hover:bg-[#222228] transition-colors ${u===d.id?"bg-[#F8F4F0] dark:bg-[#222228]":""}`,children:[d.avatar_url?e.jsx("img",{src:d.avatar_url,alt:"",className:"w-8 h-8 rounded-full flex-shrink-0"}):e.jsx("div",{className:"w-8 h-8 rounded-full bg-[#553DE9] flex items-center justify-center text-white text-xs font-bold flex-shrink-0",children:ge(d.name)}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("p",{className:"text-sm font-medium text-[#201515] dark:text-[#E8E6E3] truncate",children:d.name}),e.jsx("p",{className:"text-xs text-[#939084] truncate",children:d.email})]}),e.jsx("span",{className:"px-2 py-0.5 rounded text-[10px] font-medium flex-shrink-0",style:{backgroundColor:`${V[d.role].color}15`,color:V[d.role].color},children:V[d.role].label}),e.jsxs("div",{className:"flex items-center gap-1.5 flex-shrink-0",children:[e.jsx("span",{className:"w-2 h-2 rounded-full",style:{backgroundColor:te[d.status].color}}),e.jsx("span",{className:"text-xs text-[#939084] hidden md:inline",children:te[d.status].label})]}),e.jsx("span",{className:"text-xs text-[#939084] flex-shrink-0 hidden lg:inline w-16 text-right",children:q(d.lastActive)}),e.jsx(P,{size:14,className:"text-[#939084] flex-shrink-0"})]},d.id)),k.length===0&&e.jsx("div",{className:"px-4 py-8 text-center text-sm text-[#939084]",children:"No users match your search."})]})]}):e.jsxs("div",{className:`space-y-4 ${a}`,children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(I,{size:18,className:"text-[#553DE9]"}),e.jsx("h3",{className:"text-sm font-semibold text-[#201515] dark:text-[#E8E6E3] uppercase tracking-wider",children:"User Management"})]}),e.jsxs("div",{className:"border border-[#ECEAE3] dark:border-[#2A2A30] rounded-lg px-4 py-8 text-center",children:[e.jsx("p",{className:"text-sm font-medium text-[#36342E] dark:text-[#E8E6E3]",children:"Not connected"}),e.jsx("p",{className:"text-xs text-[#939084] mt-1",children:"This server has no user directory, so no users are listed. Team membership is managed on the Teams page."})]})]})}function ls({project:s,onApprove:r,onReject:c}){const[n,a]=x.useState(!1),[t,j]=x.useState(""),[o,b]=x.useState(!1);return e.jsxs("div",{className:"border border-[#ECEAE3] dark:border-[#2A2A30] rounded-lg overflow-hidden",children:[e.jsxs("button",{type:"button",onClick:()=>a(!n),className:"w-full flex items-center gap-3 px-4 py-3 text-left hover:bg-[#F8F4F0] dark:hover:bg-[#222228] transition-colors",children:[n?e.jsx(ie,{size:14,className:"text-[#939084]"}):e.jsx(P,{size:14,className:"text-[#939084]"}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-sm font-medium text-[#201515] dark:text-[#E8E6E3]",children:s.name}),e.jsx("span",{className:"px-1.5 py-0.5 rounded text-[10px] font-medium bg-[#F59E0B]/10 text-[#F59E0B]",children:"Pending"})]}),e.jsxs("div",{className:"flex items-center gap-3 text-xs text-[#939084] mt-0.5",children:[e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx(Te,{size:10}),s.submittedBy]}),e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx(de,{size:10}),s.template]}),e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx(Y,{size:10}),"~$",s.estimatedCost.toFixed(2)]})]})]}),e.jsx("span",{className:"text-xs text-[#939084] flex-shrink-0",children:new Date(s.submittedAt).toLocaleString("en-US",{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit",hour12:!1})})]}),n&&e.jsxs("div",{className:"px-4 pb-4 pt-2 border-t border-[#ECEAE3] dark:border-[#2A2A30] space-y-3",children:[e.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-3 text-sm",children:[e.jsxs("div",{children:[e.jsx("label",{className:"block text-xs text-[#6B6960]",children:"Template"}),e.jsx("span",{className:"text-[#201515] dark:text-[#E8E6E3] font-medium",children:s.template})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-xs text-[#6B6960]",children:"Provider"}),e.jsx("span",{className:"text-[#201515] dark:text-[#E8E6E3] font-medium",children:s.provider})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-xs text-[#6B6960]",children:"Est. Cost"}),e.jsxs("span",{className:"text-[#201515] dark:text-[#E8E6E3] font-medium",children:["$",s.estimatedCost.toFixed(2)]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-xs text-[#6B6960]",children:"Est. Iterations"}),e.jsx("span",{className:"text-[#201515] dark:text-[#E8E6E3] font-medium",children:s.estimatedIterations})]})]}),e.jsx("p",{className:"text-sm text-[#6B6960]",children:s.description}),o?e.jsxs("div",{className:"space-y-2",children:[e.jsx("textarea",{value:t,onChange:h=>j(h.target.value),placeholder:"Add a comment (optional)...",rows:2,className:"w-full px-3 py-2 text-sm rounded-lg border border-[#ECEAE3] dark:border-[#2A2A30] bg-white dark:bg-[#1A1A1E] text-[#201515] dark:text-[#E8E6E3] placeholder-[#939084] resize-none"}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(C,{size:"sm",icon:je,onClick:()=>r(t),children:"Approve"}),e.jsx(C,{size:"sm",variant:"danger",icon:ce,onClick:()=>c(t),children:"Reject"}),e.jsx(C,{size:"sm",variant:"ghost",onClick:()=>b(!1),children:"Cancel"})]})]}):e.jsx("div",{className:"flex items-center gap-2",children:e.jsx(C,{size:"sm",variant:"secondary",icon:Ae,onClick:()=>b(!0),children:"Review"})})]})]})}function is({configs:s}){return e.jsx("div",{className:"space-y-3",children:s.map(r=>{const c=r.budgetLimit>0?r.budgetUsed/r.budgetLimit*100:0,n=c>=r.alertThreshold,a=c>=100;return e.jsxs("div",{className:"border border-[#ECEAE3] dark:border-[#2A2A30] rounded-lg p-3",children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("span",{className:"text-sm font-medium text-[#201515] dark:text-[#E8E6E3]",children:r.projectName}),e.jsxs("div",{className:"flex items-center gap-2",children:[n&&e.jsx(Z,{size:14,className:a?"text-[#C45B5B]":"text-[#F59E0B]"}),e.jsxs("span",{className:"text-xs font-mono text-[#939084]",children:["$",r.budgetUsed.toFixed(2)," / $",r.budgetLimit.toFixed(2)]})]})]}),e.jsx("div",{className:"h-2 bg-[#F8F4F0] dark:bg-[#1A1A1E] rounded-full overflow-hidden",children:e.jsx("div",{className:"h-full rounded-full transition-all",style:{width:`${Math.min(c,100)}%`,background:a?"#C45B5B":n?"#F59E0B":"#1FC5A8"}})}),e.jsxs("div",{className:"flex items-center justify-between mt-1",children:[e.jsxs("span",{className:"text-[10px] text-[#939084]",children:[c.toFixed(0),"% used"]}),e.jsxs("span",{className:"text-[10px] text-[#939084]",children:["Alert at ",r.alertThreshold,"%"]})]})]},r.projectId)})})}function W({children:s}){return e.jsxs("div",{className:"text-center py-8",children:[e.jsx(oe,{size:24,className:"mx-auto text-[#939084] mb-2"}),e.jsx("p",{className:"text-sm font-medium text-[#36342E] dark:text-[#E8E6E3]",children:"Not connected"}),e.jsx("p",{className:"text-xs text-[#939084] mt-1",children:s})]})}function cs({pendingProjects:s,budgetConfigs:r,onApproveProject:c,onRejectProject:n,className:a=""}){const[t,j]=x.useState(s??[]),[o,b]=x.useState("approvals"),h=t.filter(u=>u.status==="pending").length,m=x.useCallback(async(u,p)=>{c&&(await c(u,p),j(k=>k.map(i=>i.id===u?{...i,status:"approved"}:i)))},[c]),E=x.useCallback(async(u,p)=>{n&&(await n(u,p),j(k=>k.map(i=>i.id===u?{...i,status:"rejected"}:i)))},[n]),v=[{id:"approvals",label:"Approvals",icon:je,count:h},{id:"budgets",label:"Budgets",icon:Y},{id:"templates",label:"Templates",icon:de}];return e.jsxs("div",{className:`space-y-4 ${a}`,children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(_e,{size:18,className:"text-[#553DE9]"}),e.jsx("h3",{className:"text-sm font-semibold text-[#201515] dark:text-[#E8E6E3] uppercase tracking-wider",children:"Project Governance"})]}),e.jsx("div",{className:"flex items-center gap-1 border-b border-[#ECEAE3] dark:border-[#2A2A30]",children:v.map(u=>e.jsxs("button",{onClick:()=>b(u.id),className:`flex items-center gap-1.5 px-3 py-2 text-xs font-medium border-b-2 transition-colors ${o===u.id?"border-[#553DE9] text-[#553DE9]":"border-transparent text-[#939084] hover:text-[#36342E] dark:hover:text-[#E8E6E3]"}`,children:[e.jsx(u.icon,{size:14}),u.label,u.count!==void 0&&u.count>0&&e.jsx("span",{className:"ml-1 px-1.5 py-0.5 rounded-full text-[10px] bg-[#553DE9]/10 text-[#553DE9]",children:u.count})]},u.id))}),o==="approvals"&&!s&&e.jsx(W,{children:"No project approval workflow is wired to this server, so nothing is waiting and nothing has been reviewed."}),o==="approvals"&&s&&e.jsx("div",{className:"space-y-3",children:t.filter(u=>u.status==="pending").length===0?e.jsxs("div",{className:"text-center py-8",children:[e.jsx(oe,{size:24,className:"mx-auto text-[#939084] mb-2"}),e.jsx("p",{className:"text-sm text-[#939084]",children:"No pending approvals"}),e.jsx("p",{className:"text-xs text-[#939084] mt-1",children:"All project requests have been reviewed."})]}):t.filter(u=>u.status==="pending").map(u=>e.jsx(ls,{project:u,onApprove:p=>m(u.id,p),onReject:p=>E(u.id,p)},u.id))}),o==="budgets"&&(r?e.jsx(is,{configs:r}):e.jsx(W,{children:"No per-project budgets are served here. A run's spend cap is set with LOKI_BUDGET_LIMIT and shown on the Metrics page."})),o==="templates"&&e.jsx(W,{children:"Template restrictions are not stored or enforced by this server, so none are shown."})]})}function ds({status:s}){switch(s){case"pass":return e.jsx(xe,{size:18,className:"text-[#1FC5A8]"});case"fail":return e.jsx(me,{size:18,className:"text-[#C45B5B]"});case"warning":return e.jsx(Z,{size:18,className:"text-[#F59E0B]"})}}const os={security:Ue,access:I,data:Me,audit:Ce};function xs({score:s}){const t=2*Math.PI*56,o=270/360*t,b=s/100*o,h=s>=80?"#1FC5A8":s>=60?"#F59E0B":"#C45B5B",m=135;return e.jsxs("div",{className:"relative inline-flex items-center justify-center",children:[e.jsxs("svg",{width:140,height:140,viewBox:"0 0 140 140",children:[e.jsx("circle",{cx:70,cy:70,r:56,fill:"none",stroke:"currentColor",strokeOpacity:"0.08",strokeWidth:10,strokeDasharray:`${o} ${t}`,strokeLinecap:"round",transform:`rotate(${m} 70 70)`}),e.jsx("circle",{cx:70,cy:70,r:56,fill:"none",stroke:h,strokeWidth:10,strokeDasharray:`${b} ${t}`,strokeLinecap:"round",transform:`rotate(${m} 70 70)`,className:"transition-all duration-700"})]}),e.jsxs("div",{className:"absolute inset-0 flex flex-col items-center justify-center",children:[e.jsxs("span",{className:"text-3xl font-bold text-[#36342E] dark:text-[#E8E6E3]",children:[s,"%"]}),e.jsx("span",{className:"text-xs text-[#939084]",children:"Compliant"})]})]})}function ms({items:s,onRefresh:r,className:c=""}){const[n,a]=x.useState(s??[]),[t,j]=x.useState(!1),[o,b]=x.useState(null),[h,m]=x.useState(!1),E=n.filter(g=>g.status==="pass").length,v=n.filter(g=>g.status==="warning").length,u=n.filter(g=>g.status==="fail").length,p=n.length>0?Math.round(E/n.length*100):null,k=x.useCallback(async()=>{j(!0);try{if(r){const g=await r();a(g)}}catch{}finally{j(!1)}},[r]),i=x.useCallback(()=>{m(!0);const g={generatedAt:new Date().toISOString(),overallScore:p,summary:{pass:E,warning:v,fail:u,total:n.length},items:n.map(y=>({title:y.title,status:y.status,category:y.category,details:y.details,lastChecked:y.lastChecked}))},F=new Blob([JSON.stringify(g,null,2)],{type:"application/json"}),d=URL.createObjectURL(F),f=document.createElement("a");f.href=d,f.download=`compliance-report-${new Date().toISOString().split("T")[0]}.json`,f.click(),URL.revokeObjectURL(d),setTimeout(()=>m(!1),1e3)},[n,p,E,v,u]),N=["security","access","data","audit"];return e.jsxs("div",{className:`space-y-6 ${c}`,children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(we,{size:18,className:"text-[#553DE9]"}),e.jsx("h3",{className:"text-sm font-semibold text-[#201515] dark:text-[#E8E6E3] uppercase tracking-wider",children:"Compliance"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[r&&e.jsx(C,{size:"sm",variant:"ghost",icon:pe,onClick:k,loading:t,children:"Refresh"}),p!==null&&e.jsx(C,{size:"sm",variant:"secondary",icon:K,onClick:i,loading:h,children:"Generate Report"})]})]}),p===null?e.jsxs("div",{className:"card p-6 text-center",children:[e.jsx("p",{className:"text-sm font-medium text-[#36342E] dark:text-[#E8E6E3]",children:"Not connected"}),e.jsx("p",{className:"text-xs text-[#939084] mt-1",children:"No compliance checks are wired to this server, so there is no score. Nothing here has been checked."})]}):e.jsx("div",{className:"card p-6",children:e.jsxs("div",{className:"flex items-center gap-8",children:[e.jsx(xs,{score:p}),e.jsxs("div",{className:"flex-1 space-y-3",children:[e.jsx("h4",{className:"text-sm font-medium text-[#36342E] dark:text-[#E8E6E3]",children:"Compliance Score"}),e.jsxs("div",{className:"grid grid-cols-3 gap-4",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(xe,{size:16,className:"text-[#1FC5A8]"}),e.jsxs("div",{children:[e.jsx("span",{className:"text-lg font-bold text-[#36342E] dark:text-[#E8E6E3]",children:E}),e.jsx("span",{className:"text-xs text-[#939084] ml-1",children:"Passing"})]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Z,{size:16,className:"text-[#F59E0B]"}),e.jsxs("div",{children:[e.jsx("span",{className:"text-lg font-bold text-[#36342E] dark:text-[#E8E6E3]",children:v}),e.jsx("span",{className:"text-xs text-[#939084] ml-1",children:"Warnings"})]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(me,{size:16,className:"text-[#C45B5B]"}),e.jsxs("div",{children:[e.jsx("span",{className:"text-lg font-bold text-[#36342E] dark:text-[#E8E6E3]",children:u}),e.jsx("span",{className:"text-xs text-[#939084] ml-1",children:"Failing"})]})]})]})]})]})}),N.map(g=>{const F=n.filter(f=>f.category===g);if(F.length===0)return null;const d=os[g];return e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(d,{size:14,className:"text-[#553DE9]"}),e.jsx("h4",{className:"text-xs font-semibold text-[#6B6960] uppercase tracking-wider",children:g})]}),e.jsx("div",{className:"border border-[#ECEAE3] dark:border-[#2A2A30] rounded-lg overflow-hidden divide-y divide-[#ECEAE3] dark:divide-[#2A2A30]",children:F.map(f=>e.jsxs("div",{children:[e.jsxs("button",{type:"button",onClick:()=>b(o===f.id?null:f.id),className:"w-full flex items-center gap-3 px-4 py-3 text-left hover:bg-[#F8F4F0] dark:hover:bg-[#222228] transition-colors",children:[e.jsx(ds,{status:f.status}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("p",{className:"text-sm font-medium text-[#201515] dark:text-[#E8E6E3]",children:f.title}),e.jsx("p",{className:"text-xs text-[#939084] truncate",children:f.description})]}),e.jsxs("div",{className:"flex items-center gap-1 text-[10px] text-[#939084] flex-shrink-0",children:[e.jsx(z,{size:10}),"Checked ",new Date(f.lastChecked).toLocaleString("en-US",{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit",hour12:!1})]})]}),o===f.id&&e.jsxs("div",{className:"px-4 pb-3 pt-1 bg-[#F8F4F0] dark:bg-[#222228]",children:[f.details&&e.jsx("p",{className:"text-sm text-[#6B6960] mb-2",children:f.details}),f.remediationUrl&&f.status!=="pass"&&e.jsxs("a",{href:f.remediationUrl,className:"inline-flex items-center gap-1 text-xs text-[#553DE9] hover:underline",children:[e.jsx(Fe,{size:12}),"Fix this issue"]})]})]},f.id))})]},g)})]})}function hs(s){return s==null?"Not recorded":`$${s.toFixed(2)}`}function O(s,r){return s===void 0?"...":s===null?"Unavailable":r(s)}const ae=["#553DE9","#1FC5A8","#F59E0B","#6366F1","#C45B5B","#939084"];function us(s){if(!s||s.cost_recorded!==!0)return;const r=Object.entries(s.by_model||{}).map(([n,a])=>{const t=typeof a=="number"?a:a==null?void 0:a.cost_usd;return{model:n,usd:typeof t=="number"&&isFinite(t)?t:null}}).filter(n=>n.usd!==null);if(r.length===0)return;const c=r.reduce((n,a)=>n+a.usd,0);return r.map((n,a)=>({provider:n.model,cost:n.usd,percentage:c>0?n.usd/c*100:0,color:ae[a%ae.length]}))}function ps(s){const r=s.split(".")[0].toLowerCase();return["user","auth","login","logout"].includes(r)?"auth":["team","member","role","settings"].includes(r)?"admin":["deploy","build","session"].includes(r)?"deploy":["key","secret","api"].includes(r)?"api":r==="project"?"project":"system"}function js(s){return{id:s.id,timestamp:s.timestamp,user:s.user||"unknown",action:s.action,target:s.target||"",details:s.details||"",ip:"",category:ps(s.action)}}function _({label:s,value:r,note:c,icon:n,color:a}){return e.jsx("div",{className:"card p-4",children:e.jsxs("div",{className:"flex items-start justify-between",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-xs text-[#6B6960] uppercase tracking-wider",children:s}),e.jsx("p",{className:"text-2xl font-bold text-[#36342E] dark:text-[#E8E6E3] mt-1",children:r}),e.jsx("p",{className:"text-xs mt-1 text-[#939084]",children:c})]}),e.jsx("div",{className:"p-2 rounded-lg",style:{backgroundColor:`${a}10`,color:a},children:e.jsx(n,{size:20})})]})})}function gs({entries:s}){const r=n=>new Date(n).toLocaleString("en-US",{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit",hour12:!1}),c=(s||[]).slice().sort((n,a)=>n.timestamp<a.timestamp?1:-1).slice(0,20);return e.jsxs("div",{className:"card p-4",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[e.jsx(J,{size:14,className:"text-[#553DE9]"}),e.jsx("h4",{className:"text-sm font-medium text-[#36342E] dark:text-[#E8E6E3]",children:"Recent Activity"})]}),e.jsx("p",{className:"text-[11px] text-[#939084] mb-3",children:"From this server's recent-activity log. It keeps the last 500 entries and is not tamper-evident."}),s===void 0&&e.jsx("p",{className:"text-sm text-[#939084]",children:"Loading..."}),s===null&&e.jsx("p",{className:"text-sm text-[#939084]",children:"Could not load the activity log. Nothing is shown rather than a guess."}),s&&c.length===0&&e.jsx("p",{className:"text-sm text-[#939084]",children:"No activity recorded yet."}),c.length>0&&e.jsx("div",{className:"space-y-1 max-h-[400px] overflow-y-auto terminal-scroll",children:c.map(n=>e.jsxs("div",{className:"flex items-center gap-3 px-2 py-1.5 rounded-lg hover:bg-[#F8F4F0] dark:hover:bg-[#222228] transition-colors",children:[e.jsx("span",{className:"text-[10px] font-mono text-[#939084] flex-shrink-0 w-24",children:r(n.timestamp)}),e.jsx("div",{className:"flex-1 min-w-0",children:e.jsxs("span",{className:"text-xs",children:[e.jsx("span",{className:"text-[#553DE9] font-medium",children:n.user||"unknown"}),e.jsxs("span",{className:"text-[#6B6960]",children:[" ",n.action," "]}),e.jsx("span",{className:"text-[#201515] dark:text-[#E8E6E3] font-medium",children:n.target})]})})]},n.id))})]})}function fs(){return e.jsxs("div",{className:"max-w-[500px] mx-auto px-6 py-20 text-center",children:[e.jsx(Ie,{size:48,className:"mx-auto text-[#C45B5B] mb-4"}),e.jsx("h1",{className:"font-heading text-h1 text-[#36342E] dark:text-[#E8E6E3] mb-2",children:"Access Denied"}),e.jsx("p",{className:"text-sm text-[#6B6960]",children:"You do not have permission to access the admin dashboard. Contact your organization administrator for access."})]})}const Es=[{id:"overview",label:"Overview",icon:J},{id:"users",label:"Users",icon:I},{id:"analytics",label:"Analytics",icon:re},{id:"governance",label:"Governance",icon:he},{id:"audit",label:"Audit Trail",icon:z},{id:"compliance",label:"Compliance",icon:ne}];function Ms(){const{user:s,isLocalMode:r}=Se(),[c,n]=x.useState("overview"),[a,t]=x.useState({projects:void 0,teams:void 0,cost:void 0,audit:void 0}),j=r||(s==null?void 0:s.authenticated)===!0;x.useEffect(()=>{if(!j)return;let h=!1;return Promise.allSettled([U.getSessionsHistory(),U.getTeams(),U.getCost(),U.getAuditLog()]).then(([m,E,v,u])=>{if(h)return;const p=g=>g.status==="fulfilled"?g.value:null,k=p(E),i=p(m),N=p(u);t({projects:Array.isArray(i)?i.length:null,teams:Array.isArray(k)?{count:k.length,members:k.reduce((g,F)=>{var d;return g+(((d=F.members)==null?void 0:d.length)??0)},0)}:null,cost:p(v),audit:Array.isArray(N)?N:null})}),()=>{h=!0}},[j]);const o=x.useCallback(async()=>(await U.getAuditLog()).map(js),[]);if(!j)return e.jsx(fs,{});const b=us(a.cost);return e.jsxs("div",{className:"max-w-[1200px] mx-auto px-6 py-8",children:[e.jsx("div",{className:"flex items-center justify-between mb-6",children:e.jsx("h1",{className:"font-heading text-h1 text-[#36342E] dark:text-[#E8E6E3]",children:"Admin"})}),e.jsx("div",{className:"flex items-center gap-1 border-b border-[#ECEAE3] dark:border-[#2A2A30] mb-6 overflow-x-auto",children:Es.map(h=>e.jsxs("button",{onClick:()=>n(h.id),className:`flex items-center gap-1.5 px-3 py-2 text-xs font-medium border-b-2 transition-colors whitespace-nowrap ${c===h.id?"border-[#553DE9] text-[#553DE9]":"border-transparent text-[#939084] hover:text-[#36342E] dark:hover:text-[#E8E6E3]"}`,children:[e.jsx(h.icon,{size:14}),h.label]},h.id))}),c==="overview"&&e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4",children:[e.jsx(_,{label:"Projects",value:O(a.projects,String),note:"Recent project folders (history lists up to 20 per location)",icon:he,color:"#1FC5A8"}),e.jsx(_,{label:"Teams",value:O(a.teams,h=>String(h.count)),note:a.teams?`${a.teams.members} member${a.teams.members===1?"":"s"}`:"Team membership",icon:I,color:"#553DE9"}),e.jsx(_,{label:"Total cost",value:O(a.cost,h=>hs(h.estimated_cost_usd)),note:"Recorded for the current project",icon:Y,color:"#C45B5B"}),e.jsx(_,{label:"Audit events",value:O(a.audit,h=>String(h.length)),note:"Recent-activity log entries",icon:Re,color:"#F59E0B"})]}),e.jsx(gs,{entries:a.audit})]}),c==="users"&&e.jsx(ns,{}),c==="analytics"&&e.jsx(es,{data:b?{costBreakdown:b}:{}}),c==="governance"&&e.jsx(cs,{}),c==="audit"&&e.jsx(ts,{onFetch:o}),c==="compliance"&&e.jsx(ms,{})]})}export{Ms as default};
@@ -0,0 +1,11 @@
1
+ import{c as l,j as s}from"./index-Cz7q1bvC.js";/**
2
+ * @license lucide-react v0.577.0 - ISC
3
+ *
4
+ * This source code is licensed under the ISC license.
5
+ * See the LICENSE file in the root directory of this source tree.
6
+ */const x=[["path",{d:"m22 7-8.991 5.727a2 2 0 0 1-2.009 0L2 7",key:"132q7q"}],["rect",{x:"2",y:"4",width:"20",height:"16",rx:"2",key:"izxlao"}]],m=l("mail",x);/**
7
+ * @license lucide-react v0.577.0 - ISC
8
+ *
9
+ * This source code is licensed under the ISC license.
10
+ * See the LICENSE file in the root directory of this source tree.
11
+ */const d=[["path",{d:"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2",key:"1yyitq"}],["circle",{cx:"9",cy:"7",r:"4",key:"nufk8"}],["line",{x1:"19",x2:"19",y1:"8",y2:"14",key:"1bvyxn"}],["line",{x1:"22",x2:"16",y1:"11",y2:"11",key:"1shjgl"}]],p=l("user-plus",d),b={sm:{container:"w-6 h-6",text:"text-[10px]",dot:"w-2 h-2 -bottom-0.5 -right-0.5"},md:{container:"w-8 h-8",text:"text-xs",dot:"w-2.5 h-2.5 -bottom-0.5 -right-0.5"},lg:{container:"w-11 h-11",text:"text-sm",dot:"w-3 h-3 -bottom-0.5 -right-0.5"}},g={online:"bg-[#1FC5A8]",offline:"bg-[#939084]",away:"bg-[#E5A940]"};function u(e){let t=0;for(let n=0;n<e.length;n++)t=e.charCodeAt(n)+((t<<5)-t);return Math.abs(t)}const i=["bg-[#553DE9]","bg-[#D63384]","bg-[#1FC5A8]","bg-[#E5A940]","bg-[#3B82F6]","bg-[#8B5CF6]","bg-[#EC4899]","bg-[#06B6D4]"];function f(e){var n;const t=e.trim().split(/\s+/);return t.length>=2?(t[0][0]+t[t.length-1][0]).toUpperCase():(((n=t[0])==null?void 0:n[0])||"?").toUpperCase()}function A({name:e,image:t,size:n="md",status:r,className:a=""}){const o=b[n],c=i[u(e)%i.length],h=f(e);return s.jsxs("span",{className:`relative inline-flex flex-shrink-0 ${a}`,children:[t?s.jsx("img",{src:t,alt:e,className:`${o.container} rounded-full object-cover`}):s.jsx("span",{className:`${o.container} ${c} rounded-full inline-flex items-center justify-center text-white font-semibold ${o.text}`,title:e,children:h}),r&&s.jsx("span",{className:`absolute ${o.dot} ${g[r]} rounded-full border-2 border-white dark:border-[#1A1A1E]`,title:r})]})}export{A,m as M,p as U};
@@ -1 +1 @@
1
- import{j as e}from"./index-DvZ0Kk2x.js";import{C as r}from"./clock-mlGCFq8l.js";import{C as a}from"./circle-alert-Da74VO8P.js";import{C as l}from"./check-ikfylPst.js";const i={completed:"bg-[#1FC5A8]/10 text-[#1FC5A8]",running:"bg-[#553DE9]/10 text-[#553DE9]",failed:"bg-[#C45B5B]/10 text-[#C45B5B]",started:"bg-[#D4A03C]/10 text-[#D4A03C]",empty:"bg-[#F8F4F0] text-[#6B6960]",version:"bg-[#553DE9]/10 text-[#553DE9]"};function o({status:t}){switch(t){case"completed":return e.jsx(l,{size:12});case"running":return e.jsxs("span",{className:"relative flex h-2 w-2",children:[e.jsx("span",{className:"animate-ping motion-reduce:animate-none absolute inline-flex h-full w-full rounded-full bg-current opacity-75"}),e.jsx("span",{className:"relative inline-flex rounded-full h-2 w-2 bg-current"})]});case"failed":return e.jsx(a,{size:12});case"started":return e.jsx(r,{size:12});default:return null}}function f({status:t,children:n,className:s=""}){return e.jsxs("span",{className:["inline-flex items-center gap-1 rounded-btn px-2.5 py-0.5 text-xs font-semibold",i[t],s].filter(Boolean).join(" "),children:[e.jsx(o,{status:t}),n]})}export{f as B};
1
+ import{j as e}from"./index-Cz7q1bvC.js";import{C as r}from"./clock-C8p2e4NI.js";import{C as a}from"./circle-alert-CSB88nEs.js";import{C as l}from"./check-C_9Nx7kb.js";const i={completed:"bg-[#1FC5A8]/10 text-[#1FC5A8]",running:"bg-[#553DE9]/10 text-[#553DE9]",failed:"bg-[#C45B5B]/10 text-[#C45B5B]",started:"bg-[#D4A03C]/10 text-[#D4A03C]",empty:"bg-[#F8F4F0] text-[#6B6960]",version:"bg-[#553DE9]/10 text-[#553DE9]"};function o({status:t}){switch(t){case"completed":return e.jsx(l,{size:12});case"running":return e.jsxs("span",{className:"relative flex h-2 w-2",children:[e.jsx("span",{className:"animate-ping motion-reduce:animate-none absolute inline-flex h-full w-full rounded-full bg-current opacity-75"}),e.jsx("span",{className:"relative inline-flex rounded-full h-2 w-2 bg-current"})]});case"failed":return e.jsx(a,{size:12});case"started":return e.jsx(r,{size:12});default:return null}}function f({status:t,children:n,className:s=""}){return e.jsxs("span",{className:["inline-flex items-center gap-1 rounded-btn px-2.5 py-0.5 text-xs font-semibold",i[t],s].filter(Boolean).join(" "),children:[e.jsx(o,{status:t}),n]})}export{f as B};
@@ -1 +1 @@
1
- import{r as p,j as t}from"./index-DvZ0Kk2x.js";const m={primary:"bg-[#553DE9] text-white hover:bg-[#4432c4] shadow-button rounded-btn",secondary:"border border-[#553DE9] text-[#553DE9] hover:bg-[#E8E4FD] bg-transparent rounded-btn",ghost:"text-[#36342E] hover:bg-[#F8F4F0] rounded-btn",danger:"bg-[#C45B5B]/10 text-[#C45B5B] border border-[#C45B5B]/20 hover:bg-[#C45B5B]/20 rounded-btn"},b={sm:"px-3 py-1.5 text-xs",md:"px-4 py-2 text-sm",lg:"px-6 py-3 text-base"},u={sm:14,md:16,lg:18};function h({size:e}){return t.jsxs("svg",{className:"animate-spin",width:e,height:e,viewBox:"0 0 24 24",fill:"none",children:[t.jsx("circle",{className:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"4"}),t.jsx("path",{className:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"})]})}const B=p.forwardRef(({variant:e="primary",size:o="md",icon:n,iconRight:i,loading:r=!1,disabled:a,className:c="",children:l,...x},d)=>{const s=u[o];return t.jsxs("button",{ref:d,disabled:a||r,className:["inline-flex items-center justify-center gap-2 font-medium transition-colors",m[e],b[o],(a||r)&&"opacity-60 cursor-not-allowed",c].filter(Boolean).join(" "),...x,children:[r?t.jsx(h,{size:s}):n?t.jsx(n,{size:s}):null,l,i&&!r&&t.jsx(i,{size:s})]})});B.displayName="Button";export{B};
1
+ import{r as p,j as t}from"./index-Cz7q1bvC.js";const m={primary:"bg-[#553DE9] text-white hover:bg-[#4432c4] shadow-button rounded-btn",secondary:"border border-[#553DE9] text-[#553DE9] hover:bg-[#E8E4FD] bg-transparent rounded-btn",ghost:"text-[#36342E] hover:bg-[#F8F4F0] rounded-btn",danger:"bg-[#C45B5B]/10 text-[#C45B5B] border border-[#C45B5B]/20 hover:bg-[#C45B5B]/20 rounded-btn"},b={sm:"px-3 py-1.5 text-xs",md:"px-4 py-2 text-sm",lg:"px-6 py-3 text-base"},u={sm:14,md:16,lg:18};function h({size:e}){return t.jsxs("svg",{className:"animate-spin",width:e,height:e,viewBox:"0 0 24 24",fill:"none",children:[t.jsx("circle",{className:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"4"}),t.jsx("path",{className:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"})]})}const B=p.forwardRef(({variant:e="primary",size:o="md",icon:n,iconRight:i,loading:r=!1,disabled:a,className:c="",children:l,...x},d)=>{const s=u[o];return t.jsxs("button",{ref:d,disabled:a||r,className:["inline-flex items-center justify-center gap-2 font-medium transition-colors",m[e],b[o],(a||r)&&"opacity-60 cursor-not-allowed",c].filter(Boolean).join(" "),...x,children:[r?t.jsx(h,{size:s}):n?t.jsx(n,{size:s}):null,l,i&&!r&&t.jsx(i,{size:s})]})});B.displayName="Button";export{B};
@@ -0,0 +1,47 @@
1
+ import{c as $,r as l,j as e,G as fe,Q as ge,F as be,h as ke,T as G,Z as ve,a as j,S as ye,V as je,X as Ne,P as ae,i as we,g as Se,l as Ce,Y as Re,N as I,J as Me,K as Ee,O as $e,u as Te}from"./index-Cz7q1bvC.js";import{P as K,S as Pe,E as Ae}from"./ErrorBoundary-BRABI-BT.js";import{C as ze,F as Ie,M as _e,H as De,a as Le,G as Fe,T as Oe}from"./thumbs-up-BrjZ6QuV.js";import{C as re}from"./check-C_9Nx7kb.js";import{C as He}from"./clock-C8p2e4NI.js";import{D as Be}from"./dollar-sign-DSu6n3K3.js";import{U as qe}from"./upload-B9DFBcPG.js";import{L as W}from"./loader-circle-B3HspjKR.js";/**
2
+ * @license lucide-react v0.577.0 - ISC
3
+ *
4
+ * This source code is licensed under the ISC license.
5
+ * See the LICENSE file in the root directory of this source tree.
6
+ */const Ue=[["path",{d:"M10.1 2.182a10 10 0 0 1 3.8 0",key:"5ilxe3"}],["path",{d:"M13.9 21.818a10 10 0 0 1-3.8 0",key:"11zvb9"}],["path",{d:"M17.609 3.721a10 10 0 0 1 2.69 2.7",key:"1iw5b2"}],["path",{d:"M2.182 13.9a10 10 0 0 1 0-3.8",key:"c0bmvh"}],["path",{d:"M20.279 17.609a10 10 0 0 1-2.7 2.69",key:"1ruxm7"}],["path",{d:"M21.818 10.1a10 10 0 0 1 0 3.8",key:"qkgqxc"}],["path",{d:"M3.721 6.391a10 10 0 0 1 2.7-2.69",key:"1mcia2"}],["path",{d:"M6.391 20.279a10 10 0 0 1-2.69-2.7",key:"1fvljs"}]],Ge=$("circle-dashed",Ue);/**
7
+ * @license lucide-react v0.577.0 - ISC
8
+ *
9
+ * This source code is licensed under the ISC license.
10
+ * See the LICENSE file in the root directory of this source tree.
11
+ */const Ke=[["path",{d:"M20 14V8a2.4 2.4 0 0 0-.706-1.706l-3.588-3.588A2.4 2.4 0 0 0 14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12",key:"l9p8hp"}],["path",{d:"M14 2v5a1 1 0 0 0 1 1h5",key:"wfsgrz"}],["path",{d:"M14 18h6",key:"1m8k6r"}]],We=$("file-minus-corner",Ke);/**
12
+ * @license lucide-react v0.577.0 - ISC
13
+ *
14
+ * This source code is licensed under the ISC license.
15
+ * See the LICENSE file in the root directory of this source tree.
16
+ */const Ve=[["path",{d:"M12.659 22H18a2 2 0 0 0 2-2V8a2.4 2.4 0 0 0-.706-1.706l-3.588-3.588A2.4 2.4 0 0 0 14 2H6a2 2 0 0 0-2 2v9.34",key:"o6klzx"}],["path",{d:"M14 2v5a1 1 0 0 0 1 1h5",key:"wfsgrz"}],["path",{d:"M10.378 12.622a1 1 0 0 1 3 3.003L8.36 20.637a2 2 0 0 1-.854.506l-2.867.837a.5.5 0 0 1-.62-.62l.836-2.869a2 2 0 0 1 .506-.853z",key:"zhnas1"}]],q=$("file-pen",Ve);/**
17
+ * @license lucide-react v0.577.0 - ISC
18
+ *
19
+ * This source code is licensed under the ISC license.
20
+ * See the LICENSE file in the root directory of this source tree.
21
+ */const Qe=[["path",{d:"M11.35 22H6a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.706.706l3.588 3.588A2.4 2.4 0 0 1 20 8v5.35",key:"17jvcc"}],["path",{d:"M14 2v5a1 1 0 0 0 1 1h5",key:"wfsgrz"}],["path",{d:"M14 19h6",key:"bvotb8"}],["path",{d:"M17 16v6",key:"18yu1i"}]],Ye=$("file-plus-corner",Qe);/**
22
+ * @license lucide-react v0.577.0 - ISC
23
+ *
24
+ * This source code is licensed under the ISC license.
25
+ * See the LICENSE file in the root directory of this source tree.
26
+ */const Xe=[["path",{d:"M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z",key:"18887p"}],["path",{d:"M10 15h4",key:"192ueg"}],["path",{d:"M10 9h4",key:"u4k05v"}],["path",{d:"M12 7v4",key:"xawao1"}]],Ze=$("message-square-diff",Xe);/**
27
+ * @license lucide-react v0.577.0 - ISC
28
+ *
29
+ * This source code is licensed under the ISC license.
30
+ * See the LICENSE file in the root directory of this source tree.
31
+ */const Je=[["path",{d:"m17 2 4 4-4 4",key:"nntrym"}],["path",{d:"M3 11v-1a4 4 0 0 1 4-4h14",key:"84bu3i"}],["path",{d:"m7 22-4-4 4-4",key:"1wqhfi"}],["path",{d:"M21 13v1a4 4 0 0 1-4 4H3",key:"1rx37r"}]],et=$("repeat",Je);/**
32
+ * @license lucide-react v0.577.0 - ISC
33
+ *
34
+ * This source code is licensed under the ISC license.
35
+ * See the LICENSE file in the root directory of this source tree.
36
+ */const tt=[["path",{d:"M9 14 4 9l5-5",key:"102s5s"}],["path",{d:"M4 9h10.5a5.5 5.5 0 0 1 5.5 5.5a5.5 5.5 0 0 1-5.5 5.5H11",key:"f3b9sd"}]],st=$("undo-2",tt);/**
37
+ * @license lucide-react v0.577.0 - ISC
38
+ *
39
+ * This source code is licensed under the ISC license.
40
+ * See the LICENSE file in the root directory of this source tree.
41
+ */const nt=[["path",{d:"M12 20h.01",key:"zekei9"}],["path",{d:"M8.5 16.429a5 5 0 0 1 7 0",key:"1bycff"}],["path",{d:"M5 12.859a10 10 0 0 1 5.17-2.69",key:"1dl1wf"}],["path",{d:"M19 12.859a10 10 0 0 0-2.007-1.523",key:"4k23kn"}],["path",{d:"M2 8.82a15 15 0 0 1 4.177-2.643",key:"1grhjp"}],["path",{d:"M22 8.82a15 15 0 0 0-11.288-3.764",key:"z3jwby"}],["path",{d:"m2 2 20 20",key:"1ooewy"}]],V=$("wifi-off",nt);function at(s){const t=new Map;for(const n of s??[]){const a=t.get(n.path);if(!a){t.set(n.path,{path:n.path,status:n.status,staged:n.staged,partiallyStaged:!1});continue}t.set(n.path,{path:n.path,status:a.status==="modified"?n.status:a.status,staged:a.staged||n.staged,partiallyStaged:a.staged!==n.staged})}return Array.from(t.values()).sort((n,a)=>n.path.localeCompare(a.path))}function Q(s){return(s??"").replace(/\/+$/,"")}function rt(s,t){if(!(s!=null&&s.running)||!t)return!1;const n=Q(s.projectDir),a=Q(t.path);return n.length>0&&n===a}function it(s){const t=(s??"").trim();if(!t)return{goal:null,criteria:[]};const n=t.split(`
42
+ `);let a=null;for(const d of n){const r=d.trim();if(!r)continue;const o=r.match(/^#{1,3}\s+(.*)$/);if(o){a=o[1].trim();break}if(!r.startsWith("---")){a=r.length>200?`${r.slice(0,200)}...`:r;break}}const i=[];let x=!1;for(const d of n){const r=d.trim(),o=r.match(/^#{1,6}\s+(.*)$/);if(o){x=/acceptance|success criteria|definition of done|requirements/i.test(o[1]);continue}if(!x)continue;const u=r.match(/^[-*]\s+(?:\[[ xX]\]\s*)?(.+)$/);u&&i.push(u[1].trim())}return{goal:a,criteria:i.slice(0,12)}}function ot({detail:s,status:t,git:n,isLive:a}){var o;const{goal:i,criteria:x}=l.useMemo(()=>it(s==null?void 0:s.prd),[s==null?void 0:s.prd]),[d,r]=l.useState(!1);return e.jsxs("header",{"aria-label":"Task",className:"border-b border-border dark:border-dark-border bg-card dark:bg-dark-card px-4 py-4 sm:px-6",children:[e.jsx("div",{className:"flex flex-wrap items-start justify-between gap-3",children:e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("p",{className:"text-small uppercase tracking-wide text-muted-accessible dark:text-dark-muted",children:"Goal"}),e.jsx("h1",{className:"mt-1 font-heading text-h2 leading-tight text-ink dark:text-dark-ink",children:i??"No spec recorded for this session"}),!i&&e.jsx("p",{className:"mt-1 text-caption text-muted-accessible dark:text-dark-muted",children:"A PRD.md in the project directory would appear here."})]})}),e.jsxs("dl",{className:"mt-3 flex flex-wrap items-center gap-x-5 gap-y-2 text-caption text-muted-accessible dark:text-dark-muted",children:[(n==null?void 0:n.branch)&&e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx(fe,{size:14,"aria-hidden":"true"}),e.jsx("dt",{className:"sr-only",children:"Branch"}),e.jsx("dd",{className:"font-mono",children:n.branch})]}),a&&(t==null?void 0:t.provider)&&e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx(ge,{size:14,"aria-hidden":"true"}),e.jsx("dt",{className:"sr-only",children:"Provider"}),e.jsx("dd",{children:t.provider})]}),(s==null?void 0:s.path)&&e.jsxs("div",{className:"flex min-w-0 items-center gap-1.5",children:[e.jsx(be,{size:14,"aria-hidden":"true"}),e.jsx("dt",{className:"sr-only",children:"Project directory"}),e.jsx("dd",{className:"truncate font-mono",title:s.path,children:s.path})]})]}),e.jsxs("section",{"aria-label":"Acceptance criteria",className:"mt-4",children:[e.jsx("h2",{className:"text-small uppercase tracking-wide text-muted-accessible dark:text-dark-muted",children:"Acceptance criteria"}),x.length>0?e.jsx("ul",{className:"mt-2 space-y-1.5",children:x.map(u=>e.jsxs("li",{className:"flex gap-2 text-caption text-secondary dark:text-dark-ink",children:[e.jsx("span",{"aria-hidden":"true",className:"mt-1.5 h-1.5 w-1.5 shrink-0 rounded-full bg-primary"}),e.jsx("span",{children:u})]},u))}):e.jsx("p",{className:"mt-2 text-caption text-muted-accessible dark:text-dark-muted",children:"None stated in the spec. Nothing here is inferred, so this run has no declared pass condition beyond its quality gates."})]}),((o=s==null?void 0:s.prd)==null?void 0:o.trim())&&e.jsxs("div",{className:"mt-3",children:[e.jsxs("button",{type:"button",onClick:()=>r(u=>!u),"aria-expanded":d,className:"inline-flex items-center gap-1.5 rounded-btn px-2 py-1 text-small text-primary transition-colors hover:bg-primary/5 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary",children:[e.jsx(ke,{size:14,"aria-hidden":"true",className:`transition-transform motion-reduce:transition-none ${d?"rotate-180":""}`}),d?"Hide full spec":"Read full spec"]}),d&&e.jsx("pre",{className:"mt-2 max-h-80 overflow-auto rounded-card border border-border bg-hover p-3 font-mono text-xs leading-relaxed text-secondary dark:border-dark-border dark:bg-dark-hover dark:text-dark-ink",children:s.prd})]})]})}const ie=["understanding","planning","editing","testing","review","pr-ready"],Y={"not-started":"Not started",understanding:"Understanding",planning:"Planning",editing:"Editing",testing:"Testing",review:"Review","pr-ready":"PR ready",failed:"Failed",unknown:"Unknown"},X={"not-started":"No run has been recorded for this session.",understanding:"Reading the spec and the existing code.",planning:"Deciding what to change and in what order.",editing:"Writing code.",testing:"Running checks against what it wrote.",review:"Reflecting on the result and reviewing its own changes.","pr-ready":"Work finished. Ready for your review.",failed:"The run ended without completing.",unknown:"The engine reported a phase this view does not recognise."},Z={idle:"not-started",starting:"understanding",BOOTSTRAP:"understanding",REASON:"planning",ACT:"editing",VERIFY:"testing",REFLECT:"review",BUILDING:"editing",COMPLETED:"pr-ready",FAILED:"failed",UNKNOWN:"unknown"};function U(s){const t=(s??"").trim();if(!t)return{display:"not-started",raw:"",recognised:!0};const n=Z[t];if(n)return{display:n,raw:t,recognised:!0};const a=Z[t.toUpperCase()];return a?{display:a,raw:t,recognised:!0}:{display:"unknown",raw:t,recognised:!1}}function lt(s){return ie.indexOf(s)}function dt({state:s,view:t}){return s==="active"?t==="paused"?e.jsx(K,{size:16,"aria-hidden":"true"}):t==="failed"?e.jsx(G,{size:16,"aria-hidden":"true"}):e.jsxs("span",{className:"relative flex h-4 w-4 items-center justify-center",children:[t==="running"&&e.jsx("span",{className:"absolute inline-flex h-4 w-4 animate-ping rounded-full bg-current opacity-40 motion-reduce:hidden"}),e.jsx(ze,{size:16,"aria-hidden":"true",className:"relative"})]}):s==="done"?e.jsx(re,{size:16,"aria-hidden":"true"}):e.jsx(Ge,{size:16,"aria-hidden":"true"})}function ct({phase:s,view:t,isLive:n,iteration:a}){const i=lt(s.display),x=s.display==="failed"||s.display==="pr-ready";function d(r,o){return o===i?"active":s.display==="pr-ready"?"done":n&&o<i?"ahead":!n&&i>=0&&o<i?"done":"ahead"}return e.jsxs("section",{"aria-label":"Phase timeline",className:"p-4 sm:p-5",children:[e.jsxs("div",{className:"flex items-baseline justify-between gap-2",children:[e.jsx("h2",{className:"text-small uppercase tracking-wide text-muted-accessible dark:text-dark-muted",children:"Progress"}),!n&&e.jsx("span",{className:"text-small text-muted-accessible dark:text-dark-muted",children:"Historical"})]}),e.jsx("p",{"aria-live":"polite",className:"sr-only",children:`Phase: ${Y[s.display]}`}),e.jsx("ol",{className:"mt-3 space-y-0.5",children:ie.map((r,o)=>{const u=d(r,o),m=u==="active";return e.jsxs("li",{"aria-current":m?"step":void 0,className:["flex gap-3 rounded-btn px-2 py-2 transition-colors motion-reduce:transition-none",m?"bg-primary/5 dark:bg-primary/10":""].join(" "),children:[e.jsx("span",{className:["mt-0.5 shrink-0",m&&t==="failed"?"text-danger":m?"text-primary":u==="done"?"text-success":"text-muted-accessible dark:text-dark-muted"].join(" "),children:e.jsx(dt,{state:u,view:t})}),e.jsxs("span",{className:"min-w-0",children:[e.jsx("span",{className:["block text-caption",m?"font-semibold text-ink dark:text-dark-ink":u==="done"?"text-secondary dark:text-dark-ink":"text-muted-accessible dark:text-dark-muted"].join(" "),children:Y[r]}),m&&e.jsx("span",{className:"mt-0.5 block text-small text-muted-accessible dark:text-dark-muted",children:X[r]})]})]},r)})}),s.display==="failed"&&e.jsx("p",{className:"mt-2 rounded-btn bg-danger/10 px-2 py-2 text-caption text-danger",children:X.failed}),!s.recognised&&e.jsxs("p",{className:"mt-2 rounded-btn bg-warning/10 px-2 py-2 text-caption text-ink dark:text-dark-ink",children:["The engine reported phase"," ",e.jsx("code",{className:"font-mono font-semibold",children:s.raw}),", which this view does not recognise. Shown verbatim rather than guessed at."]}),n&&!x&&typeof a=="number"&&a>0&&e.jsxs("p",{className:"mt-3 text-small text-muted-accessible dark:text-dark-muted",children:["Iteration ",a,". Phases repeat each iteration, so this is a cycle, not a countdown."]})]})}function J(s){if(s<60)return`${s}s`;const t=Math.floor(s/60),n=s%60;return t<60?`${t}m ${n}s`:`${Math.floor(t/60)}h ${t%60}m`}function L({icon:s,label:t,value:n,note:a,muted:i}){return e.jsxs("div",{className:"min-w-0",children:[e.jsxs("dt",{className:"flex items-center gap-1.5 text-small uppercase tracking-wide text-muted-accessible dark:text-dark-muted",children:[e.jsx(s,{size:13,"aria-hidden":!0}),t]}),e.jsx("dd",{className:["mt-1 font-mono text-h3 tabular-nums",i?"text-muted-accessible dark:text-dark-muted":"text-ink dark:text-dark-ink"].join(" "),children:n}),a&&e.jsx("p",{className:"mt-0.5 text-small text-muted-accessible dark:text-dark-muted",children:a})]})}function ut({status:s,isLive:t,elapsedSeconds:n,timeToFirstSignal:a}){const i=(s==null?void 0:s.iteration)??0,x=typeof(s==null?void 0:s.cost)=="number"&&s.cost>0?s.cost:null;return e.jsxs("section",{"aria-label":"Run metrics",className:"p-4 sm:p-5",children:[e.jsx("h2",{className:"text-small uppercase tracking-wide text-muted-accessible dark:text-dark-muted",children:"Metrics"}),e.jsxs("dl",{className:"mt-3 grid grid-cols-2 gap-x-4 gap-y-4 lg:grid-cols-2",children:[e.jsx(L,{icon:He,label:"Elapsed",value:n!==null?J(n):"--",note:t?void 0:"Only measured while a run is live",muted:n===null}),e.jsx(L,{icon:ve,label:"First signal",value:a!==null?J(a):"--",note:a!==null?"Observed since this view opened":t?"Not yet observed in this view":"Not recorded",muted:a===null}),e.jsx(L,{icon:et,label:"Iteration",value:t&&i>0?String(i):"--",note:t&&i>0?void 0:"Not reported",muted:!t||i<=0}),e.jsx(L,{icon:Be,label:"Cost",value:x!==null?`$${x.toFixed(2)}`:"--",note:x!==null?void 0:"Not recorded",muted:x===null})]})]})}const xt={added:Ye,deleted:We,modified:q,renamed:q,untracked:Ie},mt={added:"text-success",deleted:"text-danger",modified:"text-info",renamed:"text-info",untracked:"text-warning"};function ht({sessionId:s,files:t,clean:n}){const[a,i]=l.useState(null),[x,d]=l.useState(null),[r,o]=l.useState(!1),[u,m]=l.useState(null),[g,w]=l.useState(0),v=l.useRef(null);l.useEffect(()=>{if(!a)return;let h=!1;return o(!0),m(null),d(null),j.getSessionFileContent(s,a).then(b=>!h&&d(b.content)).catch(b=>!h&&m(b instanceof Error?b.message:"Could not read this file")).finally(()=>!h&&o(!1)),()=>{h=!0}},[s,a]);function f(h){var R;if(t.length===0)return;let b=g;if(h.key==="ArrowDown")b=Math.min(g+1,t.length-1);else if(h.key==="ArrowUp")b=Math.max(g-1,0);else if(h.key==="Home")b=0;else if(h.key==="End")b=t.length-1;else if(h.key==="Enter"||h.key===" "){h.preventDefault(),i(t[g].path);return}else return;h.preventDefault(),w(b);const S=(R=v.current)==null?void 0:R.querySelectorAll("li > button")[b];S==null||S.focus()}return n&&t.length===0?e.jsxs("section",{"aria-label":"Changed files",className:"p-4 sm:p-5",children:[e.jsx("h2",{className:"text-small uppercase tracking-wide text-muted-accessible dark:text-dark-muted",children:"Changes"}),e.jsx("p",{className:"mt-3 text-caption text-muted-accessible dark:text-dark-muted",children:"The working tree is clean. Nothing has been changed in this session."})]}):e.jsxs("section",{"aria-label":"Changed files",className:"flex min-h-0 flex-col p-4 sm:p-5",children:[e.jsxs("div",{className:"flex items-baseline justify-between gap-2",children:[e.jsx("h2",{className:"text-small uppercase tracking-wide text-muted-accessible dark:text-dark-muted",children:"Changes"}),e.jsxs("span",{className:"text-small text-muted-accessible dark:text-dark-muted",children:[t.length," ",t.length===1?"file":"files"]})]}),e.jsxs("div",{className:"mt-3 grid min-h-0 flex-1 gap-4 lg:grid-cols-[minmax(0,18rem)_minmax(0,1fr)]",children:[e.jsx("ul",{ref:v,role:"listbox","aria-label":"Changed files",tabIndex:t.length?0:-1,onKeyDown:f,className:"max-h-72 space-y-0.5 overflow-y-auto lg:max-h-none",children:t.map((h,b)=>{const S=xt[h.status]??q,R=a===h.path;return e.jsx("li",{role:"option","aria-selected":R,children:e.jsxs("button",{type:"button",tabIndex:b===g?0:-1,onFocus:()=>w(b),onClick:()=>i(h.path),className:["flex w-full items-center gap-2 rounded-btn px-2 py-1.5 text-left transition-colors motion-reduce:transition-none",R?"bg-primary/10 text-ink dark:text-dark-ink":"text-secondary hover:bg-hover dark:text-dark-ink dark:hover:bg-dark-hover","focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-[-2px] focus-visible:outline-primary"].join(" "),children:[e.jsx("span",{className:mt[h.status]??"text-muted-accessible",children:e.jsx(S,{size:14})}),e.jsx("span",{className:"min-w-0 flex-1 truncate font-mono text-xs",title:h.path,children:h.path}),e.jsx("span",{className:"shrink-0 text-small text-muted-accessible dark:text-dark-muted",children:h.partiallyStaged?"partly staged":h.staged?"staged":""})]})},h.path)})}),e.jsxs("div",{className:"min-w-0 rounded-card border border-border bg-hover dark:border-dark-border dark:bg-dark-hover",children:[!a&&e.jsx("p",{className:"p-4 text-caption text-muted-accessible dark:text-dark-muted",children:"Select a file to read it. This shows the file as it stands now; a line-by-line diff against the previous revision is not served by this API."}),a&&r&&e.jsxs("p",{className:"p-4 text-caption text-muted-accessible dark:text-dark-muted",children:["Loading ",a,"..."]}),a&&u&&e.jsx("p",{className:"p-4 text-caption text-danger",children:u}),a&&x!==null&&e.jsx("pre",{className:"max-h-[28rem] overflow-auto p-3 font-mono text-xs leading-relaxed text-secondary dark:text-dark-ink",children:x})]})]})]})}const ee={pass:{Icon:re,cls:"text-success"},fail:{Icon:Ne,cls:"text-danger"},skip:{Icon:_e,cls:"text-muted-accessible"},pending:{Icon:je,cls:"text-warning"}},B={running:!1,returncode:null,output:null,error:null};function pt({sessionId:s,checklist:t}){const[n,a]=l.useState(B),[i,x]=l.useState(B);function d(o,u){const m=o==="tests"?a:x;m({...B,running:!0}),u().then(g=>m({running:!1,returncode:g.returncode,output:g.output,error:null})).catch(g=>m({running:!1,returncode:null,output:null,error:g instanceof Error?g.message:"Failed to run"}))}const r=!!(t&&t.items.length>0);return e.jsxs("section",{"aria-label":"Evidence",className:"p-4 sm:p-5",children:[e.jsxs("h2",{className:"flex items-center gap-1.5 text-small uppercase tracking-wide text-muted-accessible dark:text-dark-muted",children:[e.jsx(ye,{size:13,"aria-hidden":"true"}),"Evidence"]}),e.jsxs("div",{className:"mt-3",children:[e.jsx("h3",{className:"text-caption font-semibold text-ink dark:text-dark-ink",children:"Quality gates"}),r?e.jsxs(e.Fragment,{children:[e.jsxs("p",{className:"mt-1 text-small text-muted-accessible dark:text-dark-muted",children:[t.passed," passed, ",t.failed," failed,"," ",t.skipped," skipped, ",t.pending," pending"]}),e.jsx("ul",{className:"mt-2 space-y-1",children:t.items.map(o=>{const{Icon:u,cls:m}=ee[o.status]??ee.pending;return e.jsxs("li",{className:"flex items-start gap-2",children:[e.jsx("span",{className:`mt-0.5 shrink-0 ${m}`,children:e.jsx(u,{size:14,"aria-hidden":"true"})}),e.jsxs("span",{className:"min-w-0",children:[e.jsx("span",{className:"block text-caption text-secondary dark:text-dark-ink",children:o.label}),e.jsx("span",{className:"sr-only",children:o.status}),o.details&&e.jsx("span",{className:"block text-small text-muted-accessible dark:text-dark-muted",children:o.details})]})]},o.id)})})]}):e.jsx("p",{className:"mt-1 text-caption text-muted-accessible dark:text-dark-muted",children:"No gate results recorded. The engine writes these during a run; an empty file is not the same as a clean pass."})]}),e.jsxs("div",{className:"mt-5 space-y-3",children:[e.jsx("h3",{className:"text-caption font-semibold text-ink dark:text-dark-ink",children:"Checks"}),e.jsx(te,{name:"Generate tests (loki test)",state:n,describe:o=>o===0?{text:"Exit 0: test files were generated. No tests were run.",cls:"text-ink dark:text-dark-ink"}:{text:`Exit ${o}: no test files generated, or the command could not run. See the output.`,cls:"text-danger"},onRun:()=>d("tests",()=>j.testProject(s))}),e.jsx(te,{name:"Code review (loki review)",state:i,describe:(o,u)=>o!==0?{text:`Exit ${o}: findings reported, or the command could not run. See the output.`,cls:"text-danger"}:/No changes to review/i.test(u??"")?{text:"Exit 0: nothing was reviewed (no changes found).",cls:"text-muted-accessible dark:text-dark-muted"}:{text:"Exit 0: no high or critical findings reported.",cls:"text-success"},onRun:()=>d("review",()=>j.reviewProject(s))}),e.jsx("p",{className:"text-small text-muted-accessible dark:text-dark-muted",children:"Build, typecheck and lint are not exposed as separate endpoints by this API."})]})]})}function te({name:s,state:t,describe:n,onRun:a}){const i=t.returncode===null?null:n(t.returncode,t.output);return e.jsxs("div",{className:"rounded-card border border-border p-3 dark:border-dark-border",children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-caption text-ink dark:text-dark-ink",children:s}),e.jsx("p",{className:`text-small ${(i==null?void 0:i.cls)??"text-muted-accessible dark:text-dark-muted"}`,children:t.running?"Running...":t.error?t.error:(i==null?void 0:i.text)??"Not run"})]}),e.jsxs("button",{type:"button",onClick:a,disabled:t.running,className:"inline-flex items-center gap-1.5 rounded-btn border border-primary/30 px-2.5 py-1 text-small font-semibold text-primary transition-colors hover:bg-primary/5 disabled:cursor-not-allowed disabled:opacity-60 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary",children:[e.jsx(ae,{size:12,"aria-hidden":"true"}),t.returncode===null?"Run":"Re-run"]})]}),t.output&&e.jsx("pre",{className:"mt-2 max-h-48 overflow-auto rounded-btn bg-hover p-2 font-mono text-xs text-secondary dark:bg-dark-hover dark:text-dark-ink",children:t.output})]})}function ft(s,t,n){const a=[],i=(t==null?void 0:t.items.filter(r=>r.status==="fail"))??[];i.length>0&&a.push(`${i.length} quality gate(s) failed: ${i.map(r=>r.label).join(", ")}.`),(!t||t.items.length===0)&&a.push("No quality gate results were recorded, so nothing here is verified.");const x=(t==null?void 0:t.items.filter(r=>r.status==="pending"))??[];x.length>0&&a.push(`${x.length} gate(s) still pending.`),s.length>20&&a.push(`${s.length} files changed, which is a large surface to review.`);const d=s.filter(r=>r.status==="untracked").length;return d>0&&a.push(`${d} file(s) are untracked and would not be included in a commit.`),n.length===0&&a.push("No checkpoints were recorded, so there is nothing to roll back to."),a}function gt({sessionId:s,checkpoints:t,changedFiles:n,checklist:a,isLive:i,onRestored:x}){const[d,r]=l.useState(null),[o,u]=l.useState(!1),[m,g]=l.useState(null),w=ft(n,a,t);function v(f){u(!0),g(null),j.restoreCheckpoint(s,f.id).then(h=>{g(`Restored: ${h.description}`),r(null),x()}).catch(h=>g(h instanceof Error?h.message:"Restore failed")).finally(()=>u(!1))}return e.jsxs("section",{"aria-label":"Risk and rollback",className:"p-4 sm:p-5",children:[e.jsxs("h2",{className:"flex items-center gap-1.5 text-small uppercase tracking-wide text-muted-accessible dark:text-dark-muted",children:[e.jsx(G,{size:13,"aria-hidden":"true"}),"Risk"]}),w.length>0?e.jsx("ul",{className:"mt-3 space-y-1.5",children:w.map(f=>e.jsxs("li",{className:"flex gap-2 text-caption text-secondary dark:text-dark-ink",children:[e.jsx("span",{"aria-hidden":"true",className:"mt-1.5 h-1.5 w-1.5 shrink-0 rounded-full bg-warning"}),e.jsx("span",{children:f})]},f))}):e.jsx("p",{className:"mt-3 text-caption text-secondary dark:text-dark-ink",children:"Nothing flagged from what was recorded. That is not a guarantee of correctness, only that no recorded signal was negative."}),e.jsxs("div",{className:"mt-5",children:[e.jsxs("h3",{className:"flex items-center gap-1.5 text-caption font-semibold text-ink dark:text-dark-ink",children:[e.jsx(De,{size:14,"aria-hidden":"true"}),"Rollback"]}),t.length===0?e.jsx("p",{className:"mt-1 text-caption text-muted-accessible dark:text-dark-muted",children:"No checkpoints recorded for this session, so there is nothing to roll back to."}):e.jsx("ul",{className:"mt-2 space-y-1.5",children:t.map(f=>e.jsxs("li",{className:"flex flex-wrap items-center justify-between gap-2 rounded-card border border-border p-2.5 dark:border-dark-border",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("p",{className:"truncate text-caption text-ink dark:text-dark-ink",children:f.description}),e.jsxs("p",{className:"text-small text-muted-accessible dark:text-dark-muted",children:[f.timestamp||"no timestamp"," - iteration ",f.iteration??"--"," -"," ",f.files_changed??"--"," file(s)"]})]}),e.jsxs("button",{type:"button",onClick:()=>r(f),disabled:o||i,title:i?"Cannot roll back while a run is in progress":void 0,className:"inline-flex shrink-0 items-center gap-1.5 rounded-btn border border-danger/30 bg-danger/10 px-2.5 py-1 text-small font-semibold text-danger transition-colors hover:bg-danger/20 disabled:cursor-not-allowed disabled:opacity-60 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-danger",children:[e.jsx(st,{size:12,"aria-hidden":"true"}),"Roll back"]})]},f.id))}),i&&t.length>0&&e.jsx("p",{className:"mt-2 text-small text-muted-accessible dark:text-dark-muted",children:"Rollback is disabled while a run is in progress. Stop the run first."})]}),d&&e.jsxs("div",{role:"alertdialog","aria-modal":"true","aria-labelledby":"rollback-title",className:"mt-3 rounded-card border border-danger/30 bg-danger/5 p-3",children:[e.jsxs("p",{id:"rollback-title",className:"text-caption font-semibold text-ink dark:text-dark-ink",children:['Roll back to "',d.description,'"?']}),e.jsxs("p",{className:"mt-1 text-small text-secondary dark:text-dark-ink",children:["This overwrites files in the project directory with the snapshot taken at iteration ",d.iteration??"--",". Changes made since then and not checkpointed are lost."]}),e.jsxs("div",{className:"mt-3 flex gap-2",children:[e.jsx("button",{type:"button",autoFocus:!0,onClick:()=>v(d),disabled:o,className:"rounded-btn bg-danger px-3 py-1.5 text-small font-semibold text-white transition-colors hover:opacity-90 disabled:opacity-60 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-danger",children:o?"Restoring...":"Yes, roll back"}),e.jsx("button",{type:"button",onClick:()=>r(null),disabled:o,className:"rounded-btn px-3 py-1.5 text-small font-semibold text-secondary transition-colors hover:bg-hover dark:text-dark-ink dark:hover:bg-dark-hover focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary",children:"Cancel"})]})]}),m&&e.jsx("p",{role:"status",className:"mt-2 text-caption text-secondary dark:text-dark-ink",children:m})]})}function bt({sessionId:s,isLive:t,status:n,git:a,changedFiles:i,onChanged:x}){const[d,r]=l.useState(null),[o,u]=l.useState(null),[m,g]=l.useState(""),[w,v]=l.useState(null),[f,h]=l.useState(""),b=!!(n!=null&&n.paused),S=i.length>0,R=(a==null?void 0:a.ahead)??0,_=[{key:"pause",label:"Pause",icon:K,disabledReason:t?b?"Already paused":null:"No run in progress for this session",onRun:()=>j.pauseSession().then(c=>c.message??"Paused")},{key:"resume",label:"Resume",icon:ae,disabledReason:t?b?null:"The run is not paused":"No run in progress for this session",onRun:()=>j.resumeSession().then(c=>c.message??"Resumed")},{key:"stop",label:"Stop run",icon:Pe,danger:!0,disabledReason:t?null:"No run in progress for this session",onRun:()=>j.stopSession().then(c=>c.message??"Stopped")},{key:"commit",label:"Commit",icon:Le,disabledReason:S?null:"The working tree is clean",onRun:()=>j.git.commit(s,m.trim()||"Loki: apply changes").then(c=>`Committed ${c.hash.slice(0,7)}`)},{key:"push",label:"Push",icon:qe,disabledReason:R<=0?"Nothing to push: no commits ahead of the remote":null,onRun:()=>j.git.push(s).then(c=>c.message??"Pushed")},{key:"pr",label:"Open pull request",icon:Fe,disabledReason:!S&&R<=0?"Nothing to open a pull request for":m.trim()?null:"Enter a title first",onRun:()=>j.git.pr(s,m.trim(),"").then(c=>`Opened #${c.number}: ${c.url}`)}];function F(c){!c.onRun||c.disabledReason||(r(c.key),u(null),c.onRun().then(k=>{u(k),x()}).catch(k=>u(k instanceof Error?k.message:`${c.label} failed`)).finally(()=>r(null)))}function A(){const c=f.trim();c&&(r("preview"),v(null),j.previewChanges(s,c).then(k=>v(k.files.length===0?"No files would change.":`${k.files.length} file(s) would change: +${k.total_additions} / -${k.total_deletions}
43
+
44
+ ${k.files.map(M=>`${M.action.padEnd(7)} ${M.path} +${M.additions} -${M.deletions}`).join(`
45
+ `)}`)).catch(k=>v(k instanceof Error?k.message:"Preview failed")).finally(()=>r(null)))}return e.jsxs("section",{"aria-label":"Actions",className:"p-4 sm:p-5",children:[e.jsx("h2",{className:"text-small uppercase tracking-wide text-muted-accessible dark:text-dark-muted",children:"Actions"}),e.jsxs("label",{className:"mt-3 block",children:[e.jsx("span",{className:"text-small text-muted-accessible dark:text-dark-muted",children:"Commit / pull request title"}),e.jsx("input",{type:"text",value:m,onChange:c=>g(c.target.value),placeholder:"Describe the change",className:"mt-1 w-full rounded-btn border border-border bg-card px-2.5 py-1.5 text-caption text-ink placeholder:text-muted-accessible focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-[-1px] focus-visible:outline-primary dark:border-dark-border dark:bg-dark-card dark:text-dark-ink"})]}),e.jsx("div",{className:"mt-3 flex flex-wrap gap-2",children:_.map(c=>{const k=!!c.disabledReason||d!==null,M=c.icon;return e.jsxs("button",{type:"button",onClick:()=>F(c),disabled:k,"aria-describedby":c.disabledReason?`reason-${c.key}`:void 0,className:["inline-flex items-center gap-1.5 rounded-btn border px-3 py-1.5 text-small font-semibold transition-colors motion-reduce:transition-none",c.danger?"border-danger/30 bg-danger/10 text-danger hover:bg-danger/20":"border-primary/30 text-primary hover:bg-primary/5",k?"cursor-not-allowed opacity-60":"","focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary"].join(" "),children:[e.jsx(M,{size:13}),d===c.key?"Working...":c.label]},c.key)})}),e.jsx("ul",{className:"mt-2 space-y-0.5",children:_.filter(c=>c.disabledReason).map(c=>e.jsxs("li",{id:`reason-${c.key}`,className:"text-small text-muted-accessible dark:text-dark-muted",children:[c.label,": ",c.disabledReason,"."]},c.key))}),o&&e.jsx("p",{role:"status",className:"mt-3 break-words rounded-btn bg-hover px-2.5 py-2 text-caption text-secondary dark:bg-dark-hover dark:text-dark-ink",children:o}),e.jsxs("div",{className:"mt-5 border-t border-border pt-4 dark:border-dark-border",children:[e.jsxs("h3",{className:"flex items-center gap-1.5 text-caption font-semibold text-ink dark:text-dark-ink",children:[e.jsx(Ze,{size:14,"aria-hidden":"true"}),"Request a change"]}),e.jsx("p",{className:"mt-1 text-small text-muted-accessible dark:text-dark-muted",children:"Dry run only. This shows the diff a change would produce; it does not apply anything."}),e.jsx("textarea",{value:f,onChange:c=>h(c.target.value),rows:2,placeholder:"What should be different?",className:"mt-2 w-full rounded-btn border border-border bg-card px-2.5 py-1.5 text-caption text-ink placeholder:text-muted-accessible focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-[-1px] focus-visible:outline-primary dark:border-dark-border dark:bg-dark-card dark:text-dark-ink"}),e.jsx("button",{type:"button",onClick:A,disabled:!f.trim()||d!==null,className:"mt-2 inline-flex items-center gap-1.5 rounded-btn border border-primary/30 px-3 py-1.5 text-small font-semibold text-primary transition-colors hover:bg-primary/5 disabled:cursor-not-allowed disabled:opacity-60 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary",children:d==="preview"?"Previewing...":"Preview change"}),w&&e.jsx("pre",{className:"mt-2 max-h-56 overflow-auto rounded-btn bg-hover p-2 font-mono text-xs text-secondary dark:bg-dark-hover dark:text-dark-ink",children:w})]}),e.jsx("div",{className:"mt-5 border-t border-border pt-4 dark:border-dark-border",children:e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx(Oe,{size:14,"aria-hidden":"true",className:"mt-0.5 shrink-0 text-muted-accessible dark:text-dark-muted"}),e.jsxs("div",{children:[e.jsx("h3",{className:"text-caption font-semibold text-muted-accessible dark:text-dark-muted",children:"Approve"}),e.jsx("p",{className:"mt-1 text-small text-muted-accessible dark:text-dark-muted",children:"Not available. This API has no endpoint that approves a local run. Approval happens on the pull request once one is open."})]})]})})]})}function kt({logs:s,isLive:t}){const[n,a]=l.useState(!1),[i,x]=l.useState(!0),d=l.useRef(null);return l.useEffect(()=>{!n||!i||!d.current||(d.current.scrollTop=d.current.scrollHeight)},[s,n,i]),e.jsxs("section",{"aria-label":"Agent activity",className:"border-t border-border bg-card dark:border-dark-border dark:bg-dark-card",children:[e.jsx("h2",{children:e.jsxs("button",{type:"button",onClick:()=>a(r=>!r),"aria-expanded":n,"aria-controls":"chatter-body",className:"flex w-full items-center gap-2 px-4 py-2.5 text-left transition-colors hover:bg-hover dark:hover:bg-dark-hover sm:px-6 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-[-2px] focus-visible:outline-primary",children:[e.jsx(we,{size:14,"aria-hidden":"true",className:"text-muted-accessible dark:text-dark-muted"}),e.jsx("span",{className:"text-small font-semibold uppercase tracking-wide text-muted-accessible dark:text-dark-muted",children:"Agent activity"}),e.jsxs("span",{className:"text-small text-muted-accessible dark:text-dark-muted",children:[s.length," line",s.length===1?"":"s",t?", live":""]}),e.jsx(Se,{size:14,"aria-hidden":"true",className:`ml-auto text-muted-accessible transition-transform motion-reduce:transition-none dark:text-dark-muted ${n?"":"rotate-180"}`})]})}),n&&e.jsxs("div",{id:"chatter-body",children:[e.jsx("div",{className:"flex items-center justify-end px-4 pb-1 sm:px-6",children:e.jsxs("label",{className:"flex items-center gap-1.5 text-small text-muted-accessible dark:text-dark-muted",children:[e.jsx("input",{type:"checkbox",checked:i,onChange:r=>x(r.target.checked),className:"accent-primary"}),"Follow output"]})}),e.jsx("div",{ref:d,onScroll:r=>{const o=r.currentTarget;!(o.scrollHeight-o.scrollTop-o.clientHeight<24)&&i&&x(!1)},className:"max-h-64 overflow-auto bg-hover px-4 py-2 dark:bg-dark-hover sm:px-6",children:s.length===0?e.jsx("p",{className:"py-2 text-caption text-muted-accessible dark:text-dark-muted",children:"No output recorded."}):e.jsx("pre",{className:"whitespace-pre-wrap break-words font-mono text-xs leading-relaxed text-secondary dark:text-dark-ink",children:s.join(`
46
+ `)})})]})]})}const se={neutral:"bg-hover text-secondary dark:bg-dark-hover dark:text-dark-ink",running:"bg-primary/10 text-primary",warning:"bg-warning/10 text-ink dark:text-dark-ink",danger:"bg-danger/10 text-danger",success:"bg-success/10 text-success"};function vt({view:s,status:t,dataAgeMs:n,stale:a}){const i=t==null?void 0:t.exit_code,x=n!==null?Math.round(n/1e3):null,d=(()=>{switch(s){case"running":return{tone:"running",Icon:W,spin:!0,text:"Running",detail:(t==null?void 0:t.current_task)||void 0};case"paused":return{tone:"warning",Icon:K,text:"Paused",detail:"Resume to continue."};case"recovering":return{tone:"warning",Icon:W,spin:!0,text:"Starting up",detail:"The process is alive but has not written any state yet."};case"failed":return{tone:"danger",Icon:G,text:"Run failed",detail:typeof i=="number"?`Process exited with code ${i}.`:void 0};case"completed":return{tone:"success",Icon:Ce,text:"Run finished"};case"disconnected":return{tone:"warning",Icon:V,text:"Disconnected",detail:x!==null?`Showing the last state received ${x}s ago. Reconnecting.`:"Showing the last state received. Reconnecting."};default:return null}})();if(!d)return null;const{Icon:r}=d,o=a&&s!=="disconnected";return e.jsxs(e.Fragment,{children:[e.jsxs("div",{role:"status",className:`flex flex-wrap items-center gap-x-2 gap-y-1 px-4 py-2 sm:px-6 ${se[d.tone]}`,children:[e.jsx(r,{size:14,className:d.spin?"animate-spin motion-reduce:animate-none":void 0}),e.jsx("span",{className:"text-caption font-semibold",children:d.text}),d.detail&&e.jsx("span",{className:"text-caption opacity-80",children:d.detail})]}),o&&e.jsxs("div",{className:`flex flex-wrap items-center gap-x-2 px-4 py-1.5 sm:px-6 ${se.warning}`,children:[e.jsx(V,{size:13,"aria-hidden":"true"}),e.jsxs("span",{className:"text-small",children:["Live updates disconnected",x!==null?`; this is the state from ${x}s ago.`:"."," ","Reconnecting."]})]})]})}function yt({status:s}){const t=(s==null?void 0:s.last_output)??[];return t.length===0?null:e.jsxs("details",{className:"border-b border-border px-4 py-2 dark:border-dark-border sm:px-6",children:[e.jsx("summary",{className:"cursor-pointer text-small font-semibold text-danger",children:"Last output before exit"}),e.jsx("pre",{className:"mt-2 max-h-48 overflow-auto rounded-btn bg-hover p-2 font-mono text-xs text-secondary dark:bg-dark-hover dark:text-dark-ink",children:t.join(`
47
+ `)})]})}const jt=U(null);function Nt(s){const[t,n]=l.useState(null),[a,i]=l.useState(null),[x,d]=l.useState(null),[r,o]=l.useState(null),[u,m]=l.useState([]),[g,w]=l.useState([]),[v,f]=l.useState(!0),[h,b]=l.useState(null),[S,R]=l.useState(!0),[_,F]=l.useState(0),[A,c]=l.useState(()=>Date.now()),[k,M]=l.useState(null),z=l.useRef(null),oe=l.useRef(Date.now()),le=l.useCallback(()=>F(p=>p+1),[]);l.useEffect(()=>{if(!s)return;let p=!1;return f(!0),b(null),j.getSessionDetail(s).then(y=>{p||(n(y),w(y.logs??[]))}).catch(y=>{p||b(y instanceof Error?y.message:"Failed to load session")}).finally(()=>{p||f(!1)}),j.getStatus().then(y=>{p||(i(y),z.current=Date.now())}).catch(()=>{}),j.getChecklist().then(y=>!p&&d(y)).catch(()=>{}),j.git.status(s).then(y=>!p&&o(y)).catch(()=>{}),j.getCheckpoints(s).then(y=>!p&&m(y)).catch(()=>{}),()=>{p=!0}},[s,_]),l.useEffect(()=>{const p=new Re,y=p.on("state_update",E=>{var T;const N=E;N!=null&&N.status&&(i(N.status),z.current=Date.now()),(T=N==null?void 0:N.logs)!=null&&T.length&&w(he=>[...he,...N.logs.map(pe=>pe.message)].slice(-500))}),O=p.on("log",E=>{const N=E==null?void 0:E.line;N&&w(T=>[...T,N].slice(-500))}),H=p.on("connected",()=>R(!0)),D=p.on("disconnected",()=>R(!1));return p.connect(),()=>{y(),O(),H(),D(),p.disconnect()}},[]),l.useEffect(()=>{const p=setInterval(()=>c(Date.now()),1e3);return()=>clearInterval(p)},[]);const C=rt(a,t),de=l.useMemo(()=>U(C?a==null?void 0:a.phase:t==null?void 0:t.status),[C,a==null?void 0:a.phase,t==null?void 0:t.status]);l.useEffect(()=>{if(!C||k!==null)return;const p=(a==null?void 0:a.phase)??"";p&&p!=="idle"&&p!=="starting"&&p!=="BOOTSTRAP"&&M(Math.max(0,Math.round((Date.now()-oe.current)/1e3)))},[C,a==null?void 0:a.phase,k]);const ce=l.useMemo(()=>{var D,E,N;if(v)return"loading";if(C){if(a!=null&&a.paused)return"paused";const T=a==null?void 0:a.exit_code;return typeof T=="number"&&T!==0?"failed":(a==null?void 0:a.phase)==="starting"?"recovering":S?"running":"disconnected"}const p=((t==null?void 0:t.status)??"").toLowerCase();if(p==="failed")return"failed";if(p==="completed")return"completed";const y=!!((D=t==null?void 0:t.prd)!=null&&D.trim()),O=(((E=r==null?void 0:r.files)==null?void 0:E.length)??0)>0,H=(((N=t==null?void 0:t.files)==null?void 0:N.length)??0)>0;return!y&&!O&&!H?"empty":"completed"},[v,C,S,a,t,r]),ue=l.useMemo(()=>{if(!C||typeof(a==null?void 0:a.uptime)!="number")return null;const p=z.current?(A-z.current)/1e3:0;return Math.max(0,Math.round(a.uptime+p))},[C,a==null?void 0:a.uptime,A]),xe=l.useMemo(()=>!C||z.current===null?null:A-z.current,[C,A]),me=l.useMemo(()=>at(r==null?void 0:r.files),[r]);return{view:ce,detail:t,status:a,isLive:C,phase:de??jt,checklist:x,changedFiles:me,git:r,checkpoints:u,logs:g,elapsedSeconds:ue,timeToFirstSignal:k,dataAgeMs:xe,stale:C&&!S,error:h,reload:le}}const ne=[{keys:"g then 1",action:"Go to progress",id:"region-progress"},{keys:"g then 2",action:"Go to changes",id:"region-changes"},{keys:"g then 3",action:"Go to evidence",id:"region-evidence"},{keys:"g then 4",action:"Go to actions",id:"region-actions"},{keys:"?",action:"Toggle this list",id:""},{keys:"Esc",action:"Close this list",id:""}],P="rounded-card border border-border bg-card shadow-card dark:border-dark-border dark:bg-dark-card";function wt({sessionId:s,onClose:t}){var r,o;const n=Nt(s),[a,i]=l.useState(!1),x=l.useRef(!1);if(l.useEffect(()=>{function u(m){const g=m.target;if(!(g instanceof HTMLInputElement||g instanceof HTMLTextAreaElement||g!=null&&g.isContentEditable||m.metaKey||m.ctrlKey||m.altKey)){if(m.key==="Escape"){i(!1),x.current=!1;return}if(m.key==="?"){m.preventDefault(),i(v=>!v);return}if(m.key==="g"){x.current=!0;return}if(x.current){x.current=!1;const v=ne.find(f=>f.keys===`g then ${m.key}`);if(v!=null&&v.id){const f=document.getElementById(v.id);f&&(m.preventDefault(),f.scrollIntoView({behavior:"smooth",block:"start"}),f.focus({preventScroll:!0}))}}}}return window.addEventListener("keydown",u),()=>window.removeEventListener("keydown",u)},[]),n.error)return e.jsx("div",{className:"flex h-full items-center justify-center bg-background p-6 dark:bg-dark-bg",children:e.jsxs("div",{className:"text-center",children:[e.jsx("p",{className:"text-caption font-semibold text-danger",children:"Could not load this session"}),e.jsx("p",{className:"mt-1 text-small text-muted-accessible dark:text-dark-muted",children:n.error}),e.jsx("button",{type:"button",onClick:n.reload,className:"mt-4 rounded-btn border border-primary/30 px-4 py-2 text-caption font-semibold text-primary hover:bg-primary/5 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary",children:"Try again"})]})});if(n.view==="loading")return e.jsxs("div",{className:"h-full overflow-y-auto bg-background p-4 dark:bg-dark-bg sm:p-6",children:[e.jsx("span",{className:"sr-only",role:"status",children:"Loading the execution cockpit"}),e.jsx(I,{variant:"block",width:"60%",height:"32px"}),e.jsxs("div",{className:"mt-3 flex gap-3",children:[e.jsx(I,{variant:"text",width:"140px",height:"12px"}),e.jsx(I,{variant:"text",width:"180px",height:"12px"})]}),e.jsxs("div",{className:"mt-6 grid gap-4 xl:grid-cols-[minmax(0,22rem)_minmax(0,1fr)]",children:[e.jsx(I,{variant:"block",width:"100%",height:"260px"}),e.jsx(I,{variant:"block",width:"100%",height:"260px"})]})]});const d=n.view==="empty";return e.jsxs("div",{className:"flex h-full flex-col bg-background dark:bg-dark-bg",children:[e.jsxs("nav",{"aria-label":"Cockpit",className:"flex items-center justify-between gap-2 border-b border-border bg-card px-4 py-2 dark:border-dark-border dark:bg-dark-card sm:px-6",children:[e.jsxs("button",{type:"button",onClick:t,className:"inline-flex items-center gap-1.5 rounded-btn px-2 py-1 text-small font-semibold text-secondary transition-colors hover:bg-hover dark:text-dark-ink dark:hover:bg-dark-hover focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary",children:[e.jsx(Me,{size:14,"aria-hidden":"true"}),"Back"]}),e.jsxs("button",{type:"button",onClick:()=>i(u=>!u),"aria-expanded":a,className:"inline-flex items-center gap-1.5 rounded-btn px-2 py-1 text-small text-muted-accessible transition-colors hover:bg-hover dark:text-dark-muted dark:hover:bg-dark-hover focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary",children:[e.jsx(Ee,{size:14,"aria-hidden":"true"}),"Shortcuts"]})]}),a&&e.jsx("div",{className:"border-b border-border bg-hover px-4 py-3 dark:border-dark-border dark:bg-dark-hover sm:px-6",children:e.jsx("dl",{className:"flex flex-wrap gap-x-6 gap-y-1",children:ne.map(u=>e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("dt",{children:e.jsx("kbd",{className:"rounded-btn border border-border bg-card px-1.5 py-0.5 font-mono text-xs text-ink dark:border-dark-border dark:bg-dark-card dark:text-dark-ink",children:u.keys})}),e.jsx("dd",{className:"text-small text-muted-accessible dark:text-dark-muted",children:u.action})]},u.keys))})}),e.jsx(vt,{view:n.view,status:n.status,dataAgeMs:n.dataAgeMs,stale:n.stale}),n.view==="failed"&&e.jsx(yt,{status:n.status}),e.jsxs("div",{className:"min-h-0 flex-1 overflow-y-auto",children:[e.jsx(ot,{detail:n.detail,status:n.status,git:n.git,isLive:n.isLive}),d?e.jsx("div",{className:"p-6",children:e.jsxs("div",{className:`${P} p-6 text-center`,children:[e.jsx("h2",{className:"font-heading text-h3 text-ink dark:text-dark-ink",children:"Nothing recorded yet"}),e.jsx("p",{className:"mx-auto mt-2 max-w-md text-caption text-muted-accessible dark:text-dark-muted",children:"This session has no spec, no files and no changes. Once a run starts, its phases, changed files and evidence appear here."})]})}):e.jsxs("main",{className:"grid gap-4 p-4 sm:p-6 xl:grid-cols-[minmax(0,22rem)_minmax(0,1fr)] xl:items-start",children:[e.jsxs("div",{className:"grid gap-4 md:grid-cols-2 xl:grid-cols-1",children:[e.jsx("div",{id:"region-progress",tabIndex:-1,className:P,children:e.jsx(ct,{phase:n.phase,view:n.view,isLive:n.isLive,iteration:((r=n.status)==null?void 0:r.iteration)??void 0})}),e.jsx("div",{className:P,children:e.jsx(ut,{status:n.status,isLive:n.isLive,elapsedSeconds:n.elapsedSeconds,timeToFirstSignal:n.timeToFirstSignal})}),e.jsx("div",{className:`${P} md:col-span-2 xl:col-span-1`,children:e.jsx(gt,{sessionId:s,checkpoints:n.checkpoints,changedFiles:n.changedFiles,checklist:n.checklist,isLive:n.isLive,onRestored:n.reload})})]}),e.jsxs("div",{className:"grid min-w-0 gap-4",children:[e.jsx("div",{id:"region-changes",tabIndex:-1,className:`${P} min-w-0`,children:e.jsx(ht,{sessionId:s,files:n.changedFiles,clean:((o=n.git)==null?void 0:o.clean)??n.changedFiles.length===0})}),e.jsxs("div",{className:"grid gap-4 lg:grid-cols-2",children:[e.jsx("div",{id:"region-evidence",tabIndex:-1,className:`${P} min-w-0`,children:e.jsx(pt,{sessionId:s,checklist:n.checklist})}),e.jsx("div",{id:"region-actions",tabIndex:-1,className:`${P} min-w-0`,children:e.jsx(bt,{sessionId:s,isLive:n.isLive,status:n.status,git:n.git,changedFiles:n.changedFiles,onChanged:n.reload})})]})]})]})]}),e.jsx(kt,{logs:n.logs,isLive:n.isLive})]})}function At(){const{sessionId:s}=$e(),t=Te();return s?e.jsx("div",{className:"h-screen bg-background dark:bg-dark-bg",children:e.jsx(Ae,{name:"ExecutionCockpit",children:e.jsx(wt,{sessionId:s,onClose:()=>t(`/project/${s}`)})})}):e.jsx("div",{className:"flex h-screen items-center justify-center bg-background dark:bg-dark-bg",children:e.jsx("p",{className:"text-caption text-danger",children:"No session specified."})})}export{At as default};
@@ -0,0 +1 @@
1
+ import{r as o,j as e}from"./index-Cz7q1bvC.js";function f({value:l,prefix:t="",suffix:s=""}){const[u,n]=o.useState(0),c=o.useRef(0);return o.useEffect(()=>{const a=c.current,h=l-a;if(h===0)return;const i=600,d=performance.now();function r(b){const v=b-d,m=Math.min(v/i,1),N=1-Math.pow(1-m,3),p=Math.round(a+h*N);n(p),c.current=p,m<1&&requestAnimationFrame(r)}requestAnimationFrame(r)},[l]),e.jsxs("span",{className:"tabular-nums",children:[t,u.toLocaleString(),s]})}function g(){const[l,t]=o.useState(5),[s,u]=o.useState(30),[n,c]=o.useState(75),a=.4,i=Math.round(l*s*a*4.33),d=Math.round(i*n);return e.jsxs("div",{className:"bg-white border border-[#ECEAE3] rounded-xl p-6 shadow-sm",children:[e.jsx("h3",{className:"text-lg font-bold text-[#36342E] mb-1",children:"ROI Calculator"}),e.jsx("p",{className:"text-sm text-[#6B6960] mb-6",children:"Estimate how much your team could save with autonomous development."}),e.jsxs("div",{className:"space-y-5",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("label",{className:"text-sm font-medium text-[#36342E]",children:"Team size"}),e.jsxs("span",{className:"text-sm font-semibold text-[#553DE9] tabular-nums",children:[l," developers"]})]}),e.jsx("input",{type:"range",min:1,max:50,value:l,onChange:r=>t(Number(r.target.value)),className:"w-full h-2 bg-[#ECEAE3] rounded-full appearance-none cursor-pointer accent-[#553DE9]"}),e.jsxs("div",{className:"flex justify-between text-xs text-[#939084] mt-1",children:[e.jsx("span",{children:"1"}),e.jsx("span",{children:"50"})]})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("label",{className:"text-sm font-medium text-[#36342E]",children:"Hours coding per week"}),e.jsxs("span",{className:"text-sm font-semibold text-[#553DE9] tabular-nums",children:[s,"h"]})]}),e.jsx("input",{type:"range",min:5,max:60,value:s,onChange:r=>u(Number(r.target.value)),className:"w-full h-2 bg-[#ECEAE3] rounded-full appearance-none cursor-pointer accent-[#553DE9]"}),e.jsxs("div",{className:"flex justify-between text-xs text-[#939084] mt-1",children:[e.jsx("span",{children:"5h"}),e.jsx("span",{children:"60h"})]})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("label",{className:"text-sm font-medium text-[#36342E]",children:"Average hourly rate"}),e.jsxs("span",{className:"text-sm font-semibold text-[#553DE9] tabular-nums",children:["$",n,"/hr"]})]}),e.jsx("input",{type:"range",min:25,max:250,step:5,value:n,onChange:r=>c(Number(r.target.value)),className:"w-full h-2 bg-[#ECEAE3] rounded-full appearance-none cursor-pointer accent-[#553DE9]"}),e.jsxs("div",{className:"flex justify-between text-xs text-[#939084] mt-1",children:[e.jsx("span",{children:"$25"}),e.jsx("span",{children:"$250"})]})]})]}),e.jsxs("div",{className:"mt-6 pt-6 border-t border-[#ECEAE3]",children:[e.jsxs("div",{className:"grid grid-cols-2 gap-4 text-center",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-2xl font-bold text-[#553DE9]",children:e.jsx(f,{value:i,suffix:"h"})}),e.jsx("div",{className:"text-xs text-[#6B6960] mt-1",children:"Est. hours saved / month"})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-2xl font-bold text-[#1FC5A8]",children:e.jsx(f,{value:d,prefix:"$"})}),e.jsx("div",{className:"text-xs text-[#6B6960] mt-1",children:"Est. cost saved / month"})]})]}),e.jsxs("div",{className:"mt-4 p-3 rounded-lg bg-[#553DE9]/5 border border-[#553DE9]/10",children:[e.jsxs("p",{className:"text-sm text-[#36342E] text-center",children:["If Loki Mode saved ",Math.round(a*100),"% of coding time, your team could save"," ",e.jsxs("span",{className:"font-bold text-[#553DE9]",children:[i.toLocaleString()," hours"]})," ","and"," ",e.jsxs("span",{className:"font-bold text-[#1FC5A8]",children:["$",d.toLocaleString()]})," ","per month."]}),e.jsxs("p",{className:"mt-2 text-xs text-[#6B6960] text-center",children:["The ",Math.round(a*100),"% is an assumption, not a measurement. Model and API spend is not included."]})]})]})]})}const j=[{feature:"Claude (Opus/Sonnet/Haiku)",category:"AI Models",lokiMode:!0,boltNew:!1,replit:!1,lovable:!0},{feature:"GPT-4o / Codex",category:"AI Models",lokiMode:!0,boltNew:!0,replit:!0,lovable:!1},{feature:"Gemini",category:"AI Models",lokiMode:!0,boltNew:!1,replit:!0,lovable:!1},{feature:"5-provider auto-failover",category:"AI Models",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"9 automated quality gates",category:"Quality",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"Blind 3-reviewer code review",category:"Quality",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"Anti-sycophancy checks",category:"Quality",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"Automated test generation",category:"Quality",lokiMode:!0,boltNew:!1,replit:"Partial",lovable:!1},{feature:"Docker container generation",category:"Deployment",lokiMode:!0,boltNew:!1,replit:!0,lovable:!1},{feature:"CI/CD pipeline generation",category:"Deployment",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"One-click cloud deploy",category:"Deployment",lokiMode:"Planned",boltNew:!0,replit:!0,lovable:!0},{feature:"Self-hosted (your keys)",category:"Cost",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"Free tier available",category:"Cost",lokiMode:"Source-available (BUSL-1.1)",boltNew:!0,replit:!0,lovable:!0},{feature:"No vendor lock-in",category:"Cost",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"SSO / OIDC authentication",category:"Enterprise",lokiMode:!0,boltNew:!1,replit:!0,lovable:!1},{feature:"RBAC access control",category:"Enterprise",lokiMode:!0,boltNew:!1,replit:!0,lovable:!1},{feature:"Audit logging",category:"Enterprise",lokiMode:!0,boltNew:!1,replit:!0,lovable:!1},{feature:"Air-gapped deployment",category:"Enterprise",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1}];function y(){return e.jsx("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",className:"text-[#1FC5A8]",children:e.jsx("path",{d:"M20 6L9 17l-5-5",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round"})})}function w(){return e.jsx("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",className:"text-[#C45B5B]/40",children:e.jsx("path",{d:"M18 6L6 18M6 6l12 12",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})}function x({value:l}){return typeof l=="string"?e.jsx("span",{className:"text-xs text-[#6B6960] font-medium",children:l}):l?e.jsx(y,{}):e.jsx(w,{})}const k=[{title:"Full Autonomy",description:"Describe what you want. Loki Mode handles planning, coding, testing, and verification automatically.",icon:e.jsx("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",className:"text-[#553DE9]",children:e.jsx("path",{d:"M13 2L3 14h9l-1 8 10-12h-9l1-8z",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})},{title:"Production Quality",description:"9 quality gates, blind code review, and anti-sycophancy checks ensure code that actually works.",icon:e.jsx("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",className:"text-[#1FC5A8]",children:e.jsx("path",{d:"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})},{title:"Your Infrastructure",description:"Self-hosted, source-available (BUSL-1.1), no data leaves your network. Use your own API keys across 5 providers.",icon:e.jsxs("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",className:"text-[#2F71E3]",children:[e.jsx("rect",{x:"2",y:"2",width:"20",height:"8",rx:"2",stroke:"currentColor",strokeWidth:"2"}),e.jsx("rect",{x:"2",y:"14",width:"20",height:"8",rx:"2",stroke:"currentColor",strokeWidth:"2"}),e.jsx("circle",{cx:"6",cy:"6",r:"1",fill:"currentColor"}),e.jsx("circle",{cx:"6",cy:"18",r:"1",fill:"currentColor"})]})},{title:"Built for Teams",description:"Enterprise auth, RBAC, audit logs, and parallel workflows for teams of any size.",icon:e.jsxs("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",className:"text-[#E93D82]",children:[e.jsx("path",{d:"M17 21v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"}),e.jsx("circle",{cx:"9",cy:"7",r:"4",stroke:"currentColor",strokeWidth:"2"}),e.jsx("path",{d:"M23 21v-2a4 4 0 00-3-3.87M16 3.13a4 4 0 010 7.75",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})]})}];function M(){const l=[...new Set(j.map(t=>t.category))];return e.jsx("div",{className:"min-h-screen bg-[#FAF9F6]",children:e.jsxs("div",{className:"max-w-6xl mx-auto px-6 py-8",children:[e.jsxs("div",{className:"mb-8",children:[e.jsx("h1",{className:"text-2xl font-bold text-[#36342E]",children:"Compare"}),e.jsx("p",{className:"text-[#6B6960] mt-1",children:"See how Loki Mode stacks up against other AI development platforms."})]}),e.jsx("div",{className:"bg-white border border-[#ECEAE3] rounded-xl overflow-hidden shadow-sm",children:e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"border-b border-[#ECEAE3]",children:[e.jsx("th",{className:"text-left px-4 py-3 font-medium text-[#6B6960] w-[240px]",children:"Feature"}),e.jsx("th",{className:"text-center px-4 py-3 font-bold text-[#553DE9] bg-[#553DE9]/5 w-[130px]",children:"Loki Mode"}),e.jsx("th",{className:"text-center px-4 py-3 font-medium text-[#6B6960] w-[130px]",children:"bolt.new"}),e.jsx("th",{className:"text-center px-4 py-3 font-medium text-[#6B6960] w-[130px]",children:"Replit"}),e.jsx("th",{className:"text-center px-4 py-3 font-medium text-[#6B6960] w-[130px]",children:"Lovable"})]})}),e.jsx("tbody",{children:l.map(t=>e.jsxs(e.Fragment,{children:[e.jsx("tr",{className:"bg-[#FAF9F6]",children:e.jsx("td",{colSpan:5,className:"px-4 py-2 text-xs font-bold text-[#939084] uppercase tracking-wider",children:t})},`cat-${t}`),j.filter(s=>s.category===t).map(s=>e.jsxs("tr",{className:"border-b border-[#ECEAE3] last:border-b-0",children:[e.jsx("td",{className:"px-4 py-2.5 text-[#36342E]",children:s.feature}),e.jsx("td",{className:"px-4 py-2.5 text-center bg-[#553DE9]/5",children:e.jsx("div",{className:"flex justify-center",children:e.jsx(x,{value:s.lokiMode})})}),e.jsx("td",{className:"px-4 py-2.5 text-center",children:e.jsx("div",{className:"flex justify-center",children:e.jsx(x,{value:s.boltNew})})}),e.jsx("td",{className:"px-4 py-2.5 text-center",children:e.jsx("div",{className:"flex justify-center",children:e.jsx(x,{value:s.replit})})}),e.jsx("td",{className:"px-4 py-2.5 text-center",children:e.jsx("div",{className:"flex justify-center",children:e.jsx(x,{value:s.lovable})})})]},s.feature))]}))})]})})}),e.jsxs("div",{className:"mt-12",children:[e.jsx("h2",{className:"text-xl font-bold text-[#36342E] mb-6",children:"Why developers choose Loki Mode"}),e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-5",children:k.map(t=>e.jsxs("div",{className:"bg-white border border-[#ECEAE3] rounded-xl p-5 shadow-sm hover:shadow-md transition-shadow",children:[e.jsx("div",{className:"mb-3",children:t.icon}),e.jsx("h3",{className:"text-base font-bold text-[#36342E] mb-1",children:t.title}),e.jsx("p",{className:"text-sm text-[#6B6960]",children:t.description})]},t.title))})]}),e.jsx("div",{className:"mt-12 max-w-xl mx-auto",children:e.jsx(g,{})})]})})}export{M as default};
@@ -1,4 +1,4 @@
1
- import{c as o,r as a,j as e,T as n,i,b as c}from"./index-DvZ0Kk2x.js";/**
1
+ import{c as o,r as a,j as e,T as n,h as i,p as c}from"./index-Cz7q1bvC.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.