fifony 0.1.15 → 0.1.16

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.
package/README.md CHANGED
@@ -6,10 +6,8 @@
6
6
 
7
7
  Point at a repo. Open the dashboard. AI plans, builds, and reviews — you approve.
8
8
 
9
- One command. Full orchestra.
10
-
11
9
  [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
12
- [![Node](https://img.shields.io/badge/node-%3E%3D20-brightgreen.svg)]()
10
+ [![Node](https://img.shields.io/badge/node-%3E%3D23-brightgreen.svg)]()
13
11
 
14
12
  </div>
15
13
 
@@ -21,97 +19,75 @@ One command. Full orchestra.
21
19
  npx -y fifony --port 4040
22
20
  ```
23
21
 
24
- Open **http://localhost:4040**. First run launches the **onboarding wizard** — it detects your CLIs, scans your project, and configures everything.
25
-
26
- State lives in `.fifony/`. No accounts, no cloud, no setup.
22
+ Open **http://localhost:4040**. The first run launches the onboarding wizard — it detects your CLIs, scans your project, and configures everything in six steps. State lives in `.fifony/`. No accounts, no cloud, no external database.
27
23
 
28
24
  ---
29
25
 
30
- ## What Makes Fifony Different
31
-
32
- ### Mixed-Agent Pipeline
26
+ ## How It Works
33
27
 
34
- The core idea: **different AI providers handle different stages** of a single task.
28
+ Fifony breaks every task into three stages, each independently configurable:
35
29
 
36
30
  ```
37
- Plan Execute Review
38
- ┌─────────┐ ┌─────────┐ ┌─────────┐
39
- │ Claude │──▶│ Codex │──▶│ Claude
40
- │ Opus 4.6 │ Sonnet
41
- │ high medium medium
42
- └─────────┘ └─────────┘ └─────────┘
31
+ Plan Execute Review
32
+ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
33
+ │ Claude │─▶│ Codex │─▶│ Claude
34
+ │ Opus 4.5 │ Sonnet 4.5
35
+ effort: high effort: med effort: med
36
+ └──────────────┘ └──────────────┘ └──────────────┘
43
37
  ```
44
38
 
45
- Claude plans. Codex executes. Claude reviews. Each stage gets its own **provider**, **model**, and **reasoning effort** configurable per-project in Settings Workflow.
46
-
47
- ### Onboarding Wizard
48
-
49
- First run detects your environment and walks you through setup:
50
-
51
- 1. **Pipeline** — Choose which CLI runs each stage (planner, executor, reviewer)
52
- 2. **Project Scan** — AI analyzes your codebase to detect language, stack, and domains
53
- 3. **Domains** — Pre-selected by AI, 21 options across Technical/Industry/Role
54
- 4. **Agents & Skills** — Curated catalog of 15 agents and 5 skills, auto-recommended by domain
55
- 5. **Effort** — Per-stage reasoning effort, reactive to which CLI is selected
56
- 6. **Workers & Theme** — Parallel worker count + visual theme
57
-
58
- Settings saved progressively. Re-run anytime from Settings.
39
+ You set the provider, model, and reasoning effort for each stage. Claude plans, Codex executes, Claude reviews or any combination you prefer. Configure it in the Settings UI or drop a `WORKFLOW.md` in your project root.
59
40
 
60
- ### Language Agnostic
61
-
62
- The project scanner works with any codebase — it detects build files for 18+ ecosystems:
63
-
64
- `package.json` · `Cargo.toml` · `pyproject.toml` · `go.mod` · `build.gradle` · `Gemfile` · `mix.exs` · `pubspec.yaml` · `CMakeLists.txt` · `composer.json` · `Package.swift` · `deno.json` · `pom.xml` · `Dockerfile` · and more
65
-
66
- Uses the detected CLI with `--reasoning-effort low` for fast, accurate analysis.
67
-
68
- ---
69
-
70
- ## How It Works
41
+ ### Issue Lifecycle
71
42
 
72
43
  ```
73
44
  Planning → Todo → Queued → Running → In Review → Done
74
-
75
- └──── Blocked ←── Rework ──────────────┘
45
+
46
+ Interrupted Blocked (retry with backoff)
76
47
  ```
77
48
 
78
- 1. **Create an Issue** — Click "+", describe what you want done
79
- 2. **AI Plans It** — Structured execution plan with steps, risks, file paths, complexity
80
- 3. **You Approve** — Review the plan, approve agents pick it up
81
- 4. **Agents Execute** — Isolated workspace, live output streaming, PID tracking
82
- 5. **Automated Review** — Diff inspection, approve/rework/block decision
83
- 6. **You Ship** — Review the diff, merge
49
+ 1. **Create** — Describe what you want done. Fifony AI-enhances the title and description before planning.
50
+ 2. **Plan** — The planner agent generates a structured execution plan: phases, steps, target files, complexity, risks.
51
+ 3. **Approve** — You review the plan. Optionally chat with the AI to refine it before approving.
52
+ 4. **Execute** — Agents run in an isolated workspace (a copy of your project). Live output streams to the dashboard.
53
+ 5. **Review** — The reviewer agent inspects the diff and either approves, requests rework, or blocks.
54
+ 6. **Merge** — You review the diff and merge the workspace back to your project root.
55
+
56
+ Agents run as detached child processes, tracked by PID. If the server restarts mid-run, Fifony recovers on the next boot.
84
57
 
85
58
  ---
86
59
 
87
- ## Dashboard
60
+ ## Onboarding Wizard
61
+
62
+ The first run walks you through six steps:
88
63
 
89
- | Page | What you see |
64
+ | Step | What happens |
90
65
  |------|-------------|
91
- | **Kanban** | Drag-and-drop board. Cards flow through the pipeline with state-colored borders and stagger animations. |
92
- | **Issues** | Searchable list with descriptions, labels, token usage, duration, and filter chips by state. |
93
- | **Agents** | Live cockpit with agent slots, real-time log output, queue, token usage sparkline. |
94
- | **Settings** | Tabbed: General, Workflow (pipeline config), Notifications, Providers. |
66
+ | CLI Detection | Finds `claude`, `codex`, `git`, `node`, `docker`, and other tools on your system |
67
+ | Project Scan | Detects language, stack, and build system 18+ ecosystems supported |
68
+ | AI Analysis | Uses the detected CLI to extract domain context from your codebase |
69
+ | Domains | 21 options across Technical / Industry / Role, pre-selected by the AI |
70
+ | Agents & Skills | Catalog of 15 agents and 5 skills, auto-recommended for your domains |
71
+ | Effort & Workers | Per-stage reasoning effort, worker concurrency, and visual theme |
95
72
 
96
- ### Kanban Drag & Drop
73
+ Settings are saved progressively and can be re-run from Settings at any time.
97
74
 
98
- Drag issues between columns to change state. Works on desktop (click + drag) and mobile (long-press). Valid drop targets highlight green, invalid ones dim. State machine enforces valid transitions only.
75
+ Supported build files include: `package.json`, `Cargo.toml`, `pyproject.toml`, `go.mod`, `build.gradle`, `Gemfile`, `mix.exs`, `pubspec.yaml`, `CMakeLists.txt`, `composer.json`, `Package.swift`, `deno.json`, `pom.xml`, `Dockerfile`, and more.
76
+
77
+ ---
99
78
 
100
- ### Micro-interactions
79
+ ## Dashboard
101
80
 
102
- Every interaction has visual feedback:
81
+ | Route | What you see |
82
+ |-------|-------------|
83
+ | `/kanban` | Drag-and-drop board. Cards flow through pipeline stages. Desktop click+drag, mobile long-press. |
84
+ | `/issues` | Searchable list with state, label, and capability filters. Shows token usage and duration per issue. |
85
+ | `/agents` | Live cockpit: worker slots, queue depth, real-time log tail, token sparklines per agent. |
86
+ | `/discover` | Import TODOs from your codebase, GitHub issues, or AI-suggested tasks. |
87
+ | `/analytics` | Token usage trends, daily and weekly rollups, top issues by cost, per-model breakdown. |
88
+ | `/settings` | General, Workflow pipeline config, Notifications, Providers. |
103
89
 
104
- - **Cards** lift on hover with state-colored left border
105
- - **Running cards** pulse with a breathing border glow
106
- - **Buttons** scale on press, hover lift
107
- - **Toasts** slide in with progress bar, typed as success/error/info
108
- - **Drawers** slide in/out with backdrop fade
109
- - **View transitions** fade between routes
110
- - **Theme changes** cross-fade in 300ms
111
- - **Counters** bounce when values change
112
- - **Skeleton loaders** shimmer during initial load
113
- - **Empty states** animate in with helpful guidance
114
- - **Confetti** bursts on issue creation
90
+ The **Issue Detail Drawer** shows the full plan (phases and steps), all execution sessions, the workspace diff, and a per-phase token breakdown — Plan / Execute / Review — with input and output counts per model.
115
91
 
116
92
  ### PWA
117
93
 
@@ -121,15 +97,15 @@ Install as a desktop app. Works offline. Desktop notifications when issues chang
121
97
 
122
98
  ## Agent & Skill Catalog
123
99
 
124
- Fifony ships with a curated catalog of specialist agents:
100
+ Fifony ships with 15 specialist agents:
125
101
 
126
- | Agent | Domain |
127
- |-------|--------|
102
+ | Agent | Focus |
103
+ |-------|-------|
128
104
  | Frontend Developer | React, Vue, CSS, responsive design |
129
105
  | Backend Architect | APIs, microservices, scalable systems |
130
106
  | Database Optimizer | Schema design, query optimization, indexing |
131
107
  | Security Engineer | OWASP, threat modeling, secure code review |
132
- | DevOps Automator | CI/CD, Docker, Kubernetes, cloud infra |
108
+ | DevOps Automator | CI/CD, Docker, Kubernetes, cloud infrastructure |
133
109
  | Mobile App Builder | iOS, Android, React Native, Flutter |
134
110
  | AI Engineer | ML models, LLM integration, data pipelines |
135
111
  | UI Designer | Visual design, component libraries, design systems |
@@ -141,9 +117,36 @@ Fifony ships with a curated catalog of specialist agents:
141
117
  | Software Architect | System design, DDD, architectural patterns |
142
118
  | Game Designer | Game mechanics, level design, cross-engine |
143
119
 
144
- Skills: `commit`, `review-pr`, `debug`, `testing`, `impeccable` (frontend design).
120
+ And 5 skills: `commit`, `review-pr`, `debug`, `testing`, `impeccable` (frontend design system).
145
121
 
146
- Agents are installed to `.claude/agents/` during onboarding. Compatible with both Claude Code and Codex CLI.
122
+ Agents install to `.claude/agents/` and `.codex/agents/` during onboarding. Skills load from `SKILL.md` files in `.claude/skills/`, `.codex/skills/`, or your home directory. Fifony infers the right agent from the issue description and target file paths — capability routing is automatic.
123
+
124
+ ---
125
+
126
+ ## CLI Reference
127
+
128
+ ```bash
129
+ # Dashboard + API + scheduler
130
+ npx -y fifony --port 4040
131
+
132
+ # With Vite HMR for frontend development
133
+ npx -y fifony --port 4040 --dev
134
+
135
+ # Headless — scheduler only, no UI
136
+ npx -y fifony
137
+
138
+ # MCP server (stdio)
139
+ npx -y fifony mcp
140
+
141
+ # Different workspace
142
+ npx -y fifony --workspace /path/to/repo --port 4040
143
+
144
+ # Run one scheduler cycle and exit
145
+ npx -y fifony --once
146
+
147
+ # Fine-grained control
148
+ npx -y fifony --concurrency 2 --attempts 3 --poll 500
149
+ ```
147
150
 
148
151
  ---
149
152
 
@@ -152,9 +155,11 @@ Agents are installed to `.claude/agents/` during onboarding. Compatible with bot
152
155
  Use Fifony as tools inside your editor:
153
156
 
154
157
  ```bash
155
- npx -y fifony mcp
158
+ npx -y fifony mcp --workspace /path/to/repo
156
159
  ```
157
160
 
161
+ Add to `claude_desktop_config.json` or VS Code settings:
162
+
158
163
  ```json
159
164
  {
160
165
  "mcpServers": {
@@ -166,53 +171,52 @@ npx -y fifony mcp
166
171
  }
167
172
  ```
168
173
 
169
- Create issues, check status, review workflows without leaving the editor.
174
+ **Resources**: state summary, all issues, workflow config, runtime guide, per-issue detail
170
175
 
171
- ---
176
+ **Tools**: `fifony.status`, `fifony.list_issues`, `fifony.create_issue`, `fifony.update_issue_state`, `fifony.integration_config`
172
177
 
173
- ## API
178
+ **Prompts**: `fifony-integrate-client`, `fifony-plan-issue`, `fifony-review-workflow`
174
179
 
175
- REST + WebSocket API with auto-generated OpenAPI docs:
180
+ ---
176
181
 
177
- ```
178
- http://localhost:4040/docs
179
- ```
182
+ ## REST API
183
+
184
+ Interactive docs at `http://localhost:4040/docs`.
180
185
 
181
186
  | Endpoint | Description |
182
187
  |----------|-------------|
183
- | `GET /api/state` | Runtime state with issues, metrics, config |
184
- | `POST /api/issues/create` | Create a new issue |
185
- | `POST /api/issues/:id/plan` | Generate AI execution plan |
188
+ | `GET /api/state` | Full runtime state: issues, metrics, config |
189
+ | `POST /api/issues/create` | Create an issue |
190
+ | `POST /api/issues/enhance` | AI-enhance title and description |
191
+ | `POST /api/issues/:id/plan` | Generate execution plan |
192
+ | `POST /api/issues/:id/plan/refine` | Refine plan with chat feedback |
186
193
  | `POST /api/issues/:id/approve` | Approve plan, start execution |
187
- | `GET /api/live/:id` | Live agent output (PID, log tail, elapsed) |
194
+ | `POST /api/issues/:id/merge` | Merge workspace to project root |
195
+ | `GET /api/live/:id` | Live agent output: PID, log tail, elapsed time |
188
196
  | `GET /api/diff/:id` | Git diff of workspace changes |
189
197
  | `GET /api/config/workflow` | Pipeline workflow configuration |
190
- | `GET /api/scan/project` | Project structure scan |
191
- | `POST /api/scan/analyze` | AI-powered project analysis |
192
- | `GET /api/catalog/agents` | Agent catalog (filterable by domain) |
198
+ | `GET /api/analytics/tokens` | Token usage summary |
199
+ | `GET /api/analytics/hourly` | Hourly usage buckets (48h retention) |
200
+ | `GET /api/providers` | Detected providers and availability |
201
+ | `GET /api/catalog/agents` | Agent catalog, filterable by domain |
193
202
  | `POST /api/install/agents` | Install agents to project |
194
- | `GET /api/settings` | All persisted settings |
195
203
  | `/ws` | WebSocket for real-time state updates |
196
204
 
197
205
  ---
198
206
 
199
- ## Run Modes
207
+ ## Configuration
200
208
 
201
- ```bash
202
- # Full experience — dashboard + API + scheduler
203
- npx -y fifony --port 4040
204
-
205
- # Dev mode — Vite HMR on port+1
206
- npx -y fifony --port 4040 --dev
209
+ Fifony reads a `WORKFLOW.md` in your project root if present. Front matter configures the pipeline; the Markdown body defines the execution contract. Settings from the UI write to `.fifony/s3db/`.
207
210
 
208
- # Headless scheduler only, no UI
209
- npx -y fifony
210
-
211
- # MCP server — stdio for editor integration
212
- npx -y fifony mcp
211
+ **Environment variables** (all optional when using the UI or WORKFLOW.md):
213
212
 
214
- # Custom workspace
215
- npx -y fifony --workspace /path/to/repo --port 4040
213
+ ```bash
214
+ FIFONY_WORKSPACE_ROOT=/path/to/repo
215
+ FIFONY_PERSISTENCE=/path/to/state # defaults to $FIFONY_WORKSPACE_ROOT
216
+ FIFONY_AGENT_PROVIDER=codex # codex | claude
217
+ FIFONY_WORKER_CONCURRENCY=2
218
+ FIFONY_MAX_ATTEMPTS=3
219
+ FIFONY_AGENT_MAX_TURNS=4
216
220
  ```
217
221
 
218
222
  ---
@@ -220,19 +224,28 @@ npx -y fifony --workspace /path/to/repo --port 4040
220
224
  ## Architecture
221
225
 
222
226
  ```
223
- .fifony/ ← all state (gitignore it)
224
- s3db/ ← durable database (issues, events, sessions, settings)
225
- source/ codebase snapshot
226
- workspaces/ ← isolated per-issue agent workspaces
227
+ .fifony/
228
+ s3db/ ← durable database (issues, events, sessions, settings)
229
+ source/ project snapshot used for workspace seeding
230
+ workspaces/ ← isolated per-issue execution directories
227
231
  ```
228
232
 
229
- **Persistence**: [s3db.js](https://github.com/forattini-dev/s3db.js) — filesystem-backed database. Issues, events, settings, agent sessions all persisted and recoverable across restarts.
233
+ **Persistence**: [s3db.js](https://github.com/forattini-dev/s3db.js) — filesystem-backed key-value store. No external database. All state is fully recoverable across restarts.
234
+
235
+ **State machine**: The `StateMachinePlugin` enforces valid state transitions. Invalid moves are rejected at the API layer.
236
+
237
+ **Token tracking**: O(1) in-memory ledger, no I/O on the hot path. Per-phase and per-model breakdown. Daily and hourly rollups via the `EventualConsistencyPlugin`. Cost estimates when the provider reports them.
230
238
 
231
- **State Machine**: `Planning Todo Queued Running Interrupted In Review Blocked Done Cancelled`
239
+ **Capability routing**: Fifony infers task type from the issue description and target file paths. It derives `capability:<category>` and `overlay:<name>` labels for queue triage. When `paths[]` is omitted, routing falls back to path mentions in the issue text and files changed in an existing workspace.
240
+
241
+ **Graceful shutdown**: Running issues are marked `Interrupted` on SIGTERM. They resume from the last completed turn on the next boot.
242
+
243
+ ---
232
244
 
233
- **Agent Protection**: Detached child processes survive server restarts. PID tracking for recovery. Graceful shutdown marks running issues as Interrupted.
245
+ ## Requirements
234
246
 
235
- **Token Tracking**: Per-model token usage with daily/weekly rollups and cost estimates.
247
+ - Node.js 23 or newer
248
+ - At least one of: `claude` CLI, `codex` CLI
236
249
 
237
250
  ---
238
251
 
@@ -240,11 +253,11 @@ npx -y fifony --workspace /path/to/repo --port 4040
240
253
 
241
254
  Fifony is built on the shoulders of:
242
255
 
243
- - **[OpenAI Codex CLI](https://github.com/openai/codex)** — Original foundation (Apache 2.0). See [NOTICE](NOTICE) and [THIRD-PARTY-NOTICES](THIRD-PARTY-NOTICES.md).
256
+ - **[OpenAI Codex CLI](https://github.com/openai/codex)** — Original foundation (Apache 2.0). See [NOTICE](NOTICE) and [THIRD-PARTY-NOTICES.md](THIRD-PARTY-NOTICES.md).
244
257
  - **[Agency Agents](https://github.com/msitarzewski/agency-agents)** — Inspiration for the agent catalog.
245
- - **[Impeccable](https://github.com/pbakaus/impeccable)** — Frontend design skill system by Paul Bakaus.
246
- - **[s3db.js](https://github.com/forattini-dev/s3db.js)** — Filesystem-backed persistence layer.
247
- - **[DaisyUI](https://daisyui.com)** — Component library for the dashboard.
258
+ - **[Impeccable](https://github.com/pbakaus/impeccable)** — Frontend design skill by Paul Bakaus.
259
+ - **[s3db.js](https://github.com/forattini-dev/s3db.js)** — Filesystem persistence layer.
260
+ - **[DaisyUI](https://daisyui.com)** — Dashboard component library.
248
261
 
249
262
  ---
250
263
 
@@ -1 +1 @@
1
- import{n as e}from"./rolldown-runtime-DF2fYuay.js";import{I as t,h as n}from"./vendor-BoGBoEwT.js";import{t as r}from"./createLucideIcon-DtZs0TX0.js";import{i}from"./index-BdrTN_Wj.js";var a=r(`keyboard`,[[`path`,{d:`M10 8h.01`,key:`1r9ogq`}],[`path`,{d:`M12 12h.01`,key:`1mp3jc`}],[`path`,{d:`M14 8h.01`,key:`1primd`}],[`path`,{d:`M16 12h.01`,key:`1l6xoz`}],[`path`,{d:`M18 8h.01`,key:`emo2bl`}],[`path`,{d:`M6 8h.01`,key:`x9i8wu`}],[`path`,{d:`M7 16h10`,key:`wp8him`}],[`path`,{d:`M8 12h.01`,key:`czm47f`}],[`rect`,{width:`20`,height:`16`,x:`2`,y:`4`,rx:`2`,key:`18n3k1`}]]),o=e(t(),1),s=n(),c=[{key:`n`,description:`Open New Issue drawer`},{key:`k`,description:`Navigate to Kanban`},{key:`i`,description:`Navigate to Issues`},{key:`a`,description:`Navigate to Agents`},{key:`t`,description:`Navigate to Analytics`},{key:`s`,description:`Navigate to Settings`},{key:`1–6`,description:`Jump to kanban column by index`},{key:`Esc`,description:`Close any open drawer / modal`},{key:`?`,description:`Show this help`}];function l({open:e,onClose:t}){let n=(0,o.useRef)(null);return(0,o.useEffect)(()=>{let t=n.current;t&&(e&&!t.open?t.showModal():!e&&t.open&&t.close())},[e]),(0,s.jsxs)(`dialog`,{ref:n,className:`modal modal-bottom sm:modal-middle`,onClose:t,children:[(0,s.jsxs)(`div`,{className:`modal-box max-w-md`,children:[(0,s.jsxs)(`div`,{className:`flex items-center justify-between mb-4`,children:[(0,s.jsxs)(`h3`,{className:`font-bold text-lg flex items-center gap-2`,children:[(0,s.jsx)(a,{className:`size-5 opacity-60`}),`Keyboard Shortcuts`]}),(0,s.jsx)(`button`,{className:`btn btn-sm btn-ghost btn-circle`,onClick:t,children:(0,s.jsx)(i,{className:`size-4`})})]}),(0,s.jsx)(`div`,{className:`overflow-x-auto`,children:(0,s.jsxs)(`table`,{className:`table table-sm`,children:[(0,s.jsx)(`thead`,{children:(0,s.jsxs)(`tr`,{children:[(0,s.jsx)(`th`,{children:`Key`}),(0,s.jsx)(`th`,{children:`Action`})]})}),(0,s.jsx)(`tbody`,{children:c.map(e=>(0,s.jsxs)(`tr`,{children:[(0,s.jsx)(`td`,{children:(0,s.jsx)(`kbd`,{className:`kbd kbd-sm`,children:e.key})}),(0,s.jsx)(`td`,{children:e.description})]},e.key))})]})}),(0,s.jsx)(`div`,{className:`modal-action`,children:(0,s.jsx)(`button`,{className:`btn btn-sm`,onClick:t,children:`Close`})})]}),(0,s.jsx)(`form`,{method:`dialog`,className:`modal-backdrop`,children:(0,s.jsx)(`button`,{children:`close`})})]})}export{l as default};
1
+ import{n as e}from"./rolldown-runtime-DF2fYuay.js";import{I as t,h as n}from"./vendor-BoGBoEwT.js";import{t as r}from"./createLucideIcon-DtZs0TX0.js";import{i}from"./index-BRWIoM5k.js";var a=r(`keyboard`,[[`path`,{d:`M10 8h.01`,key:`1r9ogq`}],[`path`,{d:`M12 12h.01`,key:`1mp3jc`}],[`path`,{d:`M14 8h.01`,key:`1primd`}],[`path`,{d:`M16 12h.01`,key:`1l6xoz`}],[`path`,{d:`M18 8h.01`,key:`emo2bl`}],[`path`,{d:`M6 8h.01`,key:`x9i8wu`}],[`path`,{d:`M7 16h10`,key:`wp8him`}],[`path`,{d:`M8 12h.01`,key:`czm47f`}],[`rect`,{width:`20`,height:`16`,x:`2`,y:`4`,rx:`2`,key:`18n3k1`}]]),o=e(t(),1),s=n(),c=[{key:`n`,description:`Open New Issue drawer`},{key:`k`,description:`Navigate to Kanban`},{key:`i`,description:`Navigate to Issues`},{key:`a`,description:`Navigate to Agents`},{key:`t`,description:`Navigate to Analytics`},{key:`s`,description:`Navigate to Settings`},{key:`1–6`,description:`Jump to kanban column by index`},{key:`Esc`,description:`Close any open drawer / modal`},{key:`?`,description:`Show this help`}];function l({open:e,onClose:t}){let n=(0,o.useRef)(null);return(0,o.useEffect)(()=>{let t=n.current;t&&(e&&!t.open?t.showModal():!e&&t.open&&t.close())},[e]),(0,s.jsxs)(`dialog`,{ref:n,className:`modal modal-bottom sm:modal-middle`,onClose:t,children:[(0,s.jsxs)(`div`,{className:`modal-box max-w-md`,children:[(0,s.jsxs)(`div`,{className:`flex items-center justify-between mb-4`,children:[(0,s.jsxs)(`h3`,{className:`font-bold text-lg flex items-center gap-2`,children:[(0,s.jsx)(a,{className:`size-5 opacity-60`}),`Keyboard Shortcuts`]}),(0,s.jsx)(`button`,{className:`btn btn-sm btn-ghost btn-circle`,onClick:t,children:(0,s.jsx)(i,{className:`size-4`})})]}),(0,s.jsx)(`div`,{className:`overflow-x-auto`,children:(0,s.jsxs)(`table`,{className:`table table-sm`,children:[(0,s.jsx)(`thead`,{children:(0,s.jsxs)(`tr`,{children:[(0,s.jsx)(`th`,{children:`Key`}),(0,s.jsx)(`th`,{children:`Action`})]})}),(0,s.jsx)(`tbody`,{children:c.map(e=>(0,s.jsxs)(`tr`,{children:[(0,s.jsx)(`td`,{children:(0,s.jsx)(`kbd`,{className:`kbd kbd-sm`,children:e.key})}),(0,s.jsx)(`td`,{children:e.description})]},e.key))})]})}),(0,s.jsx)(`div`,{className:`modal-action`,children:(0,s.jsx)(`button`,{className:`btn btn-sm`,onClick:t,children:`Close`})})]}),(0,s.jsx)(`form`,{method:`dialog`,className:`modal-backdrop`,children:(0,s.jsx)(`button`,{children:`close`})})]})}export{l as default};
@@ -0,0 +1 @@
1
+ import{n as e}from"./rolldown-runtime-DF2fYuay.js";import{I as t,h as n,m as r}from"./vendor-BoGBoEwT.js";import{c as i,l as a,n as o,t as s,u as c,w as l,y as u}from"./zap-BwZ-sPG7.js";import{t as d}from"./createLucideIcon-DtZs0TX0.js";import{S as f,a as p,b as m,c as h,d as g,g as _,h as v,l as y,m as b,n as x,p as S,r as C,s as w,t as ee,u as T,x as E,y as D}from"./index-BRWIoM5k.js";var O=d(`boxes`,[[`path`,{d:`M2.97 12.92A2 2 0 0 0 2 14.63v3.24a2 2 0 0 0 .97 1.71l3 1.8a2 2 0 0 0 2.06 0L12 19v-5.5l-5-3-4.03 2.42Z`,key:`lc1i9w`}],[`path`,{d:`m7 16.5-4.74-2.85`,key:`1o9zyk`}],[`path`,{d:`m7 16.5 5-3`,key:`va8pkn`}],[`path`,{d:`M7 16.5v5.17`,key:`jnp8gn`}],[`path`,{d:`M12 13.5V19l3.97 2.38a2 2 0 0 0 2.06 0l3-1.8a2 2 0 0 0 .97-1.71v-3.24a2 2 0 0 0-.97-1.71L17 10.5l-5 3Z`,key:`8zsnat`}],[`path`,{d:`m17 16.5-5-3`,key:`8arw3v`}],[`path`,{d:`m17 16.5 4.74-2.85`,key:`8rfmw`}],[`path`,{d:`M17 16.5v5.17`,key:`k6z78m`}],[`path`,{d:`M7.97 4.42A2 2 0 0 0 7 6.13v4.37l5 3 5-3V6.13a2 2 0 0 0-.97-1.71l-3-1.8a2 2 0 0 0-2.06 0l-3 1.8Z`,key:`1xygjf`}],[`path`,{d:`M12 8 7.26 5.15`,key:`1vbdud`}],[`path`,{d:`m12 8 4.74-2.85`,key:`3rx089`}],[`path`,{d:`M12 13.5V8`,key:`1io7kd`}]]),k=d(`brain`,[[`path`,{d:`M12 18V5`,key:`adv99a`}],[`path`,{d:`M15 13a4.17 4.17 0 0 1-3-4 4.17 4.17 0 0 1-3 4`,key:`1e3is1`}],[`path`,{d:`M17.598 6.5A3 3 0 1 0 12 5a3 3 0 1 0-5.598 1.5`,key:`1gqd8o`}],[`path`,{d:`M17.997 5.125a4 4 0 0 1 2.526 5.77`,key:`iwvgf7`}],[`path`,{d:`M18 18a4 4 0 0 0 2-7.464`,key:`efp6ie`}],[`path`,{d:`M19.967 17.483A4 4 0 1 1 12 18a4 4 0 1 1-7.967-.517`,key:`1gq6am`}],[`path`,{d:`M6 18a4 4 0 0 1-2-7.464`,key:`k1g0md`}],[`path`,{d:`M6.003 5.125a4 4 0 0 0-2.526 5.77`,key:`q97ue3`}]]),te=d(`chevron-left`,[[`path`,{d:`m15 18-6-6 6-6`,key:`1wnfg3`}]]),A=d(`chevron-right`,[[`path`,{d:`m9 18 6-6-6-6`,key:`mthhwq`}]]),j=d(`flame`,[[`path`,{d:`M12 3q1 4 4 6.5t3 5.5a1 1 0 0 1-14 0 5 5 0 0 1 1-3 1 1 0 0 0 5 0c0-2-1.5-3-1.5-5q0-2 2.5-4`,key:`1slcih`}]]),M=d(`folder-search`,[[`path`,{d:`M10.7 20H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H20a2 2 0 0 1 2 2v4.1`,key:`1bw5m7`}],[`path`,{d:`m21 21-1.9-1.9`,key:`1g2n9r`}],[`circle`,{cx:`17`,cy:`17`,r:`3`,key:`18b49y`}]]),N=d(`globe`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`path`,{d:`M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20`,key:`13o1zl`}],[`path`,{d:`M2 12h20`,key:`9i4pu4`}]]),P=d(`rocket`,[[`path`,{d:`M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5`,key:`qeys4`}],[`path`,{d:`M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09`,key:`u4xsad`}],[`path`,{d:`M9 12a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.4 22.4 0 0 1-4 2z`,key:`676m9`}],[`path`,{d:`M9 12H4s.55-3.03 2-4c1.62-1.08 5 .05 5 .05`,key:`92ym6u`}]]),F=d(`shield-check`,[[`path`,{d:`M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z`,key:`oel41y`}],[`path`,{d:`m9 12 2 2 4-4`,key:`dzmm74`}]]),I=e(t(),1),L=n(),R=[`Welcome`,`Providers`,`Scan Project`,`Domains`,`Agents & Skills`,`Effort`,`Workers & Theme`,`Launch`];function ne(e){return e?[...R.slice(0,3),`Discover Issues`,...R.slice(3)]:R}function re(e){return e?9:8}var z=[{value:`low`,label:`Low`,icon:s,description:`Quick and light -- fast responses, less thorough`,color:`text-info`},{value:`medium`,label:`Medium`,icon:b,description:`Balanced -- good mix of speed and quality`,color:`text-success`},{value:`high`,label:`High`,icon:k,description:`Thorough -- deeper analysis, takes more time`,color:`text-warning`},{value:`extra-high`,label:`Extra High`,icon:j,description:`Maximum depth -- most thorough, slowest`,color:`text-error`}],B={codex:z,claude:z.filter(e=>e.value!==`extra-high`)};function V(e,t){return B[t?.[e]||`claude`]||z}var H=[{label:`Technical`,domains:[{value:`frontend`,label:`Frontend`,emoji:`🎨`},{value:`backend`,label:`Backend`,emoji:`⚙️`},{value:`mobile`,label:`Mobile`,emoji:`📱`},{value:`devops`,label:`DevOps / Infra`,emoji:`🚀`},{value:`database`,label:`Database`,emoji:`🗄️`},{value:`ai-ml`,label:`AI / ML`,emoji:`🤖`},{value:`security`,label:`Security`,emoji:`🔒`},{value:`testing`,label:`Testing / QA`,emoji:`🧪`},{value:`embedded`,label:`Embedded / IoT`,emoji:`🔌`}]},{label:`Industry`,domains:[{value:`games`,label:`Games`,emoji:`🎮`},{value:`ecommerce`,label:`E-commerce`,emoji:`🛒`},{value:`saas`,label:`SaaS`,emoji:`☁️`},{value:`fintech`,label:`Fintech`,emoji:`💰`},{value:`healthcare`,label:`Healthcare`,emoji:`🏥`},{value:`education`,label:`Education`,emoji:`📚`},{value:`blockchain`,label:`Blockchain`,emoji:`⛓️`},{value:`spatial-computing`,label:`Spatial / XR`,emoji:`🥽`}]},{label:`Role`,domains:[{value:`design`,label:`Design / UX`,emoji:`✏️`},{value:`product`,label:`Product`,emoji:`📋`},{value:`marketing`,label:`Marketing`,emoji:`📢`},{value:`data-engineering`,label:`Data Engineering`,emoji:`📊`}]}],ie=[{value:`auto`,label:`Auto`},{value:`light`,label:`Light`},{value:`dark`,label:`Dark`},{value:`black`,label:`Black`},{value:`cupcake`,label:`Cupcake`},{value:`night`,label:`Night`},{value:`sunset`,label:`Sunset`}];async function U(e,t,n=`ui`){return l.post(`/settings/${encodeURIComponent(e)}`,{value:t,scope:n,source:`user`})}function W(e,t=`medium`){return z.some(t=>t.value===e)?e:t}function ae(e){return!e||typeof e!=`object`||Array.isArray(e)?{planner:`medium`,executor:`medium`,reviewer:`medium`}:{planner:W(e.planner??e.default,`medium`),executor:W(e.executor??e.default,`medium`),reviewer:W(e.reviewer??e.default,`medium`)}}function G(e,t,n={}){return{plan:{provider:e.planner||`claude`,model:n.plan||e.planner||`claude`,effort:t.planner||`medium`},execute:{provider:e.executor||`codex`,model:n.execute||e.executor||`codex`,effort:t.executor||`medium`},review:{provider:e.reviewer||`claude`,model:n.review||e.reviewer||`claude`,effort:t.reviewer||`medium`}}}var K=[`Pipeline`,`Scan`,`Domains`,`Agents`,`Effort`,`Workers & Theme`,`Launch`];function q(e){return e?[...K.slice(0,2),`Discover`,...K.slice(2)]:K}function oe({current:e,wantsDiscovery:t}){let n=q(t),r=e-1;return(0,L.jsx)(`ul`,{className:`steps steps-horizontal w-full max-w-2xl text-xs`,children:n.map((e,t)=>{let n=t<r,i=t===r;return(0,L.jsx)(`li`,{"data-content":n?`✓`:t+1,className:`step ${n||i?`step-primary`:``}`,style:{transition:`color 0.3s ease`},children:e},e)})})}function se({direction:e,stepKey:t,center:n,children:r}){return(0,L.jsx)(`div`,{className:`${e===`forward`?`animate-slide-in-right`:`animate-slide-in-left`} w-full max-w-2xl mx-auto ${n?`my-auto`:``}`,children:r},t)}function ce(){let[e,t]=(0,I.useState)(null),[n,r]=(0,I.useState)(!1),[i,a]=(0,I.useState)(!1);return(0,I.useEffect)(()=>{l.get(`/gitignore/status`).then(t).catch(()=>t({exists:!1,hasFifony:!1}))},[]),e===null||e.hasFifony||i?i?(0,L.jsxs)(`div`,{className:`alert alert-success text-sm max-w-md animate-fade-in`,children:[(0,L.jsx)(F,{className:`size-4 shrink-0`}),(0,L.jsxs)(`span`,{children:[(0,L.jsx)(`code`,{children:`.fifony/`}),` added to `,(0,L.jsx)(`code`,{children:`.gitignore`})]})]}):null:(0,L.jsxs)(`div`,{className:`alert alert-warning text-sm max-w-md`,children:[(0,L.jsx)(S,{className:`size-4 shrink-0`}),(0,L.jsxs)(`div`,{className:`flex-1`,children:[(0,L.jsxs)(`span`,{children:[(0,L.jsx)(`code`,{children:`.fifony/`}),` is not in your `,(0,L.jsx)(`code`,{children:`.gitignore`}),`.`]}),(0,L.jsx)(`span`,{className:`text-base-content/50 block text-xs mt-0.5`,children:`Fifony stores local state there — it shouldn't be committed.`})]}),(0,L.jsx)(`button`,{className:`btn btn-xs btn-warning`,onClick:async()=>{r(!0);try{await l.post(`/gitignore/add`),a(!0)}catch{}finally{r(!1)}},disabled:n,children:n?(0,L.jsx)(g,{className:`size-3 animate-spin`}):`Add it`})]})}function le({workspacePath:e,onGetStarted:t}){return(0,L.jsxs)(`div`,{className:`flex flex-col items-center text-center gap-6 stagger-children py-4`,children:[(0,L.jsx)(`div`,{className:`text-6xl sm:text-7xl animate-bounce-in`,children:(0,L.jsx)(T,{className:`size-16 sm:size-20 text-primary mx-auto`})}),(0,L.jsxs)(`h1`,{className:`text-3xl sm:text-4xl font-bold tracking-tight`,children:[`Welcome to `,(0,L.jsx)(`span`,{className:`text-primary`,children:`Fifony`})]}),(0,L.jsx)(`p`,{className:`text-base-content/60 text-lg max-w-md`,children:`Let's set up your AI orchestration workspace in just a few steps.`}),e&&(0,L.jsxs)(`div`,{className:`badge badge-lg badge-soft badge-primary gap-2`,children:[(0,L.jsx)(w,{className:`size-3.5`}),e]}),(0,L.jsxs)(`button`,{className:`btn btn-primary btn-lg gap-2 mt-2`,onClick:t,children:[`Get Started `,(0,L.jsx)(A,{className:`size-5`})]})]})}var ue=[{role:`planner`,label:`Planner`,description:`Scopes the issue, breaks it into steps, and decides the approach`,icon:k,color:`text-info`},{role:`executor`,label:`Executor`,description:`Implements the plan — writes code, edits files, runs commands`,icon:s,color:`text-primary`},{role:`reviewer`,label:`Reviewer`,description:`Validates the result — checks correctness, scope, and quality`,icon:h,color:`text-secondary`}];function de({providers:e,providersLoading:t,pipeline:n,setPipeline:r}){let i=Array.isArray(e)?e:[],a=i.filter(e=>e.available!==!1);return(0,L.jsxs)(`div`,{className:`flex flex-col gap-6 stagger-children`,children:[(0,L.jsxs)(`div`,{className:`text-center`,children:[(0,L.jsx)(P,{className:`size-10 text-primary mx-auto mb-3`}),(0,L.jsx)(`h2`,{className:`text-2xl font-bold`,children:`Agent Pipeline`}),(0,L.jsx)(`p`,{className:`text-base-content/60 mt-1`,children:`Choose which CLI runs each stage of the pipeline`})]}),t?(0,L.jsxs)(`div`,{className:`flex flex-col items-center gap-3 py-8`,children:[(0,L.jsx)(g,{className:`size-8 text-primary animate-spin`}),(0,L.jsx)(`p`,{className:`text-sm text-base-content/50`,children:`Detecting available CLIs...`})]}):a.length===0?(0,L.jsx)(`div`,{className:`alert alert-warning text-sm`,children:`No providers detected. Make sure claude or codex CLI is installed.`}):(0,L.jsxs)(L.Fragment,{children:[(0,L.jsx)(`div`,{className:`flex flex-wrap gap-2 justify-center`,children:i.map(e=>{let t=e.id||e.name||e,n=e.available!==!1;return(0,L.jsxs)(`span`,{className:`badge badge-lg gap-2 ${n?`badge-success`:`badge-ghost opacity-50`}`,children:[n?(0,L.jsx)(m,{className:`size-3.5`}):(0,L.jsx)(D,{className:`size-3.5`}),t,e.path&&(0,L.jsx)(`span`,{className:`font-mono text-[10px] opacity-60 hidden sm:inline`,children:e.path})]},t)})}),(0,L.jsx)(`div`,{className:`flex flex-col items-center gap-2`,children:ue.map((e,t)=>{let i=e.icon,o=n[e.role]||a[0]?.name||``;return(0,L.jsxs)(`div`,{className:`w-full`,children:[t>0&&(0,L.jsx)(`div`,{className:`flex justify-center py-1`,children:(0,L.jsx)(A,{className:`size-5 rotate-90 opacity-30`})}),(0,L.jsx)(`div`,{className:`card bg-base-200`,children:(0,L.jsxs)(`div`,{className:`card-body p-4 flex-row items-center gap-4`,children:[(0,L.jsx)(`div`,{className:`size-10 rounded-full flex items-center justify-center bg-base-300 ${e.color}`,children:(0,L.jsx)(i,{className:`size-5`})}),(0,L.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,L.jsx)(`div`,{className:`font-semibold`,children:e.label}),(0,L.jsx)(`p`,{className:`text-xs text-base-content/50`,children:e.description})]}),(0,L.jsx)(`select`,{className:`select select-bordered select-sm w-32`,value:o,onChange:t=>r(n=>({...n,[e.role]:t.target.value})),children:a.map(e=>{let t=e.id||e.name||e;return(0,L.jsx)(`option`,{value:t,children:t},t)})})]})})]},e.role)})}),(0,L.jsx)(`p`,{className:`text-xs text-base-content/40 text-center max-w-md mx-auto`,children:`Each stage can use a different CLI. The pipeline flows top to bottom: plan, then execute, then review.`})]})]})}function fe({scanResult:e,setScanResult:t,projectDescription:n,setProjectDescription:r,analysisResult:i,setAnalysisResult:a,selectedProvider:o,analyzing:s,setAnalyzing:c}){let[u,d]=(0,I.useState)(!1),[p,h]=(0,I.useState)(null),[_,y]=(0,I.useState)(null),b=(0,I.useRef)(!1);(0,I.useEffect)(()=>{b.current||e||(b.current=!0,d(!0),h(null),l.get(`/scan/project`).then(e=>{if(t(e),!n){let t=e?.packageDescription||e?.packageInfo?.description||e?.readmeExcerpt||``;t&&r(t)}o&&!i&&(c(!0),l.post(`/scan/analyze`,{provider:o}).then(e=>{a(e),e.description&&r(e.description)}).catch(()=>{}).finally(()=>c(!1)))}).catch(e=>h(e.message||`Failed to scan project`)).finally(()=>d(!1)))},[]);let x=(0,I.useCallback)(async()=>{c(!0),y(null);try{let e=await l.post(`/scan/analyze`,{provider:o||`claude`});a(e),e.description&&r(e.description)}catch(e){y(e.message||`Analysis failed`)}finally{c(!1)}},[o,c,a,r]),S={claudeMd:`CLAUDE.md`,claudeDir:`.claude/`,codexDir:`.codex/`,readmeMd:`README.md`,packageJson:`package.json`,cargoToml:`Cargo.toml`,pyprojectToml:`pyproject.toml`,goMod:`go.mod`,buildGradle:`build.gradle`,gemfile:`Gemfile`,dockerfile:`Dockerfile`,workflowMd:`WORKFLOW.md`,agentsMd:`AGENTS.md`,claudeAgentsDir:`.claude/agents/`,claudeSkillsDir:`.claude/skills/`,codexAgentsDir:`.codex/agents/`,codexSkillsDir:`.codex/skills/`},C=e?.files||{},ee=Object.entries(C).map(([e,t])=>({path:S[e]||e,exists:!!t})),T=(e?.existingAgents||[]).map(e=>typeof e==`string`?{name:e}:e),E=(e?.existingSkills||[]).map(e=>typeof e==`string`?{name:e}:e),k=i?.stack||[];return(0,L.jsxs)(`div`,{className:`flex flex-col gap-6 stagger-children`,children:[(0,L.jsxs)(`div`,{className:`text-center`,children:[(0,L.jsx)(M,{className:`size-10 text-primary mx-auto mb-3`}),(0,L.jsx)(`h2`,{className:`text-2xl font-bold`,children:`Scan Project`}),(0,L.jsx)(`p`,{className:`text-base-content/60 mt-1`,children:`We'll analyze your workspace to suggest the best setup`})]}),u&&(0,L.jsxs)(`div`,{className:`flex flex-col items-center gap-3 py-6`,children:[(0,L.jsx)(g,{className:`size-8 text-primary animate-spin`}),(0,L.jsx)(`p`,{className:`text-sm text-base-content/50`,children:`Scanning project files...`})]}),p&&(0,L.jsx)(`div`,{className:`alert alert-warning text-sm`,children:p}),e&&!u&&(0,L.jsx)(`div`,{className:`card bg-base-200`,children:(0,L.jsxs)(`div`,{className:`card-body p-4 gap-3`,children:[(0,L.jsxs)(`h3`,{className:`font-semibold text-sm flex items-center gap-2`,children:[(0,L.jsx)(v,{className:`size-4 opacity-50`}),`Project Files`]}),(0,L.jsx)(`div`,{className:`grid grid-cols-1 sm:grid-cols-2 gap-1.5`,children:ee.map(e=>(0,L.jsxs)(`div`,{className:`flex items-center gap-2 text-sm`,children:[e.exists?(0,L.jsx)(m,{className:`size-4 text-success shrink-0`}):(0,L.jsx)(D,{className:`size-4 text-base-content/30 shrink-0`}),(0,L.jsx)(`span`,{className:`font-mono text-xs truncate ${e.exists?``:`text-base-content/40`}`,children:e.path})]},e.path))}),(T.length>0||E.length>0)&&(0,L.jsxs)(L.Fragment,{children:[(0,L.jsx)(`div`,{className:`divider my-0`}),(0,L.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[T.length>0&&(0,L.jsxs)(`span`,{className:`badge badge-sm badge-info gap-1`,children:[(0,L.jsx)(f,{className:`size-3`}),T.length,` agent`,T.length===1?``:`s`,` found`]}),E.length>0&&(0,L.jsxs)(`span`,{className:`badge badge-sm badge-secondary gap-1`,children:[(0,L.jsx)(O,{className:`size-3`}),E.length,` skill`,E.length===1?``:`s`,` found`]})]})]})]})}),!s&&!i&&(0,L.jsxs)(`button`,{className:`btn btn-primary btn-lg gap-2 mx-auto`,onClick:x,disabled:u,children:[(0,L.jsx)(w,{className:`size-5`}),`Analyze with AI`]}),s&&(0,L.jsxs)(`div`,{className:`flex flex-col items-center gap-3 py-4`,children:[(0,L.jsx)(g,{className:`size-8 text-primary animate-spin`}),(0,L.jsx)(`p`,{className:`text-sm text-base-content/50`,children:`AI is analyzing your project...`})]}),_&&(0,L.jsx)(`div`,{className:`alert alert-warning text-sm`,children:`Analysis failed. You can describe your project manually below.`}),k.length>0&&(0,L.jsx)(`div`,{className:`flex flex-wrap gap-2 justify-center`,children:k.map(e=>(0,L.jsx)(`span`,{className:`badge badge-sm badge-soft badge-primary`,children:e},e))}),(e||i||_)&&!u&&!s&&(0,L.jsxs)(`div`,{children:[(0,L.jsx)(`label`,{className:`label text-sm font-medium`,children:`Project Description`}),(0,L.jsx)(`textarea`,{className:`textarea textarea-bordered w-full h-24 text-sm`,placeholder:`Describe your project so we can suggest the right agents and domains...`,value:n,onChange:e=>r(e.target.value)})]})]})}function pe({selectedDomains:e,setSelectedDomains:t,analysisResult:n}){let r=(0,I.useRef)(!1);(0,I.useEffect)(()=>{r.current||!n?.domains?.length||e.length>0||(r.current=!0,t(n.domains))},[n]);let i=(0,I.useCallback)(e=>{t(t=>t.includes(e)?t.filter(t=>t!==e):[...t,e])},[t]);return(0,L.jsxs)(`div`,{className:`flex flex-col gap-6 stagger-children`,children:[(0,L.jsxs)(`div`,{className:`text-center`,children:[(0,L.jsx)(N,{className:`size-10 text-primary mx-auto mb-3`}),(0,L.jsx)(`h2`,{className:`text-2xl font-bold`,children:`Domains`}),(0,L.jsx)(`p`,{className:`text-base-content/60 mt-1`,children:`Select the domains relevant to your project`})]}),H.map(t=>(0,L.jsxs)(`div`,{children:[(0,L.jsx)(`div`,{className:`text-xs font-semibold uppercase tracking-wider text-base-content/40 mb-2`,children:t.label}),(0,L.jsx)(`div`,{className:`flex flex-wrap gap-2`,children:t.domains.map(t=>(0,L.jsxs)(`button`,{className:`btn btn-sm gap-1.5 ${e.includes(t.value)?`btn-primary`:`btn-soft`}`,onClick:()=>i(t.value),children:[(0,L.jsx)(`span`,{children:t.emoji}),t.label]},t.value))})]},t.label))]})}function me({selectedDomains:e,selectedAgents:t,setSelectedAgents:n,selectedSkills:r,setSelectedSkills:i,existingAgents:a,existingSkills:o}){let[s,c]=(0,I.useState)([]),[u,d]=(0,I.useState)([]),[p,m]=(0,I.useState)(!1),h=(0,I.useRef)(!1);(0,I.useEffect)(()=>{if(h.current)return;h.current=!0,m(!0);let s=e.length>0?`?domains=${e.join(`,`)}`:``;Promise.all([l.get(`/catalog/agents${s}`).catch(()=>({agents:[]})),l.get(`/catalog/skills`).catch(()=>({skills:[]}))]).then(([e,s])=>{let l=e?.agents||[],u=s?.skills||[];c(l),d(u);let f=new Set((a||[]).map(e=>e.name)),p=l.filter(e=>!f.has(e.name)).map(e=>e.name);p.length>0&&t.length===0&&n(p);let m=new Set((o||[]).map(e=>e.name)),h=u.filter(e=>!m.has(e.name)).map(e=>e.name);h.length>0&&r.length===0&&i(h)}).finally(()=>m(!1))},[]);let _=new Set((a||[]).map(e=>e.name)),v=new Set((o||[]).map(e=>e.name)),y=(0,I.useCallback)(e=>{n(t=>t.includes(e)?t.filter(t=>t!==e):[...t,e])},[n]),b=(0,I.useCallback)(e=>{i(t=>t.includes(e)?t.filter(t=>t!==e):[...t,e])},[i]),x=(0,I.useCallback)(()=>{n(s.filter(e=>!_.has(e.name)).map(e=>e.name))},[s,_,n]),S=(0,I.useCallback)(()=>n([]),[n]),C=(0,I.useCallback)(()=>{i(u.filter(e=>!v.has(e.name)).map(e=>e.name))},[u,v,i]),w=(0,I.useCallback)(()=>i([]),[i]);return p?(0,L.jsxs)(`div`,{className:`flex flex-col items-center gap-3 py-12`,children:[(0,L.jsx)(g,{className:`size-8 text-primary animate-spin`}),(0,L.jsx)(`p`,{className:`text-sm text-base-content/50`,children:`Loading catalog...`})]}):(0,L.jsxs)(`div`,{className:`flex flex-col gap-6 stagger-children`,children:[(0,L.jsxs)(`div`,{className:`text-center`,children:[(0,L.jsx)(f,{className:`size-10 text-primary mx-auto mb-3`}),(0,L.jsx)(`h2`,{className:`text-2xl font-bold`,children:`Agents & Skills`}),(0,L.jsx)(`p`,{className:`text-base-content/60 mt-1`,children:`Choose which agents and skills to install`})]}),s.length>0&&(0,L.jsxs)(`div`,{children:[(0,L.jsxs)(`div`,{className:`flex items-center justify-between mb-2`,children:[(0,L.jsxs)(`h3`,{className:`font-semibold text-sm flex items-center gap-2`,children:[(0,L.jsx)(f,{className:`size-4 opacity-50`}),`Agents (`,s.length,`)`]}),(0,L.jsxs)(`div`,{className:`flex gap-1`,children:[(0,L.jsx)(`button`,{className:`btn btn-xs btn-ghost`,onClick:x,children:`Select All`}),(0,L.jsx)(`button`,{className:`btn btn-xs btn-ghost`,onClick:S,children:`None`})]})]}),(0,L.jsx)(`div`,{className:`grid gap-2`,children:s.map(e=>{let n=_.has(e.name),r=n||t.includes(e.name);return(0,L.jsx)(`button`,{className:`card bg-base-200 cursor-pointer transition-all text-left ${r?`ring-2 ring-primary ring-offset-1 ring-offset-base-100`:``} ${n?`opacity-60`:``}`,onClick:()=>!n&&y(e.name),disabled:n,children:(0,L.jsxs)(`div`,{className:`card-body p-3 flex-row items-center gap-3`,children:[(0,L.jsx)(`div`,{className:`text-xl shrink-0`,children:e.emoji||`🤖`}),(0,L.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,L.jsx)(`div`,{className:`font-semibold text-sm truncate`,children:e.displayName||e.name}),e.description&&(0,L.jsx)(`p`,{className:`text-xs text-base-content/50 truncate`,children:e.description})]}),n?(0,L.jsxs)(`span`,{className:`badge badge-sm badge-success gap-1`,children:[(0,L.jsx)(E,{className:`size-3`}),` Installed`]}):(0,L.jsx)(`input`,{type:`checkbox`,className:`checkbox checkbox-primary checkbox-sm`,checked:r,readOnly:!0,tabIndex:-1})]})},e.name)})})]}),u.length>0&&(0,L.jsxs)(`div`,{children:[(0,L.jsxs)(`div`,{className:`flex items-center justify-between mb-2`,children:[(0,L.jsxs)(`h3`,{className:`font-semibold text-sm flex items-center gap-2`,children:[(0,L.jsx)(O,{className:`size-4 opacity-50`}),`Skills (`,u.length,`)`]}),(0,L.jsxs)(`div`,{className:`flex gap-1`,children:[(0,L.jsx)(`button`,{className:`btn btn-xs btn-ghost`,onClick:C,children:`Select All`}),(0,L.jsx)(`button`,{className:`btn btn-xs btn-ghost`,onClick:w,children:`None`})]})]}),(0,L.jsx)(`div`,{className:`grid gap-2`,children:u.map(e=>{let t=v.has(e.name),n=t||r.includes(e.name);return(0,L.jsx)(`button`,{className:`card bg-base-200 cursor-pointer transition-all text-left ${n?`ring-2 ring-primary ring-offset-1 ring-offset-base-100`:``} ${t?`opacity-60`:``}`,onClick:()=>!t&&b(e.name),disabled:t,children:(0,L.jsxs)(`div`,{className:`card-body p-3 flex-row items-center gap-3`,children:[(0,L.jsx)(`div`,{className:`text-xl shrink-0`,children:e.emoji||`🧩`}),(0,L.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,L.jsx)(`div`,{className:`font-semibold text-sm truncate`,children:e.displayName||e.name}),e.description&&(0,L.jsx)(`p`,{className:`text-xs text-base-content/50 truncate`,children:e.description})]}),t?(0,L.jsxs)(`span`,{className:`badge badge-sm badge-success gap-1`,children:[(0,L.jsx)(E,{className:`size-3`}),` Installed`]}):(0,L.jsx)(`input`,{type:`checkbox`,className:`checkbox checkbox-primary checkbox-sm`,checked:n,readOnly:!0,tabIndex:-1})]})},e.name)})})]}),s.length===0&&u.length===0&&(0,L.jsx)(`div`,{className:`alert alert-info text-sm`,children:`No agents or skills found in the catalog. You can add them later from the settings page.`})]})}function J({role:e,title:t,description:n,providerName:r,value:i,onChange:a,options:o,model:s,onModelChange:c,availableModels:l}){let u=Math.max(0,o.findIndex(e=>e.value===i)),d=o[u]||o[0],f=d.icon;return(0,L.jsx)(`div`,{className:`card bg-base-200`,children:(0,L.jsxs)(`div`,{className:`card-body p-5 gap-4`,children:[(0,L.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,L.jsxs)(`div`,{children:[(0,L.jsx)(`h3`,{className:`font-semibold`,children:t}),(0,L.jsx)(`p`,{className:`text-xs text-base-content/60 mt-0.5`,children:n})]}),r&&(0,L.jsx)(`span`,{className:`badge badge-sm badge-soft badge-primary capitalize`,children:r})]}),l&&l.length>0&&(0,L.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,L.jsx)(`label`,{className:`text-xs text-base-content/50`,children:`Model`}),(0,L.jsx)(`select`,{className:`select select-sm select-bordered w-full`,value:s||``,onChange:e=>c?.(e.target.value),children:l.map(e=>(0,L.jsx)(`option`,{value:e.id,children:e.label||e.id},e.id))})]}),(0,L.jsxs)(`div`,{className:`flex flex-col items-center gap-2 py-2`,children:[(0,L.jsxs)(`div`,{className:`flex items-center gap-2 text-lg font-bold ${d.color}`,children:[(0,L.jsx)(f,{className:`size-6`}),d.label]}),(0,L.jsx)(`p`,{className:`text-xs text-base-content/50 text-center max-w-xs`,children:d.description})]}),(0,L.jsxs)(`div`,{className:`px-1`,children:[(0,L.jsx)(`input`,{type:`range`,min:0,max:o.length-1,value:u,onChange:e=>a(o[Number(e.target.value)].value),className:`range range-primary range-sm w-full`,step:1}),(0,L.jsx)(`div`,{className:`flex justify-between mt-1 px-0.5`,children:o.map(t=>(0,L.jsx)(`span`,{className:`text-[10px] ${t.value===d.value?d.color+` font-semibold`:`text-base-content/30`}`,children:t.label},`${e}-tick-${t.value}`))})]})]})})}function he({efforts:e,setEfforts:t,pipeline:n,models:r,setModels:i,modelsByProvider:a}){(0,I.useEffect)(()=>{for(let r of[`planner`,`executor`,`reviewer`]){let i=V(r,n),a=e[r];a&&!i.some(e=>e.value===a)&&t(e=>({...e,[r]:`high`}))}},[n,e,t]);let o=a?.[n?.planner]||[],s=a?.[n?.executor]||[],c=a?.[n?.reviewer]||[];return(0,L.jsxs)(`div`,{className:`flex flex-col gap-6 stagger-children`,children:[(0,L.jsxs)(`div`,{className:`text-center`,children:[(0,L.jsx)(b,{className:`size-10 text-primary mx-auto mb-3`}),(0,L.jsx)(`h2`,{className:`text-2xl font-bold`,children:`Models & Reasoning Effort`}),(0,L.jsx)(`p`,{className:`text-base-content/60 mt-1`,children:`Choose the model and reasoning depth for each pipeline stage.`})]}),(0,L.jsx)(J,{role:`planner`,title:`Planning`,description:`Scopes the issue and decides the overall approach.`,providerName:n?.planner,value:e.planner,onChange:e=>t(t=>({...t,planner:e})),options:V(`planner`,n),model:r?.plan,onModelChange:e=>i(t=>({...t,plan:e})),availableModels:o}),(0,L.jsx)(J,{role:`executor`,title:`Execution`,description:`Implements the plan — writes code, edits files.`,providerName:n?.executor,value:e.executor,onChange:e=>t(t=>({...t,executor:e})),options:V(`executor`,n),model:r?.execute,onModelChange:e=>i(t=>({...t,execute:e})),availableModels:s}),(0,L.jsx)(J,{role:`reviewer`,title:`Review`,description:`Validates the result before approving.`,providerName:n?.reviewer,value:e.reviewer,onChange:e=>t(t=>({...t,reviewer:e})),options:V(`reviewer`,n),model:r?.review,onModelChange:e=>i(t=>({...t,review:e})),availableModels:c})]})}function ge({concurrency:e,setConcurrency:t,selectedTheme:n,setSelectedTheme:r}){return(0,L.jsxs)(`div`,{className:`flex flex-col gap-6 stagger-children`,children:[(0,L.jsxs)(`div`,{children:[(0,L.jsxs)(`div`,{className:`text-center mb-4`,children:[(0,L.jsx)(p,{className:`size-10 text-primary mx-auto mb-3`}),(0,L.jsx)(`h2`,{className:`text-2xl font-bold`,children:`Workers & Theme`}),(0,L.jsx)(`p`,{className:`text-base-content/60 mt-1`,children:`Configure parallel workers and visual theme`})]}),(0,L.jsx)(`div`,{className:`card bg-base-200`,children:(0,L.jsxs)(`div`,{className:`card-body p-5 gap-3`,children:[(0,L.jsxs)(`h3`,{className:`font-semibold text-sm flex items-center gap-2`,children:[(0,L.jsx)(p,{className:`size-4 opacity-50`}),`Worker Concurrency`]}),(0,L.jsxs)(`p`,{className:`text-xs text-base-content/60`,children:[`How many agents can work in parallel (`,e,` worker`,e===1?``:`s`,`)`]}),(0,L.jsx)(`input`,{type:`range`,min:1,max:16,value:e,onChange:e=>t(Number(e.target.value)),className:`range range-primary range-sm`}),(0,L.jsxs)(`div`,{className:`flex justify-between text-xs text-base-content/40 px-1`,children:[(0,L.jsx)(`span`,{children:`1`}),(0,L.jsx)(`span`,{children:`4`}),(0,L.jsx)(`span`,{children:`8`}),(0,L.jsx)(`span`,{children:`12`}),(0,L.jsx)(`span`,{children:`16`})]})]})})]}),(0,L.jsx)(`div`,{className:`card bg-base-200`,children:(0,L.jsxs)(`div`,{className:`card-body p-5 gap-3`,children:[(0,L.jsxs)(`h3`,{className:`font-semibold text-sm flex items-center gap-2`,children:[(0,L.jsx)(y,{className:`size-4 opacity-50`}),`Theme`]}),(0,L.jsx)(`div`,{className:`flex flex-wrap gap-2`,children:ie.map(e=>(0,L.jsx)(`button`,{className:`btn btn-sm ${n===e.value?`btn-primary`:`btn-soft`}`,onClick:()=>r(e.value),children:e.label},e.value))})]})})]})}function _e({config:e,launching:t}){return(0,L.jsxs)(`div`,{className:`flex flex-col items-center text-center gap-6 stagger-children py-4`,children:[(0,L.jsx)(`div`,{className:`animate-bounce-in`,children:(0,L.jsx)(P,{className:`size-16 sm:size-20 text-primary mx-auto`})}),(0,L.jsx)(`h2`,{className:`text-2xl sm:text-3xl font-bold`,children:`You're All Set!`}),(0,L.jsx)(`p`,{className:`text-base-content/60 max-w-md`,children:`Here's a summary of your configuration. Hit launch when you're ready.`}),(0,L.jsx)(`div`,{className:`card bg-base-200 w-full max-w-sm`,children:(0,L.jsxs)(`div`,{className:`card-body p-4 gap-2 text-sm text-left`,children:[(0,L.jsxs)(`div`,{className:`flex justify-between`,children:[(0,L.jsx)(`span`,{className:`text-base-content/60`,children:`Pipeline`}),(0,L.jsxs)(`span`,{className:`font-semibold capitalize text-xs font-mono`,children:[e.pipeline?.planner||`?`,` → `,e.pipeline?.executor||`?`,` → `,e.pipeline?.reviewer||`?`]})]}),(0,L.jsx)(`div`,{className:`divider my-0`}),(0,L.jsxs)(`div`,{className:`flex justify-between`,children:[(0,L.jsx)(`span`,{className:`text-base-content/60`,children:`Domains`}),(0,L.jsx)(`span`,{className:`font-semibold`,children:e.domains?.length>0?e.domains.length+` selected`:`none`})]}),(0,L.jsx)(`div`,{className:`divider my-0`}),(0,L.jsxs)(`div`,{className:`flex justify-between`,children:[(0,L.jsx)(`span`,{className:`text-base-content/60`,children:`Agents`}),(0,L.jsxs)(`span`,{className:`font-semibold`,children:[e.agents?.length||0,` to install`]})]}),(0,L.jsx)(`div`,{className:`divider my-0`}),(0,L.jsxs)(`div`,{className:`flex justify-between`,children:[(0,L.jsx)(`span`,{className:`text-base-content/60`,children:`Skills`}),(0,L.jsxs)(`span`,{className:`font-semibold`,children:[e.skills?.length||0,` to install`]})]}),(0,L.jsx)(`div`,{className:`divider my-0`}),(0,L.jsxs)(`div`,{className:`flex justify-between`,children:[(0,L.jsx)(`span`,{className:`text-base-content/60`,children:`Plan`}),(0,L.jsx)(`span`,{className:`font-semibold capitalize`,children:e.efforts.planner})]}),(0,L.jsx)(`div`,{className:`divider my-0`}),(0,L.jsxs)(`div`,{className:`flex justify-between`,children:[(0,L.jsx)(`span`,{className:`text-base-content/60`,children:`Execute`}),(0,L.jsx)(`span`,{className:`font-semibold capitalize`,children:e.efforts.executor})]}),(0,L.jsx)(`div`,{className:`divider my-0`}),(0,L.jsxs)(`div`,{className:`flex justify-between`,children:[(0,L.jsx)(`span`,{className:`text-base-content/60`,children:`Review`}),(0,L.jsx)(`span`,{className:`font-semibold capitalize`,children:e.efforts.reviewer})]}),(0,L.jsx)(`div`,{className:`divider my-0`}),(0,L.jsxs)(`div`,{className:`flex justify-between`,children:[(0,L.jsx)(`span`,{className:`text-base-content/60`,children:`Workers`}),(0,L.jsx)(`span`,{className:`font-semibold`,children:e.concurrency})]}),(0,L.jsx)(`div`,{className:`divider my-0`}),(0,L.jsxs)(`div`,{className:`flex justify-between`,children:[(0,L.jsx)(`span`,{className:`text-base-content/60`,children:`Theme`}),(0,L.jsx)(`span`,{className:`font-semibold capitalize`,children:e.theme})]})]})}),t&&(0,L.jsxs)(`div`,{className:`flex items-center gap-2 text-sm text-base-content/50`,children:[(0,L.jsx)(g,{className:`size-4 animate-spin`}),`Saving configuration & installing agents...`]})]})}function ve({onComplete:e}){let t=r(),n=u(),s=a(n.data),[d,f]=(0,I.useState)(0),[p,m]=(0,I.useState)(`forward`),[h,v]=(0,I.useState)(!1),[y,b]=(0,I.useState)(null),S=(0,I.useRef)(!1),[w,T]=(0,I.useState)(``),[E,D]=(0,I.useState)({planner:``,executor:``,reviewer:``}),[O,k]=(0,I.useState)(()=>ae(null)),[j,M]=(0,I.useState)(2),[N,F]=(0,I.useState)(`auto`),[R,z]=(0,I.useState)(null),[B,V]=(0,I.useState)(null),[H,ie]=(0,I.useState)(``),[W,K]=(0,I.useState)([]),[q,ue]=(0,I.useState)([]),[J,ve]=(0,I.useState)([]),[ye,be]=(0,I.useState)(!1),[Y,xe]=(0,I.useState)(!1),X=re(Y),Z=ne(Y)[d]||``,[Se,Ce]=(0,I.useState)(null),[we,Te]=(0,I.useState)(!1),[Ee,De]=(0,I.useState)({}),[Q,Oe]=(0,I.useState)({plan:``,execute:``,review:``}),[ke,Ae]=(0,I.useState)(``);(0,I.useEffect)(()=>{l.get(`/state`).then(e=>{Ae(e?.sourceRepoUrl||e?.config?.sourceRepo||``)}).catch(()=>{})},[]),(0,I.useEffect)(()=>{if(S.current||n.isLoading)return;S.current=!0;let e=i(s,`runtime.agentProvider`,``),t=i(s,`runtime.defaultEffort`,null),r=i(s,`ui.theme`,`auto`),a=i(s,`runtime.workerConcurrency`,2);typeof e==`string`&&e.trim()&&T(e),k(ae(t)),typeof r==`string`&&r.trim()&&F(r);let o=Number.parseInt(String(a??2),10);Number.isFinite(o)&&M(Math.min(16,Math.max(1,o)))},[s,n.isLoading]),(0,I.useEffect)(()=>{d===1&&Se===null&&(Te(!0),Promise.all([l.get(`/providers`),l.get(`/config/workflow?details=1`).catch(()=>null)]).then(([e,t])=>{let n=Array.isArray(e)?e:e?.providers||[];Ce(n);let r=t?.models||{};De(r);let i=n.filter(e=>e.available!==!1),a=i[0]?.id||i[0]?.name||``;a&&!w&&T(a);let o=i.find(e=>(e.id||e.name)===`claude`),s=a,c=o?`claude`:s,l={planner:c,executor:s,reviewer:c};D(e=>({planner:e.planner||l.planner,executor:e.executor||l.executor,reviewer:e.reviewer||l.reviewer})),Oe(e=>({plan:e.plan||r[c]?.[0]?.id||``,execute:e.execute||r[s]?.[0]?.id||``,review:e.review||r[c]?.[0]?.id||``}))}).catch(()=>{Ce([])}).finally(()=>{Te(!1)}))},[d]),(0,I.useEffect)(()=>{let e=N===`auto`?window.matchMedia(`(prefers-color-scheme: dark)`).matches?`dark`:`light`:N;document.documentElement.setAttribute(`data-theme`,e)},[N]),(0,I.useEffect)(()=>{E.executor&&E.executor!==w&&T(E.executor)},[E.executor]);let je=(0,I.useCallback)(e=>{if(e===`Providers`){let e=[{provider:E.planner,role:`planner`},{provider:E.executor,role:`executor`},{provider:E.reviewer,role:`reviewer`}];U(`runtime.agentProvider`,E.executor,`runtime`).catch(()=>{}),U(`runtime.pipeline`,e,`runtime`).catch(()=>{}),U(`runtime.workflowConfig`,G(E,O,Q),`runtime`).catch(()=>{})}else e===`Effort`?(U(`runtime.defaultEffort`,O,`runtime`).catch(()=>{}),U(`runtime.workflowConfig`,G(E,O,Q),`runtime`).catch(()=>{})):e===`Workers & Theme`&&(U(`ui.theme`,N,`ui`).catch(()=>{}),l.post(`/config/concurrency`,{concurrency:j}).catch(()=>{}))},[E,O,Q,j,N]),$=(0,I.useCallback)(()=>{d<X-1&&(je(Z),m(`forward`),f(e=>e+1))},[d,X,Z,je]),Me=(0,I.useCallback)(()=>{d>0&&(m(`backward`),f(e=>e-1))},[d]),Ne=(0,I.useCallback)(async()=>{v(!0);try{let n=[U(`ui.theme`,N,`ui`),U(`ui.onboarding.completed`,!0,`ui`)],r=[{provider:E.planner,role:`planner`},{provider:E.executor,role:`executor`},{provider:E.reviewer,role:`reviewer`}];n.push(U(`runtime.agentProvider`,E.executor,`runtime`)),n.push(U(`runtime.pipeline`,r,`runtime`)),n.push(U(`runtime.workflowConfig`,G(E,O),`runtime`)),n.push(U(`runtime.defaultEffort`,O,`runtime`)),n.push(U(`runtime.workflowConfig`,G(E,O,Q),`runtime`)),n.push(l.post(`/config/concurrency`,{concurrency:j})),q.length>0&&n.push(l.post(`/install/agents`,{agents:q})),J.length>0&&n.push(l.post(`/install/skills`,{skills:J})),await Promise.allSettled(n),t.setQueryData(o,e=>c(e,{id:`ui.onboarding.completed`,scope:`ui`,value:!0,source:`user`,updatedAt:new Date().toISOString()})),b({x:window.innerWidth/2,y:window.innerHeight/3}),setTimeout(()=>{t.invalidateQueries({queryKey:o}),e?.()},1200)}catch{t.setQueryData(o,e=>c(e,{id:`ui.onboarding.completed`,scope:`ui`,value:!0,source:`user`,updatedAt:new Date().toISOString()})),await U(`ui.onboarding.completed`,!0,`ui`).catch(()=>{}),t.invalidateQueries({queryKey:o}),e?.()}},[E,w,O,Q,j,N,q,J,t,e]),Pe=Z===`Welcome`||Z===`Providers`&&(E.executor||we)||Z===`Scan Project`||Z===`Discover Issues`||Z===`Domains`||Z===`Agents & Skills`||Z===`Effort`||Z===`Workers & Theme`||Z===`Launch`,Fe=(R?.existingAgents||[]).map(e=>typeof e==`string`?{name:e}:e),Ie=(R?.existingSkills||[]).map(e=>typeof e==`string`?{name:e}:e),Le={pipeline:E,efforts:O,concurrency:j,theme:N,domains:W,agents:q,skills:J};return(0,L.jsxs)(`div`,{className:`fixed inset-0 z-50 bg-base-100 flex flex-col overflow-hidden`,children:[(0,L.jsx)(x,{}),y&&(0,L.jsx)(C,{x:y.x,y:y.y,active:!0,onDone:()=>b(null)}),d>0&&(0,L.jsx)(`div`,{className:`relative z-10 pt-6 pb-2 px-4 flex justify-center`,children:(0,L.jsx)(oe,{current:d,wantsDiscovery:Y})}),(0,L.jsx)(`div`,{className:`relative z-10 flex-1 flex flex-col items-center justify-start px-4 py-6 overflow-y-auto`,children:(0,L.jsxs)(se,{direction:p,stepKey:d,center:Z===`Welcome`||Z===`Providers`||Z===`Launch`,children:[Z===`Welcome`&&(0,L.jsx)(le,{workspacePath:ke,onGetStarted:$}),Z===`Providers`&&(0,L.jsx)(de,{providers:Se||[],providersLoading:we,pipeline:E,setPipeline:D}),Z===`Scan Project`&&(0,L.jsxs)(L.Fragment,{children:[(0,L.jsx)(fe,{scanResult:R,setScanResult:z,projectDescription:H,setProjectDescription:ie,analysisResult:B,setAnalysisResult:V,selectedProvider:w,analyzing:ye,setAnalyzing:be}),(0,L.jsx)(`div`,{className:`mt-4 w-full max-w-lg`,children:(0,L.jsxs)(`label`,{className:`flex items-center gap-3 cursor-pointer p-3 rounded-lg bg-base-200/50 border border-base-300/50 hover:border-primary/30 transition-colors`,children:[(0,L.jsx)(`input`,{type:`checkbox`,className:`toggle toggle-primary toggle-sm`,checked:Y,onChange:e=>xe(e.target.checked)}),(0,L.jsxs)(`div`,{className:`flex-1`,children:[(0,L.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,L.jsx)(_,{className:`size-4 text-primary`}),(0,L.jsx)(`span`,{className:`text-sm font-medium`,children:`Discover existing issues`})]}),(0,L.jsx)(`p`,{className:`text-xs text-base-content/50 mt-0.5`,children:`Scan for TODOs, FIXMEs, and GitHub issues to import`})]})]})}),(0,L.jsx)(`div`,{className:`mt-3 w-full max-w-lg`,children:(0,L.jsx)(ce,{})})]}),Z===`Discover Issues`&&(0,L.jsx)(ee,{}),Z===`Domains`&&(0,L.jsx)(pe,{selectedDomains:W,setSelectedDomains:K,analysisResult:B}),Z===`Agents & Skills`&&(0,L.jsx)(me,{selectedDomains:W,selectedAgents:q,setSelectedAgents:ue,selectedSkills:J,setSelectedSkills:ve,existingAgents:Fe,existingSkills:Ie}),Z===`Effort`&&(0,L.jsx)(he,{efforts:O,setEfforts:k,pipeline:E,models:Q,setModels:Oe,modelsByProvider:Ee}),Z===`Workers & Theme`&&(0,L.jsx)(ge,{concurrency:j,setConcurrency:M,selectedTheme:N,setSelectedTheme:F}),Z===`Launch`&&(0,L.jsx)(_e,{config:Le,launching:h})]})}),d>0&&(0,L.jsxs)(`div`,{className:`relative z-10 p-4 pb-6 flex items-center max-w-2xl mx-auto w-full justify-between`,children:[d>0&&(0,L.jsxs)(`button`,{className:`btn btn-ghost gap-1`,onClick:Me,disabled:h,children:[(0,L.jsx)(te,{className:`size-4`}),` Back`]}),d<X-1?(0,L.jsxs)(`button`,{className:`btn btn-primary gap-1`,onClick:$,disabled:!Pe,children:[Z===`Discover Issues`?`Continue`:`Next`,` `,(0,L.jsx)(A,{className:`size-4`})]}):(0,L.jsx)(`button`,{className:`btn btn-primary btn-lg gap-2 animate-pulse-soft`,onClick:Ne,disabled:h,children:h?(0,L.jsxs)(L.Fragment,{children:[(0,L.jsx)(g,{className:`size-5 animate-spin`}),` Launching...`]}):(0,L.jsxs)(L.Fragment,{children:[(0,L.jsx)(P,{className:`size-5`}),` Launch Fifony`]})})]})]})}export{ve as default};
@@ -1 +1 @@
1
- import{n as e}from"./rolldown-runtime-DF2fYuay.js";import{I as t,a as n,h as r}from"./vendor-BoGBoEwT.js";import{d as i,t as a,x as o}from"./zap-BwZ-sPG7.js";import{C as s,_ as c,f as l,o as u,v as d}from"./index-BdrTN_Wj.js";var f=e(t(),1),p=r();function m(e){return!e||e===0?`0`:e>=1e6?`${(e/1e6).toFixed(1)}M`:e>=1e3?`${(e/1e3).toFixed(1)}K`:String(e)}function h(e){return!e||e===0?`0`:e.toLocaleString()}function g({value:e,format:t=m,className:n=``}){let[r,i]=(0,f.useState)(()=>t(e)),a=(0,f.useRef)(e),o=(0,f.useRef)(null);return(0,f.useEffect)(()=>{let n=a.current||0,r=e||0;if(a.current=r,n===r){i(t(r));return}let s=performance.now(),c=e=>{let a=e-s,l=Math.min(a/600,1),u=1-(1-l)**3,d=n+(r-n)*u;i(t(Math.round(d))),l<1&&(o.current=requestAnimationFrame(c))};return cancelAnimationFrame(o.current),o.current=requestAnimationFrame(c),()=>cancelAnimationFrame(o.current)},[e,t]),(0,p.jsx)(`span`,{className:`${n} inline-block tabular-nums`,children:r})}var _=[{key:`planner`,label:`Plan`,color:`bg-info`,textColor:`text-info`},{key:`executor`,label:`Execute`,color:`bg-primary`,textColor:`text-primary`},{key:`reviewer`,label:`Review`,color:`bg-secondary`,textColor:`text-secondary`}];function v({byPhase:e}){if(!e)return null;let t=_.reduce((t,n)=>t+(e[n.key]?.totalTokens||0),0);return t===0?null:(0,p.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,p.jsx)(`div`,{className:`flex h-4 rounded-full overflow-hidden bg-base-300 w-full`,children:_.map(n=>{let r=e[n.key]?.totalTokens||0,i=r/t*100;return i===0?null:(0,p.jsx)(`div`,{className:`${n.color} opacity-80 transition-all duration-500`,style:{width:`${i}%`},title:`${n.label}: ${h(r)} (${Math.round(i)}%)`},n.key)})}),(0,p.jsx)(`div`,{className:`flex items-center gap-4 flex-wrap`,children:_.map(n=>{let r=e[n.key]?.totalTokens||0,i=t>0?Math.round(r/t*100):0;return r===0?null:(0,p.jsxs)(`span`,{className:`flex items-center gap-1.5 text-sm`,children:[(0,p.jsx)(`span`,{className:`inline-block w-3 h-3 rounded-full ${n.color} shrink-0`}),(0,p.jsx)(`span`,{className:`opacity-60`,children:n.label}),(0,p.jsx)(`span`,{className:`font-mono font-semibold`,children:m(r)}),(0,p.jsxs)(`span`,{className:`opacity-40`,children:[`(`,i,`%)`]})]},n.key)})})]})}function y({data:e,height:t=160}){if(!e||e.length===0)return null;let n=Math.max(...e.map(e=>e.totalTokens||0),1);return(0,p.jsx)(`div`,{className:`flex items-end gap-2 w-full`,style:{height:t},children:e.map((e,r)=>{let i=e.totalTokens||0,a=Math.max(2,Math.round(i/n*t)),o=e.date?new Date(e.date+`T00:00:00`).toLocaleDateString(void 0,{weekday:`short`,month:`short`,day:`numeric`}):`Day ${r+1}`,s=e.date?new Date(e.date+`T00:00:00`).toLocaleDateString(void 0,{weekday:`short`}):`${r+1}`;return(0,p.jsxs)(`div`,{className:`flex-1 flex flex-col items-center gap-1.5 group`,children:[(0,p.jsx)(`span`,{className:`text-[10px] font-mono opacity-0 group-hover:opacity-70 transition-opacity`,children:m(i)}),(0,p.jsx)(`div`,{className:`w-full bg-primary rounded-t-md opacity-70 hover:opacity-100 transition-all duration-300 cursor-default`,style:{height:a},title:`${o}: ${h(i)} tokens`}),(0,p.jsx)(`span`,{className:`text-[10px] opacity-50`,children:s})]},e.date||r)})})}function b({data:e,valueKey:t=`totalTokens`,height:n=60,color:r=`stroke-primary`,label:i}){if(!e||e.length===0)return null;let a=e.map(e=>e[t]||e.count||0),o=Math.max(...a,1),s=a.map((e,t)=>`${t/Math.max(a.length-1,1)*200},${n-e/o*(n-4)-2}`).join(` `),c=a.reduce((e,t)=>e+t,0),l=a.length>0?Math.round(c/a.length):0,u=Math.max(...a);return(0,p.jsxs)(`div`,{className:`flex flex-col gap-2 flex-1 min-w-0`,children:[(0,p.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,p.jsx)(`span`,{className:`text-xs font-medium opacity-60`,children:i}),(0,p.jsxs)(`span`,{className:`flex items-center gap-3 text-[10px] opacity-50`,children:[(0,p.jsxs)(`span`,{children:[`avg: `,(0,p.jsxs)(`span`,{className:`font-mono`,children:[m(l),`/h`]})]}),(0,p.jsxs)(`span`,{children:[`peak: `,(0,p.jsxs)(`span`,{className:`font-mono`,children:[m(u),`/h`]})]})]})]}),(0,p.jsxs)(`svg`,{viewBox:`0 0 200 ${n}`,className:`w-full`,style:{height:n},preserveAspectRatio:`none`,children:[(0,p.jsx)(`polyline`,{points:`0,${n} ${s} 200,${n}`,fill:`currentColor`,className:r.replace(`stroke-`,`text-`),opacity:`0.08`}),(0,p.jsx)(`polyline`,{points:s,fill:`none`,className:r,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,vectorEffect:`non-scaling-stroke`})]})]})}function x({byModel:e}){if(!e)return null;let t=Object.entries(e).map(([e,t])=>({model:e,inputTokens:t?.inputTokens||0,outputTokens:t?.outputTokens||0,totalTokens:t?.totalTokens||0})).sort((e,t)=>t.totalTokens-e.totalTokens);if(t.length===0)return null;let n=t.reduce((e,t)=>e+t.totalTokens,0);return(0,p.jsx)(`div`,{className:`overflow-x-auto`,children:(0,p.jsxs)(`table`,{className:`table table-sm`,children:[(0,p.jsx)(`thead`,{children:(0,p.jsxs)(`tr`,{children:[(0,p.jsx)(`th`,{children:`Model`}),(0,p.jsx)(`th`,{className:`text-right`,children:`Input`}),(0,p.jsx)(`th`,{className:`text-right`,children:`Output`}),(0,p.jsx)(`th`,{className:`text-right`,children:`Total`}),(0,p.jsx)(`th`,{className:`text-right`,children:`Share`})]})}),(0,p.jsx)(`tbody`,{children:t.map(e=>{let t=n>0?Math.round(e.totalTokens/n*100):0,r=e.model.includes(`claude`)?`bg-primary`:e.model.includes(`codex`)?`bg-secondary`:`bg-accent`;return(0,p.jsxs)(`tr`,{children:[(0,p.jsxs)(`td`,{className:`flex items-center gap-2`,children:[(0,p.jsx)(`span`,{className:`inline-block w-2.5 h-2.5 rounded-full ${r} shrink-0`}),(0,p.jsx)(`span`,{className:`font-mono text-xs`,children:e.model})]}),(0,p.jsx)(`td`,{className:`text-right font-mono text-xs`,children:m(e.inputTokens)}),(0,p.jsx)(`td`,{className:`text-right font-mono text-xs`,children:m(e.outputTokens)}),(0,p.jsx)(`td`,{className:`text-right font-mono text-xs font-semibold`,children:m(e.totalTokens)}),(0,p.jsx)(`td`,{className:`text-right`,children:(0,p.jsxs)(`div`,{className:`flex items-center justify-end gap-1.5`,children:[(0,p.jsx)(`div`,{className:`w-12 h-1.5 bg-base-300 rounded-full overflow-hidden`,children:(0,p.jsx)(`div`,{className:`h-full ${r} rounded-full`,style:{width:`${t}%`}})}),(0,p.jsxs)(`span`,{className:`text-xs opacity-60 w-8 text-right`,children:[t,`%`]})]})})]},e.model)})})]})})}function S({topIssues:e}){return!e||e.length===0?null:(0,p.jsx)(`div`,{className:`overflow-x-auto`,children:(0,p.jsxs)(`table`,{className:`table table-sm`,children:[(0,p.jsx)(`thead`,{children:(0,p.jsxs)(`tr`,{children:[(0,p.jsx)(`th`,{className:`w-20`,children:`Issue`}),(0,p.jsx)(`th`,{children:`Title`}),(0,p.jsx)(`th`,{className:`text-right`,children:`Tokens`}),(0,p.jsx)(`th`,{className:`hidden sm:table-cell`,children:`Phase Split`})]})}),(0,p.jsx)(`tbody`,{children:e.slice(0,10).map(e=>{let t=e.byPhase,n=e.totalTokens||0;return(0,p.jsxs)(`tr`,{children:[(0,p.jsx)(`td`,{className:`font-mono text-xs font-semibold text-primary`,children:e.identifier}),(0,p.jsx)(`td`,{className:`max-w-[200px] truncate text-sm`,title:e.title,children:e.title||`-`}),(0,p.jsx)(`td`,{className:`text-right font-mono text-xs font-semibold`,children:m(n)}),(0,p.jsx)(`td`,{className:`hidden sm:table-cell`,children:t?(0,p.jsx)(`div`,{className:`flex h-1.5 rounded-full overflow-hidden bg-base-300 w-24`,children:_.map(e=>{let r=t[e.key]?.totalTokens||0,i=n>0?r/n*100:0;return i===0?null:(0,p.jsx)(`div`,{className:`${e.color} opacity-80`,style:{width:`${i}%`},title:`${e.label}: ${m(r)}`},e.key)})}):(0,p.jsx)(`span`,{className:`opacity-30 text-xs`,children:`-`})})]},e.id||e.identifier)})})]})})}function C(){return(0,p.jsx)(`div`,{className:`flex-1 flex flex-col min-h-0 px-4 pb-4 pt-3`,children:(0,p.jsxs)(`div`,{className:`max-w-6xl w-full mx-auto space-y-6`,children:[(0,p.jsx)(`div`,{className:`skeleton-line h-8 w-48`}),(0,p.jsx)(`div`,{className:`grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4`,children:[...[,,,]].map((e,t)=>(0,p.jsx)(`div`,{className:`skeleton-card h-28`,style:{animationDelay:`${t*80}ms`}},t))}),(0,p.jsx)(`div`,{className:`skeleton-card h-52`}),(0,p.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-4`,children:[(0,p.jsx)(`div`,{className:`skeleton-card h-32`}),(0,p.jsx)(`div`,{className:`skeleton-card h-32`})]}),(0,p.jsx)(`div`,{className:`skeleton-card h-64`})]})})}function w(){return(0,p.jsxs)(`div`,{className:`flex-1 flex flex-col items-center justify-center gap-4 px-4 pb-20 animate-fade-in`,children:[(0,p.jsx)(u,{className:`size-16 opacity-15`}),(0,p.jsx)(`h2`,{className:`text-lg font-semibold opacity-60`,children:`No analytics data yet`}),(0,p.jsx)(`p`,{className:`text-sm opacity-40 text-center max-w-md`,children:`Token usage and pipeline metrics will appear here once issues start processing.`})]})}var T=n(`/analytics`)({component:E});function E(){let{data:e,isLoading:t}=o(),{data:n,isLoading:r}=i(24);if(t&&!e)return(0,p.jsx)(C,{});let f=e?.overall?.totalTokens||0,_=e?.byPhase||null,T=e?.byModel||{},E=e?.daily||[],D=e?.topIssues||[],O=n?.tokensPerHour||[],k=n?.eventsPerHour||[],A=new Date().toISOString().slice(0,10),j=E.find(e=>e.date===A)?.totalTokens||0,M=E.reduce((e,t)=>e+(t.totalTokens||0),0);return f===0&&E.length===0&&D.length===0?(0,p.jsx)(w,{}):(0,p.jsx)(`div`,{className:`flex-1 flex flex-col min-h-0 px-4 pb-4 pt-3 overflow-y-auto`,children:(0,p.jsxs)(`div`,{className:`max-w-6xl w-full mx-auto space-y-6 stagger-children`,children:[(0,p.jsx)(`section`,{children:(0,p.jsxs)(`div`,{className:`grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4`,children:[(0,p.jsxs)(`div`,{className:`stat bg-base-200 rounded-box`,children:[(0,p.jsx)(`div`,{className:`stat-figure text-primary`,children:(0,p.jsx)(a,{className:`size-6`})}),(0,p.jsx)(`div`,{className:`stat-title`,children:`Total Tokens`}),(0,p.jsx)(`div`,{className:`stat-value text-2xl`,children:(0,p.jsx)(g,{value:f})}),(0,p.jsx)(`div`,{className:`stat-desc font-mono`,children:h(f)})]}),(0,p.jsxs)(`div`,{className:`stat bg-base-200 rounded-box`,children:[(0,p.jsx)(`div`,{className:`stat-figure text-accent`,children:(0,p.jsx)(d,{className:`size-6`})}),(0,p.jsx)(`div`,{className:`stat-title`,children:`Today`}),(0,p.jsx)(`div`,{className:`stat-value text-2xl`,children:(0,p.jsx)(g,{value:j})}),(0,p.jsxs)(`div`,{className:`stat-desc`,children:[`This week: `,m(M)]})]}),(0,p.jsxs)(`div`,{className:`stat bg-base-200 rounded-box`,children:[(0,p.jsx)(`div`,{className:`stat-figure text-info`,children:(0,p.jsx)(l,{className:`size-6`})}),(0,p.jsx)(`div`,{className:`stat-title`,children:`Phase Split`}),(0,p.jsx)(`div`,{className:`stat-value text-2xl p-0`,children:_?(0,p.jsx)(v,{byPhase:_}):(0,p.jsx)(`span`,{className:`opacity-30`,children:`-`})})]})]})}),E.length>0&&(0,p.jsxs)(`section`,{className:`bg-base-200 rounded-box p-5`,children:[(0,p.jsxs)(`div`,{className:`flex items-center justify-between mb-4`,children:[(0,p.jsxs)(`h2`,{className:`text-sm font-semibold flex items-center gap-2`,children:[(0,p.jsx)(u,{className:`size-4 text-primary`}),`Daily Token Usage`]}),(0,p.jsxs)(`span`,{className:`text-xs opacity-40`,children:[`Last `,E.length,` days`]})]}),(0,p.jsx)(y,{data:E,height:160})]}),(O.length>0||k.length>0)&&(0,p.jsxs)(`section`,{className:`bg-base-200 rounded-box p-5`,children:[(0,p.jsxs)(`h2`,{className:`text-sm font-semibold flex items-center gap-2 mb-4`,children:[(0,p.jsx)(s,{className:`size-4 text-secondary`}),`Hourly Activity (last 24h)`]}),(0,p.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-6`,children:[O.length>0&&(0,p.jsx)(b,{data:O,valueKey:`totalTokens`,height:60,color:`stroke-primary`,label:`Tokens / hour`}),k.length>0&&(0,p.jsx)(b,{data:k,valueKey:`count`,height:60,color:`stroke-secondary`,label:`Events / hour`})]})]}),D.length>0&&(0,p.jsxs)(`section`,{className:`bg-base-200 rounded-box p-5`,children:[(0,p.jsxs)(`h2`,{className:`text-sm font-semibold flex items-center gap-2 mb-4`,children:[(0,p.jsx)(a,{className:`size-4 text-accent`}),`Top Issues by Token Usage`]}),(0,p.jsx)(S,{topIssues:D})]}),Object.keys(T).length>0&&(0,p.jsxs)(`section`,{className:`bg-base-200 rounded-box p-5`,children:[(0,p.jsxs)(`h2`,{className:`text-sm font-semibold flex items-center gap-2 mb-4`,children:[(0,p.jsx)(c,{className:`size-4 text-info`}),`Model Breakdown`]}),(0,p.jsx)(x,{byModel:T})]})]})})}export{T as Route};
1
+ import{n as e}from"./rolldown-runtime-DF2fYuay.js";import{I as t,a as n,h as r}from"./vendor-BoGBoEwT.js";import{d as i,t as a,x as o}from"./zap-BwZ-sPG7.js";import{C as s,_ as c,f as l,o as u,v as d}from"./index-BRWIoM5k.js";var f=e(t(),1),p=r();function m(e){return!e||e===0?`0`:e>=1e6?`${(e/1e6).toFixed(1)}M`:e>=1e3?`${(e/1e3).toFixed(1)}K`:String(e)}function h(e){return!e||e===0?`0`:e.toLocaleString()}function g({value:e,format:t=m,className:n=``}){let[r,i]=(0,f.useState)(()=>t(e)),a=(0,f.useRef)(e),o=(0,f.useRef)(null);return(0,f.useEffect)(()=>{let n=a.current||0,r=e||0;if(a.current=r,n===r){i(t(r));return}let s=performance.now(),c=e=>{let a=e-s,l=Math.min(a/600,1),u=1-(1-l)**3,d=n+(r-n)*u;i(t(Math.round(d))),l<1&&(o.current=requestAnimationFrame(c))};return cancelAnimationFrame(o.current),o.current=requestAnimationFrame(c),()=>cancelAnimationFrame(o.current)},[e,t]),(0,p.jsx)(`span`,{className:`${n} inline-block tabular-nums`,children:r})}var _=[{key:`planner`,label:`Plan`,color:`bg-info`,textColor:`text-info`},{key:`executor`,label:`Execute`,color:`bg-primary`,textColor:`text-primary`},{key:`reviewer`,label:`Review`,color:`bg-secondary`,textColor:`text-secondary`}];function v({byPhase:e}){if(!e)return null;let t=_.reduce((t,n)=>t+(e[n.key]?.totalTokens||0),0);return t===0?null:(0,p.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,p.jsx)(`div`,{className:`flex h-4 rounded-full overflow-hidden bg-base-300 w-full`,children:_.map(n=>{let r=e[n.key]?.totalTokens||0,i=r/t*100;return i===0?null:(0,p.jsx)(`div`,{className:`${n.color} opacity-80 transition-all duration-500`,style:{width:`${i}%`},title:`${n.label}: ${h(r)} (${Math.round(i)}%)`},n.key)})}),(0,p.jsx)(`div`,{className:`flex items-center gap-4 flex-wrap`,children:_.map(n=>{let r=e[n.key]?.totalTokens||0,i=t>0?Math.round(r/t*100):0;return r===0?null:(0,p.jsxs)(`span`,{className:`flex items-center gap-1.5 text-sm`,children:[(0,p.jsx)(`span`,{className:`inline-block w-3 h-3 rounded-full ${n.color} shrink-0`}),(0,p.jsx)(`span`,{className:`opacity-60`,children:n.label}),(0,p.jsx)(`span`,{className:`font-mono font-semibold`,children:m(r)}),(0,p.jsxs)(`span`,{className:`opacity-40`,children:[`(`,i,`%)`]})]},n.key)})})]})}function y({data:e,height:t=160}){if(!e||e.length===0)return null;let n=Math.max(...e.map(e=>e.totalTokens||0),1);return(0,p.jsx)(`div`,{className:`flex items-end gap-2 w-full`,style:{height:t},children:e.map((e,r)=>{let i=e.totalTokens||0,a=Math.max(2,Math.round(i/n*t)),o=e.date?new Date(e.date+`T00:00:00`).toLocaleDateString(void 0,{weekday:`short`,month:`short`,day:`numeric`}):`Day ${r+1}`,s=e.date?new Date(e.date+`T00:00:00`).toLocaleDateString(void 0,{weekday:`short`}):`${r+1}`;return(0,p.jsxs)(`div`,{className:`flex-1 flex flex-col items-center gap-1.5 group`,children:[(0,p.jsx)(`span`,{className:`text-[10px] font-mono opacity-0 group-hover:opacity-70 transition-opacity`,children:m(i)}),(0,p.jsx)(`div`,{className:`w-full bg-primary rounded-t-md opacity-70 hover:opacity-100 transition-all duration-300 cursor-default`,style:{height:a},title:`${o}: ${h(i)} tokens`}),(0,p.jsx)(`span`,{className:`text-[10px] opacity-50`,children:s})]},e.date||r)})})}function b({data:e,valueKey:t=`totalTokens`,height:n=60,color:r=`stroke-primary`,label:i}){if(!e||e.length===0)return null;let a=e.map(e=>e[t]||e.count||0),o=Math.max(...a,1),s=a.map((e,t)=>`${t/Math.max(a.length-1,1)*200},${n-e/o*(n-4)-2}`).join(` `),c=a.reduce((e,t)=>e+t,0),l=a.length>0?Math.round(c/a.length):0,u=Math.max(...a);return(0,p.jsxs)(`div`,{className:`flex flex-col gap-2 flex-1 min-w-0`,children:[(0,p.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,p.jsx)(`span`,{className:`text-xs font-medium opacity-60`,children:i}),(0,p.jsxs)(`span`,{className:`flex items-center gap-3 text-[10px] opacity-50`,children:[(0,p.jsxs)(`span`,{children:[`avg: `,(0,p.jsxs)(`span`,{className:`font-mono`,children:[m(l),`/h`]})]}),(0,p.jsxs)(`span`,{children:[`peak: `,(0,p.jsxs)(`span`,{className:`font-mono`,children:[m(u),`/h`]})]})]})]}),(0,p.jsxs)(`svg`,{viewBox:`0 0 200 ${n}`,className:`w-full`,style:{height:n},preserveAspectRatio:`none`,children:[(0,p.jsx)(`polyline`,{points:`0,${n} ${s} 200,${n}`,fill:`currentColor`,className:r.replace(`stroke-`,`text-`),opacity:`0.08`}),(0,p.jsx)(`polyline`,{points:s,fill:`none`,className:r,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,vectorEffect:`non-scaling-stroke`})]})]})}function x({byModel:e}){if(!e)return null;let t=Object.entries(e).map(([e,t])=>({model:e,inputTokens:t?.inputTokens||0,outputTokens:t?.outputTokens||0,totalTokens:t?.totalTokens||0})).sort((e,t)=>t.totalTokens-e.totalTokens);if(t.length===0)return null;let n=t.reduce((e,t)=>e+t.totalTokens,0);return(0,p.jsx)(`div`,{className:`overflow-x-auto`,children:(0,p.jsxs)(`table`,{className:`table table-sm`,children:[(0,p.jsx)(`thead`,{children:(0,p.jsxs)(`tr`,{children:[(0,p.jsx)(`th`,{children:`Model`}),(0,p.jsx)(`th`,{className:`text-right`,children:`Input`}),(0,p.jsx)(`th`,{className:`text-right`,children:`Output`}),(0,p.jsx)(`th`,{className:`text-right`,children:`Total`}),(0,p.jsx)(`th`,{className:`text-right`,children:`Share`})]})}),(0,p.jsx)(`tbody`,{children:t.map(e=>{let t=n>0?Math.round(e.totalTokens/n*100):0,r=e.model.includes(`claude`)?`bg-primary`:e.model.includes(`codex`)?`bg-secondary`:`bg-accent`;return(0,p.jsxs)(`tr`,{children:[(0,p.jsxs)(`td`,{className:`flex items-center gap-2`,children:[(0,p.jsx)(`span`,{className:`inline-block w-2.5 h-2.5 rounded-full ${r} shrink-0`}),(0,p.jsx)(`span`,{className:`font-mono text-xs`,children:e.model})]}),(0,p.jsx)(`td`,{className:`text-right font-mono text-xs`,children:m(e.inputTokens)}),(0,p.jsx)(`td`,{className:`text-right font-mono text-xs`,children:m(e.outputTokens)}),(0,p.jsx)(`td`,{className:`text-right font-mono text-xs font-semibold`,children:m(e.totalTokens)}),(0,p.jsx)(`td`,{className:`text-right`,children:(0,p.jsxs)(`div`,{className:`flex items-center justify-end gap-1.5`,children:[(0,p.jsx)(`div`,{className:`w-12 h-1.5 bg-base-300 rounded-full overflow-hidden`,children:(0,p.jsx)(`div`,{className:`h-full ${r} rounded-full`,style:{width:`${t}%`}})}),(0,p.jsxs)(`span`,{className:`text-xs opacity-60 w-8 text-right`,children:[t,`%`]})]})})]},e.model)})})]})})}function S({topIssues:e}){return!e||e.length===0?null:(0,p.jsx)(`div`,{className:`overflow-x-auto`,children:(0,p.jsxs)(`table`,{className:`table table-sm`,children:[(0,p.jsx)(`thead`,{children:(0,p.jsxs)(`tr`,{children:[(0,p.jsx)(`th`,{className:`w-20`,children:`Issue`}),(0,p.jsx)(`th`,{children:`Title`}),(0,p.jsx)(`th`,{className:`text-right`,children:`Tokens`}),(0,p.jsx)(`th`,{className:`hidden sm:table-cell`,children:`Phase Split`})]})}),(0,p.jsx)(`tbody`,{children:e.slice(0,10).map(e=>{let t=e.byPhase,n=e.totalTokens||0;return(0,p.jsxs)(`tr`,{children:[(0,p.jsx)(`td`,{className:`font-mono text-xs font-semibold text-primary`,children:e.identifier}),(0,p.jsx)(`td`,{className:`max-w-[200px] truncate text-sm`,title:e.title,children:e.title||`-`}),(0,p.jsx)(`td`,{className:`text-right font-mono text-xs font-semibold`,children:m(n)}),(0,p.jsx)(`td`,{className:`hidden sm:table-cell`,children:t?(0,p.jsx)(`div`,{className:`flex h-1.5 rounded-full overflow-hidden bg-base-300 w-24`,children:_.map(e=>{let r=t[e.key]?.totalTokens||0,i=n>0?r/n*100:0;return i===0?null:(0,p.jsx)(`div`,{className:`${e.color} opacity-80`,style:{width:`${i}%`},title:`${e.label}: ${m(r)}`},e.key)})}):(0,p.jsx)(`span`,{className:`opacity-30 text-xs`,children:`-`})})]},e.id||e.identifier)})})]})})}function C(){return(0,p.jsx)(`div`,{className:`flex-1 flex flex-col min-h-0 px-4 pb-4 pt-3`,children:(0,p.jsxs)(`div`,{className:`max-w-6xl w-full mx-auto space-y-6`,children:[(0,p.jsx)(`div`,{className:`skeleton-line h-8 w-48`}),(0,p.jsx)(`div`,{className:`grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4`,children:[...[,,,]].map((e,t)=>(0,p.jsx)(`div`,{className:`skeleton-card h-28`,style:{animationDelay:`${t*80}ms`}},t))}),(0,p.jsx)(`div`,{className:`skeleton-card h-52`}),(0,p.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-4`,children:[(0,p.jsx)(`div`,{className:`skeleton-card h-32`}),(0,p.jsx)(`div`,{className:`skeleton-card h-32`})]}),(0,p.jsx)(`div`,{className:`skeleton-card h-64`})]})})}function w(){return(0,p.jsxs)(`div`,{className:`flex-1 flex flex-col items-center justify-center gap-4 px-4 pb-20 animate-fade-in`,children:[(0,p.jsx)(u,{className:`size-16 opacity-15`}),(0,p.jsx)(`h2`,{className:`text-lg font-semibold opacity-60`,children:`No analytics data yet`}),(0,p.jsx)(`p`,{className:`text-sm opacity-40 text-center max-w-md`,children:`Token usage and pipeline metrics will appear here once issues start processing.`})]})}var T=n(`/analytics`)({component:E});function E(){let{data:e,isLoading:t}=o(),{data:n,isLoading:r}=i(24);if(t&&!e)return(0,p.jsx)(C,{});let f=e?.overall?.totalTokens||0,_=e?.byPhase||null,T=e?.byModel||{},E=e?.daily||[],D=e?.topIssues||[],O=n?.tokensPerHour||[],k=n?.eventsPerHour||[],A=new Date().toISOString().slice(0,10),j=E.find(e=>e.date===A)?.totalTokens||0,M=E.reduce((e,t)=>e+(t.totalTokens||0),0);return f===0&&E.length===0&&D.length===0?(0,p.jsx)(w,{}):(0,p.jsx)(`div`,{className:`flex-1 flex flex-col min-h-0 px-4 pb-4 pt-3 overflow-y-auto`,children:(0,p.jsxs)(`div`,{className:`max-w-6xl w-full mx-auto space-y-6 stagger-children`,children:[(0,p.jsx)(`section`,{children:(0,p.jsxs)(`div`,{className:`grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4`,children:[(0,p.jsxs)(`div`,{className:`stat bg-base-200 rounded-box`,children:[(0,p.jsx)(`div`,{className:`stat-figure text-primary`,children:(0,p.jsx)(a,{className:`size-6`})}),(0,p.jsx)(`div`,{className:`stat-title`,children:`Total Tokens`}),(0,p.jsx)(`div`,{className:`stat-value text-2xl`,children:(0,p.jsx)(g,{value:f})}),(0,p.jsx)(`div`,{className:`stat-desc font-mono`,children:h(f)})]}),(0,p.jsxs)(`div`,{className:`stat bg-base-200 rounded-box`,children:[(0,p.jsx)(`div`,{className:`stat-figure text-accent`,children:(0,p.jsx)(d,{className:`size-6`})}),(0,p.jsx)(`div`,{className:`stat-title`,children:`Today`}),(0,p.jsx)(`div`,{className:`stat-value text-2xl`,children:(0,p.jsx)(g,{value:j})}),(0,p.jsxs)(`div`,{className:`stat-desc`,children:[`This week: `,m(M)]})]}),(0,p.jsxs)(`div`,{className:`stat bg-base-200 rounded-box`,children:[(0,p.jsx)(`div`,{className:`stat-figure text-info`,children:(0,p.jsx)(l,{className:`size-6`})}),(0,p.jsx)(`div`,{className:`stat-title`,children:`Phase Split`}),(0,p.jsx)(`div`,{className:`stat-value text-2xl p-0`,children:_?(0,p.jsx)(v,{byPhase:_}):(0,p.jsx)(`span`,{className:`opacity-30`,children:`-`})})]})]})}),E.length>0&&(0,p.jsxs)(`section`,{className:`bg-base-200 rounded-box p-5`,children:[(0,p.jsxs)(`div`,{className:`flex items-center justify-between mb-4`,children:[(0,p.jsxs)(`h2`,{className:`text-sm font-semibold flex items-center gap-2`,children:[(0,p.jsx)(u,{className:`size-4 text-primary`}),`Daily Token Usage`]}),(0,p.jsxs)(`span`,{className:`text-xs opacity-40`,children:[`Last `,E.length,` days`]})]}),(0,p.jsx)(y,{data:E,height:160})]}),(O.length>0||k.length>0)&&(0,p.jsxs)(`section`,{className:`bg-base-200 rounded-box p-5`,children:[(0,p.jsxs)(`h2`,{className:`text-sm font-semibold flex items-center gap-2 mb-4`,children:[(0,p.jsx)(s,{className:`size-4 text-secondary`}),`Hourly Activity (last 24h)`]}),(0,p.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-6`,children:[O.length>0&&(0,p.jsx)(b,{data:O,valueKey:`totalTokens`,height:60,color:`stroke-primary`,label:`Tokens / hour`}),k.length>0&&(0,p.jsx)(b,{data:k,valueKey:`count`,height:60,color:`stroke-secondary`,label:`Events / hour`})]})]}),D.length>0&&(0,p.jsxs)(`section`,{className:`bg-base-200 rounded-box p-5`,children:[(0,p.jsxs)(`h2`,{className:`text-sm font-semibold flex items-center gap-2 mb-4`,children:[(0,p.jsx)(a,{className:`size-4 text-accent`}),`Top Issues by Token Usage`]}),(0,p.jsx)(S,{topIssues:D})]}),Object.keys(T).length>0&&(0,p.jsxs)(`section`,{className:`bg-base-200 rounded-box p-5`,children:[(0,p.jsxs)(`h2`,{className:`text-sm font-semibold flex items-center gap-2 mb-4`,children:[(0,p.jsx)(c,{className:`size-4 text-info`}),`Model Breakdown`]}),(0,p.jsx)(x,{byModel:T})]})]})})}export{T as Route};