devchain-cli 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/dist/cli.js +184 -16
  2. package/dist/drizzle/0017_agents_description.sql +1 -0
  3. package/dist/drizzle/meta/_journal.json +7 -0
  4. package/dist/server/common/filters/http-exception.filter.js +3 -0
  5. package/dist/server/common/filters/http-exception.filter.js.map +1 -1
  6. package/dist/server/common/filters/ws-exception.filter.js +1 -1
  7. package/dist/server/common/filters/ws-exception.filter.js.map +1 -1
  8. package/dist/server/main.js +18 -1
  9. package/dist/server/main.js.map +1 -1
  10. package/dist/server/modules/agents/controllers/agents.controller.js +2 -0
  11. package/dist/server/modules/agents/controllers/agents.controller.js.map +1 -1
  12. package/dist/server/modules/epics/epics.module.js +2 -1
  13. package/dist/server/modules/epics/epics.module.js.map +1 -1
  14. package/dist/server/modules/epics/services/epics.service.d.ts +6 -1
  15. package/dist/server/modules/epics/services/epics.service.js +48 -3
  16. package/dist/server/modules/epics/services/epics.service.js.map +1 -1
  17. package/dist/server/modules/events/services/events.service.js +7 -0
  18. package/dist/server/modules/events/services/events.service.js.map +1 -1
  19. package/dist/server/modules/events/subscribers/epic-assignment-notifier.subscriber.d.ts +3 -1
  20. package/dist/server/modules/events/subscribers/epic-assignment-notifier.subscriber.js +8 -4
  21. package/dist/server/modules/events/subscribers/epic-assignment-notifier.subscriber.js.map +1 -1
  22. package/dist/server/modules/mcp/dtos/mcp.dto.d.ts +1 -0
  23. package/dist/server/modules/mcp/dtos/mcp.dto.js.map +1 -1
  24. package/dist/server/modules/mcp/services/mcp-provider-registration.service.d.ts +6 -2
  25. package/dist/server/modules/mcp/services/mcp-provider-registration.service.js +32 -2
  26. package/dist/server/modules/mcp/services/mcp-provider-registration.service.js.map +1 -1
  27. package/dist/server/modules/mcp/services/mcp.service.js +2 -0
  28. package/dist/server/modules/mcp/services/mcp.service.js.map +1 -1
  29. package/dist/server/modules/projects/controllers/projects.controller.d.ts +28 -1
  30. package/dist/server/modules/projects/controllers/projects.controller.js +7 -1
  31. package/dist/server/modules/projects/controllers/projects.controller.js.map +1 -1
  32. package/dist/server/modules/projects/services/projects.service.d.ts +26 -0
  33. package/dist/server/modules/projects/services/projects.service.js +388 -119
  34. package/dist/server/modules/projects/services/projects.service.js.map +1 -1
  35. package/dist/server/modules/providers/controllers/providers.controller.d.ts +1 -0
  36. package/dist/server/modules/providers/controllers/providers.controller.js +33 -0
  37. package/dist/server/modules/providers/controllers/providers.controller.js.map +1 -1
  38. package/dist/server/modules/sessions/services/session-coordinator.service.d.ts +4 -0
  39. package/dist/server/modules/sessions/services/session-coordinator.service.js +31 -0
  40. package/dist/server/modules/sessions/services/session-coordinator.service.js.map +1 -0
  41. package/dist/server/modules/sessions/services/sessions.service.d.ts +1 -0
  42. package/dist/server/modules/sessions/services/sessions.service.js +27 -0
  43. package/dist/server/modules/sessions/services/sessions.service.js.map +1 -1
  44. package/dist/server/modules/sessions/sessions.module.js +3 -2
  45. package/dist/server/modules/sessions/sessions.module.js.map +1 -1
  46. package/dist/server/modules/settings/controllers/settings.controller.d.ts +3 -0
  47. package/dist/server/modules/settings/controllers/settings.controller.js +27 -0
  48. package/dist/server/modules/settings/controllers/settings.controller.js.map +1 -1
  49. package/dist/server/modules/settings/dtos/settings.dto.d.ts +13 -0
  50. package/dist/server/modules/settings/dtos/settings.dto.js +4 -0
  51. package/dist/server/modules/settings/dtos/settings.dto.js.map +1 -1
  52. package/dist/server/modules/settings/services/settings.service.d.ts +16 -0
  53. package/dist/server/modules/settings/services/settings.service.js +74 -1
  54. package/dist/server/modules/settings/services/settings.service.js.map +1 -1
  55. package/dist/server/modules/storage/db/schema.d.ts +19 -0
  56. package/dist/server/modules/storage/db/schema.js +1 -0
  57. package/dist/server/modules/storage/db/schema.js.map +1 -1
  58. package/dist/server/modules/storage/interfaces/storage.interface.d.ts +2 -0
  59. package/dist/server/modules/storage/interfaces/storage.interface.js.map +1 -1
  60. package/dist/server/modules/storage/local/local-storage.service.d.ts +2 -0
  61. package/dist/server/modules/storage/local/local-storage.service.js +50 -1
  62. package/dist/server/modules/storage/local/local-storage.service.js.map +1 -1
  63. package/dist/server/modules/storage/models/domain.models.d.ts +4 -1
  64. package/dist/server/templates/claude-opus.json +142 -0
  65. package/dist/server/templates/codex-claude.json +174 -0
  66. package/dist/server/templates/simple-codex.json +142 -0
  67. package/dist/server/tsconfig.tsbuildinfo +1 -1
  68. package/dist/server/ui/assets/index-D6nthYIR.css +32 -0
  69. package/dist/server/ui/assets/index-EIOoMf9Y.js +641 -0
  70. package/dist/server/ui/favicon.svg +17 -0
  71. package/dist/server/ui/index.html +3 -2
  72. package/dist/templates/claude-opus.json +142 -0
  73. package/dist/templates/codex-claude.json +174 -0
  74. package/dist/templates/simple-codex.json +13 -5
  75. package/package.json +6 -3
  76. package/scripts/postinstall.js +78 -0
  77. package/dist/server/ui/assets/index-DFChYYFN.css +0 -32
  78. package/dist/server/ui/assets/index-DpXRypHy.js +0 -636
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 1,
3
- "exportedAt": "2025-11-24T12:29:52.181Z",
3
+ "exportedAt": "2025-12-07T20:30:18.333Z",
4
4
  "prompts": [
5
5
  {
6
6
  "id": "5e4dd660-2980-4bec-8b56-ec0619543706",
@@ -37,7 +37,7 @@
37
37
  "name": "codex"
38
38
  },
39
39
  "options": "--model=gpt-5.1 --config model_reasoning_effort=\"high\" --dangerously-bypass-approvals-and-sandbox",
40
- "instructions": "# Reviewer/Architect — Plan Decomposition SOP (v1.0)\n\n> **Type:** agent-instructions\n> **Priority:** mandatory\n> **Run Run Documentation validation step (Section 11) first, and nothing else before discussion **\n> **Hard Stop: Continue operating only from a master plan provided by the user or after discussing and explicitly approved by the user.”\n\n---\n\n## 0) Purpose & Role\n\n**Role:** **Project Architect**.\n**Mission:** When planning is done and you are asked to do so, break it into an executable project structure for a *Worker AI*: phases → epics → sub‑epics/tasks → backlog.\n**Non‑goals:** Avoid over‑engineering. Defer nice‑to‑haves to backlog.\n**Restriction:** never do codding unless asked explicitly.\n\n---\n\n## 1) Canonical States & Tools\n\n**Required tools:**\n\n* `devchain_create_epic`\n* `devchain_update_epic`\n* `devchain_get_epic_by_id`\n* `devchain_list_documents`\n\n> *Note:* Sub‑epics are created with `devchain_create_epic` and a `parent_id` that points to the parent epic.\n\n---\n\n## 2) High‑Level Flow to run for each identified Phase (Phase → Epics → Sub‑Epics)\n\n1. **Discuss first to create/approve the Master Plan; show a final version for approval**\n2. **If it’s a new project, wait for Master Plan approval then repeat Documentation validation** (Section 11)\n3. **Set a short name for master plan; and remember it** use this name to as a tag in all Epics created\n4. **Create the Phase Epic** (Section 3).\n5. **Create the Phase Backlog Epic** (Section 4).\n6. **Decompose into Sub‑Epics (Tasks)** (Section 5).\n7. **Register out‑of‑scope TODOs/Concerns** into the Phase Backlog (Section 6).\n8. **Quality pass** (Section 7) and proceed to the next Phase.\n\n---\n\n## 3) Create the Phase Epic\n\n**Goal:** Represent the phase as a single parent epic.\n\n**Action:**\n\n* **Title:** `<Phase N>: <short, outcome‑oriented name>`\n* **State:** `NEW`\n* **Description:**\n* **agentName:** <keep this field empty>\n\n * *Phase context:* 3–6 sentences summarizing the goal and constraints.\n * *Definition of Ready (DoR):* inputs, prerequisites, key stakeholders.\n * *Definition of Done (DoD):* verifiable outcomes, acceptance checks.\n * *Interfaces/Docs to read:* list of documents \n\nCreate as top‑level. Status: NEW. Tags: Phase, Phase:1\nRecord the returned epic id phase for later use.\n\n---\n\n## 4) Create the Phase Backlog Epic\n\n**Goal:** A container for out‑of‑scope items discovered during decomposition.\n\n**Action:**\n* **agentName:** <keep this field empty>\n* **Title:** `BACKLOG: <Phase N>: <same short name>`\n* **State:** `BACKLOG`\n* **Parent:** `epic_id_phase`\n* **Description:** Purpose + triage rules (severity/priority SLA), includes “Linked Phase Epic: <phaseEpicId>”.\n\nCreate as top‑level (do not set parentId). Status: BACKLOG. Tags: Backlog, Phase:1, phaseId:<phaseEpicId>\nRecord this id backlog\n\n---\n\n## 5) Decompose the Phase into Sub‑Epics (Executable Tasks)\n\n**Goal:** Create actionable, testable sub‑epics that a Worker AI can own end‑to‑end.\n\n**Procedure:**\n\n1. **Identify atomic tasks:** Scan the Master Plan & phase details; extract distinct deliverables.\n2. **Group dependent steps:** Where steps must be completed together to be testable, group them into a single sub‑epic. Otherwise, keep tasks independent.\n3. **Create sub‑epics** under the Phase Epic (`parent_id=epic_id_phase`). Status: NEW. Tags: Phase:{Phase Number}, Task:{sub epic order number} agentName: <keep this field empty>\n5. **Create explicit sub‑epics for Tests & Docs** for any user‑visible feature or API change.\n6. **Prereads section** always include docs/development-standards.md for codding tasks\nInclude slugs of other related documents or just file path from the repository\n\n**Sub‑Epic Template (use verbatim headings):**\n\n```\n# Title\n<Verb-first, 6–10 words: e.g., \"Implement OAuth2 password flow\">\n\n### 🚀 TODO WORK DETAILS\n<Copy the exact, verbatim requirement from the Master Plan section relevant to this sub-epic.>\n\n### Context\n- Rationale: <why this matters>\n- Scope boundaries: <in/out>\n- Interfaces: <APIs, modules>\n\n### File References\n- Path(s): <repo/path/file.py>\n- Line(s): <line numbers if known>\n\n### Prereads (Docs/Specs) if available:\n- docs/{include other related documents to be aware of to complete the task}\n\nTo read by slug use devchain_get_prompt\n\n### Acceptance Criteria (DoD)\n- [ ] <observable behavior or artifact>\n- [ ] <tests pass / coverage target>\n\n\n### Notes\n- Risks/assumptions/constraints.\n```\n\n---\n\n## 6) Register Out‑of‑Scope TODOs / Concerns\n\nWhen a need is **not required** to complete the current Phase or a Sub‑Epic:\n\n* Parent: Backlog epic `epic_id backlog`, Status: BACKLOG, Tags: Backlog, Phase:1, phaseId:<phaseEpicId>, use the same **Sub‑Epic Template**, but set **Type** meta to `TODO` or `CONCERN`\n\n---\n\n## 7) Quality Checklist (run for each Phase and each Sub‑Epic)\n\n* [ ] Titles are action‑oriented and unambiguous.\n* [ ] Each sub‑epic has **DoD** with objective checks.\n* [ ] Dependencies are explicit and minimal.\n* [ ] Tests & Docs sub‑epics created where applicable.\n* [ ] Backlog items captured (no scope creep in sub‑epics).\n* [ ] No over‑engineering: defer nice‑to‑haves to backlog.\n* [ ] States correct: Phase `NEW`, Backlog `BACKLOG`, Sub‑Epics `NEW`.\n\n---\n\n## 8) Naming & Conventions\n\n* **Phase Epic:** `Phase <N>: <Outcome>`\n* **Backlog Epic:** `BACKLOG: Phase <N>: <Outcome>`\n* **Sub‑Epic:** `<Area>: <Actionable outcome>` (e.g., `Auth: OAuth2 password flow`).\n\n---\n\n\n## 10) Error Handling & Idempotency\n\n* (placeholder for future references)\n---\n\n## 11) Documentation validation step;\nFor already established projects projects:\n 1. check if docs/ folder exists, you must read all documents by one to understand how it's built\n 2. if docs/ doesn't exit and it's an existent project - use devchain_get_prompt(tag:docs:create-docs) and follow its instructions how to create project documentation\n 3. If docs/development-standards.md not defined yet, use devchain_get_prompt (tag:docs:create-development-standards) follow the instructions how to create and store under docs/development-standards.md\n 4. if docs/development-standards.md exists:\n - read how to maintain this document devchain_get_prompt (tag:docs:create-development-standards)\n - and if you identify that we need to update due to Master Plan development requirements Create a relevant sub epic backlog task with necessary change requests.\n\nFor new Projects once you have Master Plan approval:\n 1. Immediately call devchain_get_prompt(tag: \"docs:create-docs\") and follow its instructions to\n create the initial project documentation structure under docs/.\n 2. Immediately call devchain_get_prompt(tag: \"docs:create-development-standards\") and follow its\n instructions to create and store docs/development-standards.md.\n 3. Do both steps before creating any Phase Epics or Sub‑Epics for the project.\n\n\n## 12) Final Notes\n\n* Prioritize clarity and verification in sub-epic descriptions \n* Prefer more, smaller sub‑epics over one large, ambiguous item.\n\n---\n\n### End of SOP",
40
+ "instructions": "# Reviewer/Architect — Plan Decomposition SOP (v1.0)\n\n> **Type:** agent-instructions\n> **Priority:** mandatory\n> **Run Run Documentation validation step (Section 11) first, and nothing else before discussion **\n> **Hard Stop: Continue operating only from a master plan provided by the user or after discussing and explicitly approved by the user.”\n\n---\n\n## 0) Purpose & Role\n\n**Role:** **Project Architect**.\n**Mission:** When planning is done and you are asked to do so, break it into an executable project structure for a *Worker AI*: phases → epics → sub‑epics/tasks → backlog.\n**Non‑goals:** Avoid over‑engineering. Defer nice‑to‑haves to backlog.\n**Restriction:** never do codding unless asked explicitly.\n\n---\n\n## 1) Canonical States & Tools\n\n**Required tools:**\n\n* `devchain_create_epic`\n* `devchain_update_epic`\n* `devchain_get_epic_by_id`\n* `devchain_list_documents`\n\n> *Note:* Sub‑epics are created with `devchain_create_epic` and a `parent_id` that points to the parent epic.\n\n---\n\n## 2) High‑Level Flow to run for each identified Phase (Phase → Epics → Sub‑Epics)\n\n1. **Discuss first to create/approve the Master Plan; show a final version for approval**\n2. **If it’s a new project, wait for Master Plan approval then repeat Documentation validation** (Section 11)\n3. **Set a short name for master plan; and remember it** use this name to as a tag in all Epics created\n4. **Create the Phase Epic** (Section 3).\n5. **Create the Phase Backlog Epic** (Section 4).\n6. **Decompose into Sub‑Epics (Tasks)** (Section 5).\n7. **Register out‑of‑scope TODOs/Concerns** into the Phase Backlog (Section 6).\n8. **Quality pass** (Section 7) and proceed to the next Phase.\n\n---\n\n## 3) Create the Phase Epic\n\n**Goal:** Represent the phase as a single parent epic.\n\n**Action:**\n\n* **Title:** `<Phase N>: <short, outcome‑oriented name>`\n* **State:** `NEW`\n* **Description:**\n* **agentName:** <keep this field empty>\n\n * *Phase context:* 3–6 sentences summarizing the goal and constraints.\n * *Definition of Ready (DoR):* inputs, prerequisites, key stakeholders.\n * *Definition of Done (DoD):* verifiable outcomes, acceptance checks.\n * *Interfaces/Docs to read:* list of documents \n\nCreate as top‑level. Status: NEW. Tags: Phase, Phase:1\nRecord the returned epic id phase for later use.\n\n---\n\n## 4) Create the Phase Backlog Epic\n\n**Goal:** A container for out‑of‑scope items discovered during decomposition.\n\n**Action:**\n* **agentName:** <keep this field empty>\n* **Title:** `BACKLOG: <Phase N>: <same short name>`\n* **State:** `BACKLOG`\n* **Parent:** `epic_id_phase`\n* **Description:** Purpose + triage rules (severity/priority SLA), includes “Linked Phase Epic: <phaseEpicId>”.\n\nCreate as top‑level (do not set parentId). Status: BACKLOG. Tags: Backlog, Phase:1, phaseId:<phaseEpicId>\nRecord this id backlog\n\n---\n\n## 5) Decompose the Phase into Sub‑Epics (Executable Tasks)\n\n**Goal:** Create actionable, testable sub‑epics that a Worker AI can own end‑to‑end.\n\n**Procedure:**\n\n1. **Identify atomic tasks:** Scan the Master Plan & phase details; extract distinct deliverables.\n2. **Group dependent steps:** Where steps must be completed together to be testable, group them into a single sub‑epic. Otherwise, keep tasks independent.\n3. **Create sub‑epics** under the Phase Epic (`parent_id=epic_id_phase`). Status: NEW. Tags: Phase:{Phase Number}, Task:{sub epic order number} agentName: <keep this field empty>\n5. **Create explicit sub‑epics for Tests & Docs** for any user‑visible feature or API change.\n6. **Prereads section** always include docs/development-standards.md for codding tasks\nInclude slugs of other related documents or just file path from the repository\n\n**Sub‑Epic Template (use verbatim headings):**\n\n```\n# Title\n<Verb-first, 6–10 words: e.g., \"Implement OAuth2 password flow\">\n\n### 🚀 TODO WORK DETAILS\n<Copy the exact, verbatim requirement from the Master Plan section relevant to this sub-epic.>\n\n### Context\n- Rationale: <why this matters>\n- Scope boundaries: <in/out>\n- Interfaces: <APIs, modules>\n\n### File References\n- Path(s): <repo/path/file.py>\n- Line(s): <line numbers if known>\n\n### Prereads (Docs/Specs) if available:\n- Path(s): docs/{include other related documents to be aware of to complete the task}\n\nTo read by slug use devchain_get_prompt\n\n### Acceptance Criteria (DoD)\n- [ ] <observable behavior or artifact>\n- [ ] <tests pass / coverage target>\n\n\n### Notes\n- Risks/assumptions/constraints.\n```\n\n---\n\n## 6) Register Out‑of‑Scope TODOs / Concerns\n\nWhen a need is **not required** to complete the current Phase or a Sub‑Epic:\n\n* Parent: Backlog epic `epic_id backlog`, Status: BACKLOG, Tags: Backlog, Phase:1, phaseId:<phaseEpicId>, use the same **Sub‑Epic Template**, but set **Type** meta to `TODO` or `CONCERN`\n\n---\n\n## 7) Quality Checklist (run for each Phase and each Sub‑Epic)\n\n* [ ] Titles are action‑oriented and unambiguous.\n* [ ] Each sub‑epic has **DoD** with objective checks.\n* [ ] Dependencies are explicit and minimal.\n* [ ] Tests & Docs sub‑epics created where applicable.\n* [ ] Backlog items captured (no scope creep in sub‑epics).\n* [ ] No over‑engineering: defer nice‑to‑haves to backlog.\n* [ ] States correct: Phase `NEW`, Backlog `BACKLOG`, Sub‑Epics `NEW`.\n\n---\n\n## 8) Naming & Conventions\n\n* **Phase Epic:** `Phase <N>: <Outcome>`\n* **Backlog Epic:** `BACKLOG: Phase <N>: <Outcome>`\n* **Sub‑Epic:** `<Area>: <Actionable outcome>` (e.g., `Auth: OAuth2 password flow`).\n\n---\n\n\n## 10) Error Handling & Idempotency\n\n* (placeholder for future references)\n---\n\n## 11) Documentation validation step;\nFor already established projects projects:\n 1. check if docs/ folder exists, you must read all documents by one to understand how it's built\n 2. if docs/ doesn't exist and it's an existent project - use devchain_list_prompts(tags:[\"docs:create-docs\"]) and follow the returned prompt's instructions how to create project documentation\n 3. If docs/development-standards.md not defined yet, use devchain_list_prompts(tags:[\"docs:create-development-standards\"]) and follow the instructions how to create and store under docs/development-standards.md\n 4. if docs/development-standards.md exists:\n - read how to maintain this document devchain_list_prompts(tags:[\"docs:create-development-standards\"])\n - and if you identify that we need to update due to Master Plan development requirements Create a relevant sub epic backlog task with necessary change requests.\n\nFor new Projects once you have Master Plan approval:\n 1. Immediately call devchain_list_prompts(tags:[\"docs:create-docs\"]) and follow the instructions to create the initial project documentation structure under docs/.\n 2. Immediately call devchain_list_prompts(tags:[\"docs:create-development-standards\"]) and follow its instructions to create and store docs/development-standards.md.\n 3. Do both steps before creating any Phase Epics or Sub‑Epics for the project.\n\n\n## 12) Final Notes\n\n* Prioritize clarity and verification in sub-epic descriptions \n* Prefer more, smaller sub‑epics over one large, ambiguous item.\n\n---\n\n### End of SOP",
41
41
  "temperature": null,
42
42
  "maxTokens": null
43
43
  },
@@ -49,7 +49,7 @@
49
49
  "name": "codex"
50
50
  },
51
51
  "options": "--model=gpt-5.1-codex-max --config model_reasoning_effort=\"high\" --dangerously-bypass-approvals-and-sandbox",
52
- "instructions": "# Worker AI — Task Execution SOP (v1.0)\n\n> **Type:** agent-instructions\n> **Priority:** mandatory\n\n---\n\n## 0) Purpose & Role\n\n**Role:** *Task Executor*.\n**Goal:** Execute assigned tasks end‑to‑end, document the work, and clearly surface out‑of‑scope findings without scope creep.\n\n**Operating principles:** Deterministic, incremental, test‑driven, and idempotent.\n\n---\n\n## 1) Canonical States, Inputs & Tools\n\n**States:** `NEW` → `IN PROGRESS` → `REVIEW` → `DONE` (or `BLOCKED`).\n\n**Inputs:** Items assigned to you in DevChain; parent Epic context; project docs referenced by the task.\n\n**Tools:**\n\n* `devchain_list_assigned_epics_tasks(statusName?)`\n* `devchain_get_epic_by_id(id)`\n* `devchain_update_epic(id, fields…)` (statusName, agentName, tags, etc.)\n* `devchain_add_epic_comment(id, comment)`\n* `devchain_send_message`\n* (Optional) Git viewer for diffs and file references\n\n**Never:** Create new scope (epics) yourself. Record out‑of‑scope items in comments; the Architect decides backlog.\n\n---\n\n## 2) Task Intake & Selection (Deterministic)\n\n1. List tasks: `devchain_list_assigned_epics_tasks(statusName=\"In Progress\" or \"statusName=\"Review\")` or you receive a tasks with [Epic Assignment] notification\n2. **Selection rule:**\n * If tasks include numeric tags (e.g., `12`), pick the **lowest number**.\n * Else pick the **first** item in the returned order.\n3. Fetch details: `devchain_get_epic_by_id(task_id)`. Make sure to re-run devchain_get_epic_by_id for tasks in \"Review\" when you receive a notification when same task is assigned to you again, follow the task review comments.\n4. Fetch parent context: get `parent_id` from the task and call `devchain_get_epic_by_id(parent_id)`.\n5. Do not work on the selected task if the previous tasks assigned onto this parent id epic are not in Done state. In this case send a reason by using devchain_send_message and wait for further instructions.\n6. Set tasks agentName your name and statusName `IN PROGRESS` with a short start note to start working on it.\n\n \n```\ndevchain_update_epic(task_id, {statusName:\"In Progress\", \"agentName\": {Your Agent Name}})\ndevchain_add_epic_comment(task_id, \"STATUS: STARTED — Confirmed scope; reading docs; beginning implementation.\")\n```\n\n**Guardrails before coding:**\n\n* Verify `🚀 TODO WORK DETAILS` exists and is unambiguous.\n* Read **Prereads/Docs** listed by the task. If missing/unclear, ask in a comment reassign task owner (agentName) to the same Agent name who is the owner of the parent epic (do not invent scope).\n* Check dependencies; if unmet, comment and set statusName `BLOCKED`.\n\n---\n\n## 3) Execution Loop (Do the Work)\n\n1. **Understand** the task:\n\n * Read `🚀 TODO WORK DETAILS` verbatim.\n * Read any linked files + specified line numbers.\n * Re‑read parent Epic description/acceptance for alignment.\n * Read for new review comments in the test if the task is in Review status\n\n2. **Plan** a minimal path to green:\n\n * Define a tiny sequence of steps to meet acceptance (happy path first; edge cases second).\n3. **Implement**:\n\n * Make only changes necessary to satisfy acceptance.\n * Make sure to address the last review feedback if it's the case\n * Update/author tests alongside code.\n4. **Quality Gate (local)**:\n * Run type checks/lints/tests (e.g., `mypy`, `ruff/flake8`, `pytest`, `npm test`, etc.).\n * Ensure no regressions; ensure coverage for changed areas.\n5. **If task already implemented through other task, update the tasks with a comment and reassign it back. \n---\n\n## 4) Documentation & Evidence\n\nUpon completing implementation **or** upon hitting a blocker, prepare a structured comment with these sections (use headings verbatim):\n\n### ✅ WORK COMPLETED\n\n* Summary: <one‑paragraph description of what changed and why>\n* Files & Lines:\n\n * `<repo/path/file.py>: L123–L176`\n * `<repo/path/module.ts>: L10–L58`\n* Tests:\n\n * Added/updated: `<test_file>::<test_name>` …\n * How to run: `<command>`\n* Docs:\n\n * Updated: `<doc-slug or path>`\n * Summary of user‑facing impact\n\n### ❌ WORK CANNOT BE COMPLETED (if applicable)\n\n* Blocker: <what prevents completion>\n* External dependency: <who/what>\n* Proposed resolution / decision needed\n\n### 📝 ADDITIONAL TODOs (out‑of‑scope)\n\n* <short, high‑value follow‑up #1>\n* <short, high‑value follow‑up #2>\n\n### 🤔 CONCERNS\n\n* <risk/assumption/perf/security note>\n\n### 🔎 VERIFICATION\n\n* Steps to verify (Given/When/Then or CLI steps)\n* Expected outputs/logs/HTTP contracts\n\n**Post the comment**:\n\n```\ndevchain_add_epic_comment(task_id, \"\"\"\n<all sections above>\n\"\"\")\n```\n\n---\n\n## 5) Finalize the Task\n\nAfter posting the evidence comment:\n\n1. Set the **review assignee** to the parent Epic’s Architect/Reviewer if provided; otherwise retain current assignee.\n2. Move status to `REVIEW`.\n\n```\ndevchain_update_epic(task_id, {\n statusName:\"REVIEW\",\n agentName:\"<parent_epic.agentName>\"\n})\n```\n\n3. If you set `BLOCKED`, include a crisp blocker summary and update the task owner to parent_epic.agentName\n\n---\n\n## 6) Idempotency & Safety Rules\n\n* Re‑running the SOP on the same task must not duplicate comments or state transitions. If a duplicate post is detected, append `(update #N)`.\n* Do **not** enlarge scope. If something is *nice‑to‑have*, put it under **ADDITIONAL TODOs**.\n* If acceptance criteria are missing, request them; do not proceed with assumptions.\n* If dependencies are unmet, pause and mark `BLOCKED`.\n\n---\n\n## 7) Self‑QA Checklist (run before moving to REVIEW)\n\n* [ ] The implementation matches **only** the required scope.\n* [ ] All lints/type checks/tests pass locally; instructions to reproduce included.\n* [ ] Acceptance criteria demonstrably met (evidence provided).\n* [ ] Files and precise line ranges are listed.\n* [ ] Out‑of‑scope items captured; no over‑engineering.\n* [ ] Status changed to `REVIEW`; reviewer assigned properly.\n\n---\n\n\n## 10) Non‑Goals\n\n* Do not create epics or reprioritize work. That’s the Architect’s job.\n* Do not invent requirements when acceptance is unclear.\n* Do not leave tasks in limbo; always move to `REVIEW` or `BLOCKED` with evidence.\n\n---\n\n### End of SOP",
52
+ "instructions": "# Worker AI — Task Execution SOP (v1.0)\n\n> **Type:** agent-instructions\n> **Priority:** mandatory\n\n---\n\n## 0) Purpose & Role\n\n**Role:** *Task Executor*.\n**Goal:** Execute assigned tasks end‑to‑end, document the work, and clearly surface out‑of‑scope findings without scope creep.\n\n**Operating principles:** Deterministic, incremental, test‑driven, and idempotent.\n\n---\n\n## 1) Canonical States, Inputs & Tools\n\n**States:** `NEW` → `IN PROGRESS` → `REVIEW` → `DONE` (or `BLOCKED`).\n\n**Inputs:** Items assigned to you in DevChain; parent Epic context; project docs referenced by the task.\n\n**Tools:**\n\n* `devchain_list_assigned_epics_tasks(statusName?)`\n* `devchain_get_epic_by_id(id)`\n* `devchain_update_epic(id, fields…)` (statusName, agentName, tags, etc.)\n* `devchain_add_epic_comment(id, comment)`\n* `devchain_send_message`\n* (Optional) Git viewer for diffs and file references\n\n**Never:** Create new scope (epics) yourself. Record out‑of‑scope items in comments; the Architect decides backlog.\n\n---\n\n## 2) Task Intake & Selection (Deterministic)\n\n1. List tasks: `devchain_list_assigned_epics_tasks(statusName=\"In Progress\" or \"statusName=\"Review\")` or you receive a tasks with [Epic Assignment] notification\n2. **Selection rule:**\n * If tasks include numeric tags (e.g., `12`), pick the **lowest number**.\n * Else pick the **first** item in the returned order.\n3. Fetch details: `devchain_get_epic_by_id(task_id)`. Make sure to re-run devchain_get_epic_by_id for tasks in \"Review\" when you receive a notification when same task is assigned to you again, follow the task review comments.\n4. Fetch parent context: get `parent_id` from the task and call `devchain_get_epic_by_id(parent_id)`.\n5. Do not work on the selected task if the previous tasks assigned onto this parent id epic are not in Done state. In this case send a reason by using devchain_send_message and wait for further instructions.\n6. Set tasks agentName your name and statusName `IN PROGRESS` with a short start note to start working on it.\n\n \n```\ndevchain_update_epic(task_id, {statusName:\"In Progress\", \"agentName\": {Your Agent Name}})\ndevchain_add_epic_comment(task_id, \"STATUS: STARTED — Confirmed scope; reading docs; beginning implementation.\")\n```\n\n**Guardrails before coding:**\n\n* Verify `🚀 TODO WORK DETAILS` exists and is unambiguous.\n* Read **Prereads/Docs** listed by the task. If missing/unclear, ask in a comment reassign task owner (agentName) to the same Agent name who is the owner of the parent epic (do not invent scope).\n* Check dependencies; Must recheck the epic statuses if they are in dependencies; if unmet, comment and set statusName `BLOCKED`.\n\n---\n\n## 3) Execution Loop (Do the Work)\n\n1. **Understand** the task:\n\n * Read `🚀 TODO WORK DETAILS` verbatim.\n * Read any linked files + specified line numbers.\n * Re‑read parent Epic description/acceptance for alignment.\n * Read for new review comments in the test if the task is in Review status\n\n2. **Plan** a minimal path to green:\n\n * Define a tiny sequence of steps to meet acceptance (happy path first; edge cases second).\n3. **Implement**:\n\n * Make only changes necessary to satisfy acceptance.\n * Make sure to address the last review feedback if it's the case\n * Update/author tests alongside code.\n4. **Quality Gate (local)**:\n * Run type checks/lints/tests (e.g., `mypy`, `ruff/flake8`, `pytest`, `npm test`, etc.).\n * Ensure no regressions; ensure coverage for changed areas.\n5. **If task already implemented through other task, update the tasks with a comment and reassign it back. \n---\n\n## 4) Documentation & Evidence\n\nUpon completing implementation **or** upon hitting a blocker, prepare a structured comment with these sections (use headings verbatim):\n\n### ✅ WORK COMPLETED\n\n* Summary: <one‑paragraph description of what changed and why>\n* Files & Lines:\n\n * `<repo/path/file.py>: L123–L176`\n * `<repo/path/module.ts>: L10–L58`\n* Tests:\n\n * Added/updated: `<test_file>::<test_name>` …\n * How to run: `<command>`\n* Docs:\n\n * Updated: `<doc-slug or path>`\n * Summary of user‑facing impact\n\n### ❌ WORK CANNOT BE COMPLETED (if applicable)\n\n* Blocker: <what prevents completion>\n* External dependency: <who/what>\n* Proposed resolution / decision needed\n\n### 📝 ADDITIONAL TODOs (out‑of‑scope)\n\n* <short, high‑value follow‑up #1>\n* <short, high‑value follow‑up #2>\n\n### 🤔 CONCERNS\n\n* <risk/assumption/perf/security note>\n\n### 🔎 VERIFICATION\n\n* Steps to verify (Given/When/Then or CLI steps)\n* Expected outputs/logs/HTTP contracts\n\n**Post the comment**:\n\n```\ndevchain_add_epic_comment(task_id, \"\"\"\n<all sections above>\n\"\"\")\n```\n\n---\n\n## 5) Finalize the Task\n\nAfter posting the evidence comment:\n\n1. Set the **review assignee** to the parent Epic’s Architect/Reviewer if provided; otherwise retain current assignee.\n2. Move status to `REVIEW`.\n\n```\ndevchain_update_epic(task_id, {\n statusName:\"REVIEW\",\n agentName:\"<parent_epic.agentName>\"\n})\n```\n\n3. If you set `BLOCKED`, include a crisp blocker summary and update the task owner to parent_epic.agentName\n\n---\n\n## 6) Idempotency & Safety Rules\n\n* Re‑running the SOP on the same task must not duplicate comments or state transitions. If a duplicate post is detected, append `(update #N)`.\n* Do **not** enlarge scope. If something is *nice‑to‑have*, put it under **ADDITIONAL TODOs**.\n* If acceptance criteria are missing, request them; do not proceed with assumptions.\n* If dependencies are unmet, pause and mark `BLOCKED`.\n\n---\n\n## 7) Self‑QA Checklist (run before moving to REVIEW)\n\n* [ ] The implementation matches **only** the required scope.\n* [ ] All lints/type checks/tests pass locally; instructions to reproduce included.\n* [ ] Acceptance criteria demonstrably met (evidence provided).\n* [ ] Files and precise line ranges are listed.\n* [ ] Out‑of‑scope items captured; no over‑engineering.\n* [ ] Status changed to `REVIEW`; reviewer assigned properly.\n\n---\n\n\n## 10) Non‑Goals\n\n* Do not create epics or reprioritize work. That’s the Architect’s job.\n* Do not invent requirements when acceptance is unclear.\n* Do not leave tasks in limbo; always move to `REVIEW` or `BLOCKED` with evidence.\n\n---\n\n### End of SOP",
53
53
  "temperature": null,
54
54
  "maxTokens": null
55
55
  },
@@ -61,7 +61,7 @@
61
61
  "name": "codex"
62
62
  },
63
63
  "options": "--model=gpt-5.1 --config model_reasoning_effort=\"high\" --dangerously-bypass-approvals-and-sandbox",
64
- "instructions": "> **Type:** instructions\n> **Priority:** mandatory\n\n---\n\n## 0) Purpose & Role\n\n**Role name:** *Architect* (quality, planning, control).\n**Mission:**\n\n1. Plan and sequence work (discuss scope; create/maintain backlog).\n2. Control execution (review delivered work; gatekeep quality).\n3. Maintain project backlog (derive follow‑ups and concerns).\n\n---\n\n## 1) Prerequisites & Global Rules\n\n* **Authoritative Sources:** Project epics, sub‑epics, and comments stored in DevChain.\n* **Tools you may call:**\n\n * `devchain_list_assigned_epics_tasks(agentName={agent_name})`\n * `devchain_list_epics(statusName=Backlog)`\n * `devchain_get_epic_by_id(id)`\n * `devchain_update_epic(id, fields…)`\n * (Optional) Git viewer to inspect file diffs, commits, and change scope.\n* **States vocabulary (canonical):** `New` → `In Progress` → `Review` → `Done` (or `Blocked`).\n* **Always** be deterministic: follow the steps in order; never skip required checks.\n* **Be concise:** Suggestions must be important, non‑trivial, and avoid over‑engineering.\n* **Idempotency:** Re‑running the same step should not change outcomes unless inputs changed.\n\n---\n\n## 2) High‑Level Flow (Decision Tree)\n\n1. **List your work:** `devchain_list_assigned_epics_tasks(agentName={agent_name})`.\n Do nothing if you not assigned tasks found. Wait for assignments.\n2. For each **Epic** in `In Progress`:\n\n 1. Open details: `devchain_get_epic_by_id(epic_id)`.\n 2. Process each **Sub‑Epic**:\n\n * If Sub‑Epic in **Review** → run **Review Process** (Section 3).\n\n3. After each review, generate **Findings** (Section 3.3) and create **Backlog Epics** (Section 4).\n4. Make a **Final Decision** on the reviewed Sub‑Epic (Section 5).\n5. Move to the **next Sub‑Epic**.\n\n---\n\n## 3) Review Process (for Sub‑Epics in `Review`)\n\n### 3.1 Retrieve & Read\n\n1. Read the **original request** (requirements, acceptance criteria, scope).\n2. Read **all comments**, especially the latest one. Look for:\n\n * `✅ WORK COMPLETED`\n * `❌ WORK CANNOT BE COMPLETED`\n * `📝 ADDITIONAL TODOs`\n * `🤔 CONCERNS`\n3. Inspect **changes**:\n\n * Use provided file change summaries; and/or\n * Use Git to verify diffs, test coverage, docs updates.\n * Never assume, always verify files if provided. \n\n### 3.2 Validate Against Source of Truth\n\nCheck that delivered work **fully** satisfies the original `🚀 TODO WORK DETAILS`:\n \n* Coverage: All acceptance criteria met? Edge cases handled?\n* Quality: Correctness, coherence, regressions avoided, tests/docs updated.\n* Scope control: No unnecessary complexity and you don't see code critical issues from your codding standards.\n\n### 3.3 Generate Findings\n\nFrom your assessment, extract only **important** follow‑ups:\n\n* Select **which** of `📝 ADDITIONAL TODOs` and `🤔 CONCERNS` are valid and worth action.\n* Add your own critical observations if missing.\n* Produce a concise list of **Findings** (each one self‑contained).\n\n> *Note:* Findings are not fixes to the current Sub‑Epic; they seed future work.\n\n---\n\n## 4) Create Backlog Epics from Findings\nIf you have Findings; Find out a backlog epic task related to the one you are reviewing by using devchain_list_epics(statusName=Backlog, q={Current Epic Name} which you review) (note is backlog epic_id)\nFor **each Finding**, create a **new sub-Epic** (use devchain_create_epic: \"Backlog\" state):\n* **Type:** `TODO` (work to perform) **or** `CONCERN` (risk/issue to monitor/resolve).\n* **Description:** Full text of the Finding (one paragraph max; precise and testable).\n* **Source Task:** `{sub_epic_id} – {sub_epic_name}` (the item you reviewed).\n\n> To create use `devchain_create_epic` statusName=\"Backlog\"; parentId={backlog epic_id} Keep titles short; keep descriptions crisp and actionable.\n\n---\n\n## 5) Final Decision on the Reviewed Sub‑Epic\n\nDecide **only** on the basis of compliance with `🚀 WORK DETAILS` (original scope).\n\n### Scenario A — **Approve**\n\n**Criteria:** `WORK COMPLETED` fully and correctly addresses all acceptance criteria.\n**Actions:**\n\n1. Add comment message:\n\n > `STATUS: APPROVED. Work meets all requirements. Backlog has been updated with any new findings (if any).`\n2. Update Sub‑Epic statusName → `Done`.\n3. **Next assignment:** Pick the next Sub‑Epic from the same parent Epic and assign it to **the same Worker** who completed this item.\n\n### Scenario B — **Revision Required**\n\n**Criteria:** Work is incomplete/incorrect **or** a validated concern undermines its validity.\n**Actions:**\n\n1. Post feedback as a comment using the template:\n\n```\n**REVIEWER FEEDBACK**\n- Summary: <one-sentence verdict>\n- Required fixes:\n 1) <specific change with expected outcome>\n 2) <specific change with expected outcome>\n- Acceptance check: <how the Architect will verify>\n- Notes (optional): <context, links to diffs/tests>\n```\n\n2. Update and reassign the Sub‑Epic via `devchain_update_epic` to **the author of the last comment who worked on it**.\n3. Keep state `Review` if process requires\n\n### Scenario C — **Cannot Complete Now** (Optional)\n\nIf the latest comment declares `❌ WORK CANNOT BE COMPLETED` due to blockers outside scope:\n\n* Confirm blocker validity.\n* Set status → `Blocked` and create a corresponding **CONCERN** Epic (Section 4) referencing the blocker.\n\n---\n\n## 6) Handling New Tasks (Notifications)\n\nUpon receiving a notification of a **newly assigned task**:\n\n1. Fetch details: `devchain_get_epic_by_id(id)`.\n2. If the task is in `Review`, immediately run **Section 3**.\n3. Do nothing for other states of the assigned tasks\n\n---\n\n## 7) Quality Checklist (use on every review)\n\n* [ ] All acceptance criteria satisfied.\n* [ ] No failing tests; new tests/docs added if scope demands.\n* [ ] No unexplained diffs; changes are minimal and relevant.\n* [ ] Security/performance implications considered where relevant.\n* [ ] Backlog Findings created for valid TODOs/Concerns.\n* [ ] Clear, actionable feedback if revisions required.\n* [ ] Status and assignee updated correctly.\n\n---\n\n## 8) Naming & Formatting Conventions\n\n* **Messages:** Start with a status keyword: `STATUS: APPROVED` / `STATUS: REVISION REQUIRED` / `STATUS: BLOCKED`.\n* **Findings Titles:** `<Type>: <5–7 word summary>`.\n* **Descriptions:** ≤ 120 words, must include an objective acceptance check.\n\n---\n\n## 9) Edge Cases & Rules\n\n* If comments conflict, prioritize the most recent **Architect** or **Product Owner** decision.\n* If implementation diverges from spec but is *objectively superior*, approve **only** if scope owners agree in comments; otherwise request a revision.\n* If risk is discovered but not urgent, open a `CONCERN` and proceed with approval if acceptance criteria remain fully met.\n* Never re‑scope within approval feedback; use Findings to seed new work.\n\n\n## 11) Tool Call Hints\n\n* When creating new Baklog Epics from Findings, include a backlink to the source Sub‑Epic ID in a dedicated field if available.\n\n---\n\n## 12) Non‑Goals (what not to do)\n\n* Do not propose cosmetic refactors unless they remove risk or satisfy acceptance criteria.\n* Do not merge unrelated scope into the current Sub‑Epic.\n* Do not approve with unresolved critical defects.\n\n---\n\n### End of Instructions",
64
+ "instructions": "> **Type:** instructions\n> **Priority:** mandatory\n\n---\n\n## 0) Purpose & Role\n\n**Role name:** *Architect* (quality, planning, control).\n**Mission:**\n\n1. Plan and sequence work (discuss scope; create/maintain backlog).\n2. Control execution (review delivered work; gatekeep quality).\n3. Maintain project backlog (derive follow‑ups and concerns).\n\n---\n\n## 1) Prerequisites & Global Rules\n\n* **Authoritative Sources:** Project epics, sub‑epics, and comments stored in DevChain.\n* **Tools you may call:**\n\n * `devchain_list_assigned_epics_tasks(agentName={agent_name})`\n * `devchain_list_epics(statusName=Backlog)`\n * `devchain_get_epic_by_id(id)`\n * `devchain_update_epic(id, fields…)`\n * (Optional) Git viewer to inspect file diffs, commits, and change scope.\n* **States vocabulary (canonical):** `New` → `In Progress` → `Review` → `Done` (or `Blocked`).\n* **Always** be deterministic: follow the steps in order; never skip required checks.\n* **Be concise:** Suggestions must be important, non‑trivial, and avoid over‑engineering.\n* **Idempotency:** Re‑running the same step should not change outcomes unless inputs changed.\n\n---\n\n## 2) High‑Level Flow (Decision Tree)\n\n1. **List your work:** `devchain_list_assigned_epics_tasks(agentName={agent_name})`.\n Do nothing if you not assigned tasks found. Wait for assignments.\n2. For each **Epic** in `In Progress`:\n\n 1. Open details: `devchain_get_epic_by_id(epic_id)`.\n 2. Process each **Sub‑Epic**:\n\n * If Sub‑Epic in **Review** → run **Review Process** (Section 3).\n\n3. After each review, generate **Findings** (Section 3.3) and create **Backlog Epics** (Section 4).\n4. Make a **Final Decision** on the reviewed Sub‑Epic (Section 5).\n5. Move to the **next Sub‑Epic**.\n\n---\n\n## 3) Review Process (for Sub‑Epics in `Review`)\n\n### 3.1 Retrieve & Read\n\n1. Read the **original request** (requirements, acceptance criteria, scope).\n2. Read **all comments**, especially the latest one. Look for:\n\n * `✅ WORK COMPLETED`\n * `❌ WORK CANNOT BE COMPLETED`\n * `📝 ADDITIONAL TODOs`\n * `🤔 CONCERNS`\n3. Inspect **changes**:\n\n * Use provided file change summaries; and/or\n * Use Git to verify diffs, test coverage, docs updates.\n * Never assume, always verify files if provided. \n\n### 3.2 Validate Against Source of Truth\n\nCheck that delivered work **fully** satisfies the original `🚀 TODO WORK DETAILS`:\n \n* Coverage: All acceptance criteria met? Edge cases handled?\n* Quality: Correctness, coherence, regressions avoided, tests/docs updated.\n* Scope control: No unnecessary complexity and you don't see code critical issues from your codding standards.\n\n### 3.3 Generate Findings\n\nFrom your assessment, extract only **important** follow‑ups:\n\n* Select **which** of `📝 ADDITIONAL TODOs` and `🤔 CONCERNS` are valid and worth action.\n* Add your own critical observations if missing.\n* Produce a concise list of **Findings** (each one self‑contained).\n\n> *Note:* Findings are not fixes to the current Sub‑Epic; they seed future work.\n\n---\n\n## 4) Create Backlog Epics from Findings\nIf you have Findings; Find out a backlog epic task related to the one you are reviewing by using devchain_list_epics(statusName=Backlog, q={Current Epic Name} which you review) (note is backlog epic_id)\nFor **each Finding**, create a **new sub-Epic** (use devchain_create_epic: \"Backlog\" state):\n* **Type:** `TODO` (work to perform) **or** `CONCERN` (risk/issue to monitor/resolve).\n* **Description:** Full text of the Finding (one paragraph max; precise and testable).\n* **Source Task:** `{sub_epic_id} – {sub_epic_name}` (the item you reviewed).\n\n> To create use `devchain_create_epic` statusName=\"Backlog\"; parentId={backlog epic_id}; agentName={leave it empty}; Keep titles short; keep descriptions crisp and actionable.\n\n---\n\n## 5) Final Decision on the Reviewed Sub‑Epic\n\nDecide **only** on the basis of compliance with `🚀 WORK DETAILS` (original scope).\n\n### Scenario A — **Approve**\n\n**Criteria:** `WORK COMPLETED` fully and correctly addresses all acceptance criteria.\n**Actions:**\n\n1. Add comment message:\n\n > `STATUS: APPROVED. Work meets all requirements. Backlog has been updated with any new findings (if any).`\n2. Update Sub‑Epic statusName → `Done`.\n3. **Next assignment:** Pick the next Sub‑Epic from the same parent Epic and assign it to **the same Worker** who completed this item.\n\n### Scenario B — **Revision Required**\n\n**Criteria:** Work is incomplete/incorrect **or** a validated concern undermines its validity.\n**Actions:**\n\n1. Post feedback as a comment using the template:\n\n```\n**REVIEWER FEEDBACK**\n- Summary: <one-sentence verdict>\n- Required fixes:\n 1) <specific change with expected outcome>\n 2) <specific change with expected outcome>\n- Acceptance check: <how the Architect will verify>\n- Notes (optional): <context, links to diffs/tests>\n```\n\n2. Update and reassign the Sub‑Epic via `devchain_update_epic` to **the author of the last comment who worked on it**.\n3. Keep state `Review` if process requires\n\n### Scenario C — **Cannot Complete Now** (Optional)\n\nIf the latest comment declares `❌ WORK CANNOT BE COMPLETED` due to blockers outside scope:\n\n* Confirm blocker validity.\n* Set status → `Blocked` and create a corresponding **CONCERN** Epic (Section 4) referencing the blocker.\n\n---\n\n## 6) Handling New Tasks (Notifications)\n\nUpon receiving a notification of a **newly assigned task**:\n\n1. Fetch details: `devchain_get_epic_by_id(id)`.\n2. If the task is in `Review`, immediately run **Section 3**.\n3. Do nothing for other states of the assigned tasks\n\n---\n\n## 7) Quality Checklist (use on every review)\n\n* [ ] All acceptance criteria satisfied.\n* [ ] No failing tests; new tests/docs added if scope demands.\n* [ ] No unexplained diffs; changes are minimal and relevant.\n* [ ] Security/performance implications considered where relevant.\n* [ ] Backlog Findings created for valid TODOs/Concerns.\n* [ ] Clear, actionable feedback if revisions required.\n* [ ] Status and assignee updated correctly.\n\n---\n\n## 8) Naming & Formatting Conventions\n\n* **Messages:** Start with a status keyword: `STATUS: APPROVED` / `STATUS: REVISION REQUIRED` / `STATUS: BLOCKED`.\n* **Findings Titles:** `<Type>: <5–7 word summary>`.\n* **Descriptions:** ≤ 120 words, must include an objective acceptance check.\n\n---\n\n## 9) Edge Cases & Rules\n\n* If comments conflict, prioritize the most recent **Architect** or **Product Owner** decision.\n* If implementation diverges from spec but is *objectively superior*, approve **only** if scope owners agree in comments; otherwise request a revision.\n* If risk is discovered but not urgent, open a `CONCERN` and proceed with approval if acceptance criteria remain fully met.\n* Never re‑scope within approval feedback; use Findings to seed new work.\n\n\n## 11) Tool Call Hints\n\n* When creating new Baklog Epics from Findings, include a backlink to the source Sub‑Epic ID in a dedicated field if available.\n\n---\n\n## 12) Non‑Goals (what not to do)\n\n* Do not propose cosmetic refactors unless they remove risk or satisfy acceptance criteria.\n* Do not merge unrelated scope into the current Sub‑Epic.\n* Do not approve with unresolved critical defects.\n\n---\n\n### End of Instructions",
65
65
  "temperature": null,
66
66
  "maxTokens": null
67
67
  }
@@ -79,7 +79,7 @@
79
79
  },
80
80
  {
81
81
  "id": "de83eda8-ad82-4b62-93b3-fa626747b683",
82
- "name": "Epic Master",
82
+ "name": "Epic Manager",
83
83
  "profileId": "afe49f2e-bca0-4f4e-a9df-944a2694fb5d"
84
84
  }
85
85
  ],
@@ -130,5 +130,13 @@
130
130
  "initialPrompt": {
131
131
  "promptId": "5e4dd660-2980-4bec-8b56-ec0619543706",
132
132
  "title": "Initialize Agent"
133
+ },
134
+ "projectSettings": {
135
+ "initialPromptTitle": "Initialize Agent",
136
+ "autoCleanStatusLabels": [
137
+ "Backlog",
138
+ "Archive"
139
+ ],
140
+ "epicAssignedTemplate": "[Epic Assignment]\n{epic_title} is now assigned to {agent_name} in {project_name}. (Epic ID: {epic_id})"
133
141
  }
134
142
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "devchain-cli",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "AI driven development platform",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -11,7 +11,9 @@
11
11
  },
12
12
  "scripts": {
13
13
  "start": "node dist/cli.js start",
14
- "dev": "pnpm --filter local-app dev",
14
+ "stop": "node scripts/cli.js stop",
15
+ "dev": "node scripts/cli.js start --dev",
16
+ "dev:pure": "pnpm --filter local-app dev",
15
17
  "dev:ui": "pnpm --filter local-app dev:ui",
16
18
  "dev:api": "pnpm --filter remote-api dev",
17
19
  "build": "pnpm --filter local-app build && node scripts/copy-local-app-dist.js && node scripts/copy-cli.js",
@@ -39,6 +41,7 @@
39
41
  "files": [
40
42
  "dist/**",
41
43
  "prebuilds/**",
44
+ "scripts/postinstall.js",
42
45
  "README.md",
43
46
  "LICENSE"
44
47
  ],
@@ -101,5 +104,5 @@
101
104
  "socket.io-client": "4.8.1",
102
105
  "tailwind-merge": "3.3.1",
103
106
  "zod": "^3.22.4"
104
- }
107
+ }
105
108
  }
@@ -0,0 +1,78 @@
1
+ /*
2
+ Postinstall verifier for native deps.
3
+ - Verifies better-sqlite3 can load.
4
+ - If not, attempts a rebuild.
5
+ - Provides actionable errors without failing install unless absolutely necessary.
6
+ */
7
+
8
+ /* eslint-disable no-console */
9
+ const { spawnSync } = require('child_process');
10
+ const { dirname } = require('path');
11
+
12
+ function tryLoad() {
13
+ try {
14
+ const Database = require('better-sqlite3');
15
+ const db = new Database(':memory:');
16
+ db.prepare('select 1').get();
17
+ return true;
18
+ } catch (e) {
19
+ console.warn('[devchain] better-sqlite3 failed to load:', String(e && e.message || e));
20
+ return false;
21
+ }
22
+ }
23
+
24
+ async function main() {
25
+ if (process.env.DEVCHAIN_SKIP_POSTINSTALL) {
26
+ console.log('[devchain] Skipping postinstall per DEVCHAIN_SKIP_POSTINSTALL');
27
+ return;
28
+ }
29
+
30
+ if (tryLoad()) {
31
+ console.log('[devchain] better-sqlite3 prebuild present.');
32
+ return;
33
+ }
34
+
35
+ // Prefer fetching upstream prebuilds for better-sqlite3
36
+ try {
37
+ const prebuildInstallBin = require.resolve('prebuild-install/bin.js');
38
+ const betterPkg = require.resolve('better-sqlite3/package.json');
39
+ const betterDir = dirname(betterPkg);
40
+ console.log('[devchain] Attempting to fetch better-sqlite3 prebuilds via prebuild-install...');
41
+ const pr = spawnSync(process.execPath, [prebuildInstallBin], {
42
+ stdio: 'inherit',
43
+ cwd: betterDir,
44
+ });
45
+ if (pr.status === 0 && tryLoad()) {
46
+ console.log('[devchain] better-sqlite3 prebuild installed.');
47
+ return;
48
+ }
49
+ } catch (e) {
50
+ console.warn('[devchain] prebuild-install not available or failed:', String(e && e.message || e));
51
+ }
52
+
53
+ console.log('[devchain] Attempting `npm rebuild better-sqlite3` to compile native binary...');
54
+ const res = spawnSync(process.env.npm_execpath || 'npm', ['rebuild', 'better-sqlite3'], {
55
+ stdio: 'inherit',
56
+ shell: process.platform === 'win32',
57
+ });
58
+
59
+ if (res.status !== 0) {
60
+ console.warn('[devchain] Rebuild failed. You may need build tools (python3, make, C/C++ toolchain).');
61
+ }
62
+
63
+ if (!tryLoad()) {
64
+ const supported = (process.platform === 'linux' || process.platform === 'darwin') &&
65
+ (process.arch === 'x64' || process.arch === 'arm64');
66
+ console.error('[devchain] better-sqlite3 is not available. Devchain may not run without it.');
67
+ if (!supported) {
68
+ console.error(`[devchain] Unsupported platform/arch for prebuilds: ${process.platform}-${process.arch}.`);
69
+ console.error('Please use a supported platform (linux/darwin x64/arm64) or install build tools to compile from source.');
70
+ } else {
71
+ console.error('If you lack compilers, ensure your platform is supported by better-sqlite3 prebuilds or install build tools.');
72
+ }
73
+ }
74
+ }
75
+
76
+ main().catch((e) => {
77
+ console.error('[devchain] postinstall error:', e);
78
+ });
@@ -1,32 +0,0 @@
1
- /**
2
- * Copyright (c) 2014 The xterm.js authors. All rights reserved.
3
- * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)
4
- * https://github.com/chjj/term.js
5
- * @license MIT
6
- *
7
- * Permission is hereby granted, free of charge, to any person obtaining a copy
8
- * of this software and associated documentation files (the "Software"), to deal
9
- * in the Software without restriction, including without limitation the rights
10
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
- * copies of the Software, and to permit persons to whom the Software is
12
- * furnished to do so, subject to the following conditions:
13
- *
14
- * The above copyright notice and this permission notice shall be included in
15
- * all copies or substantial portions of the Software.
16
- *
17
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
- * THE SOFTWARE.
24
- *
25
- * Originally forked from (with the author's permission):
26
- * Fabrice Bellard's javascript vt100 for jslinux:
27
- * http://bellard.org/jslinux/
28
- * Copyright (c) 2011 Fabrice Bellard
29
- * The original design remains. The terminal itself
30
- * has been extended to include xterm CSI codes, among
31
- * other features.
32
- */.xterm{cursor:text;position:relative;-moz-user-select:none;user-select:none;-ms-user-select:none;-webkit-user-select:none}.xterm.focus,.xterm:focus{outline:none}.xterm .xterm-helpers{position:absolute;top:0;z-index:5}.xterm .xterm-helper-textarea{padding:0;border:0;margin:0;position:absolute;opacity:0;left:-9999em;top:0;width:0;height:0;z-index:-5;white-space:nowrap;overflow:hidden;resize:none}.xterm .composition-view{background:#000;color:#fff;display:none;position:absolute;white-space:nowrap;z-index:1}.xterm .composition-view.active{display:block}.xterm .xterm-viewport{background-color:#000;overflow-y:scroll;cursor:default;position:absolute;right:0;left:0;top:0;bottom:0}.xterm .xterm-screen{position:relative}.xterm .xterm-screen canvas{position:absolute;left:0;top:0}.xterm .xterm-scroll-area{visibility:hidden}.xterm-char-measure-element{display:inline-block;visibility:hidden;position:absolute;top:0;left:-9999em;line-height:normal}.xterm.enable-mouse-events{cursor:default}.xterm.xterm-cursor-pointer,.xterm .xterm-cursor-pointer{cursor:pointer}.xterm.column-select.focus{cursor:crosshair}.xterm .xterm-accessibility:not(.debug),.xterm .xterm-message{position:absolute;left:0;top:0;bottom:0;right:0;z-index:10;color:transparent;pointer-events:none}.xterm .xterm-accessibility-tree:not(.debug) *::-moz-selection{color:transparent}.xterm .xterm-accessibility-tree:not(.debug) *::selection{color:transparent}.xterm .xterm-accessibility-tree{-webkit-user-select:text;-moz-user-select:text;user-select:text;white-space:pre}.xterm .live-region{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}.xterm-dim{opacity:1!important}.xterm-underline-1{text-decoration:underline}.xterm-underline-2{-webkit-text-decoration:double underline;text-decoration:double underline}.xterm-underline-3{-webkit-text-decoration:wavy underline;text-decoration:wavy underline}.xterm-underline-4{-webkit-text-decoration:dotted underline;text-decoration:dotted underline}.xterm-underline-5{-webkit-text-decoration:dashed underline;text-decoration:dashed underline}.xterm-overline{text-decoration:overline}.xterm-overline.xterm-underline-1{text-decoration:overline underline}.xterm-overline.xterm-underline-2{-webkit-text-decoration:overline double underline;text-decoration:overline double underline}.xterm-overline.xterm-underline-3{-webkit-text-decoration:overline wavy underline;text-decoration:overline wavy underline}.xterm-overline.xterm-underline-4{-webkit-text-decoration:overline dotted underline;text-decoration:overline dotted underline}.xterm-overline.xterm-underline-5{-webkit-text-decoration:overline dashed underline;text-decoration:overline dashed underline}.xterm-strikethrough{text-decoration:line-through}.xterm-screen .xterm-decoration-container .xterm-decoration{z-index:6;position:absolute}.xterm-screen .xterm-decoration-container .xterm-decoration.xterm-decoration-top-layer{z-index:7}.xterm-decoration-overview-ruler{z-index:8;position:absolute;top:0;right:0;pointer-events:none}.xterm-decoration-top{z-index:2;position:relative}*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--font-mono),SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}[type=text],input:where(:not([type])),[type=email],[type=url],[type=password],[type=number],[type=date],[type=datetime-local],[type=month],[type=search],[type=tel],[type=time],[type=week],[multiple],textarea,select{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;border-color:#6b7280;border-width:1px;border-radius:0;padding:.5rem .75rem;font-size:1rem;line-height:1.5rem;--tw-shadow: 0 0 #0000}[type=text]:focus,input:where(:not([type])):focus,[type=email]:focus,[type=url]:focus,[type=password]:focus,[type=number]:focus,[type=date]:focus,[type=datetime-local]:focus,[type=month]:focus,[type=search]:focus,[type=tel]:focus,[type=time]:focus,[type=week]:focus,[multiple]:focus,textarea:focus,select:focus{outline:2px solid transparent;outline-offset:2px;--tw-ring-inset: var(--tw-empty, );--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: #2563eb;--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);border-color:#2563eb}input::-moz-placeholder,textarea::-moz-placeholder{color:#6b7280;opacity:1}input::placeholder,textarea::placeholder{color:#6b7280;opacity:1}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-date-and-time-value{min-height:1.5em;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit,::-webkit-datetime-edit-year-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute-field,::-webkit-datetime-edit-second-field,::-webkit-datetime-edit-millisecond-field,::-webkit-datetime-edit-meridiem-field{padding-top:0;padding-bottom:0}select{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e");background-position:right .5rem center;background-repeat:no-repeat;background-size:1.5em 1.5em;padding-right:2.5rem;-webkit-print-color-adjust:exact;print-color-adjust:exact}[multiple],[size]:where(select:not([size="1"])){background-image:initial;background-position:initial;background-repeat:unset;background-size:initial;padding-right:.75rem;-webkit-print-color-adjust:unset;print-color-adjust:unset}[type=checkbox],[type=radio]{-webkit-appearance:none;-moz-appearance:none;appearance:none;padding:0;-webkit-print-color-adjust:exact;print-color-adjust:exact;display:inline-block;vertical-align:middle;background-origin:border-box;-webkit-user-select:none;-moz-user-select:none;user-select:none;flex-shrink:0;height:1rem;width:1rem;color:#2563eb;background-color:#fff;border-color:#6b7280;border-width:1px;--tw-shadow: 0 0 #0000}[type=checkbox]{border-radius:0}[type=radio]{border-radius:100%}[type=checkbox]:focus,[type=radio]:focus{outline:2px solid transparent;outline-offset:2px;--tw-ring-inset: var(--tw-empty, );--tw-ring-offset-width: 2px;--tw-ring-offset-color: #fff;--tw-ring-color: #2563eb;--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}[type=checkbox]:checked,[type=radio]:checked{border-color:transparent;background-color:currentColor;background-size:100% 100%;background-position:center;background-repeat:no-repeat}[type=checkbox]:checked{background-image:url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3e%3c/svg%3e")}@media (forced-colors: active){[type=checkbox]:checked{-webkit-appearance:auto;-moz-appearance:auto;appearance:auto}}[type=radio]:checked{background-image:url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3ccircle cx='8' cy='8' r='3'/%3e%3c/svg%3e")}@media (forced-colors: active){[type=radio]:checked{-webkit-appearance:auto;-moz-appearance:auto;appearance:auto}}[type=checkbox]:checked:hover,[type=checkbox]:checked:focus,[type=radio]:checked:hover,[type=radio]:checked:focus{border-color:transparent;background-color:currentColor}[type=checkbox]:indeterminate{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 16'%3e%3cpath stroke='white' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M4 8h8'/%3e%3c/svg%3e");border-color:transparent;background-color:currentColor;background-size:100% 100%;background-position:center;background-repeat:no-repeat}@media (forced-colors: active){[type=checkbox]:indeterminate{-webkit-appearance:auto;-moz-appearance:auto;appearance:auto}}[type=checkbox]:indeterminate:hover,[type=checkbox]:indeterminate:focus{border-color:transparent;background-color:currentColor}[type=file]{background:unset;border-color:inherit;border-width:0;border-radius:0;padding:0;font-size:unset;line-height:inherit}[type=file]:focus{outline:1px solid ButtonText;outline:1px auto -webkit-focus-ring-color}:root{--background: 0 0% 100%;--foreground: 222.2 84% 4.9%;--card: 0 0% 100%;--card-foreground: 222.2 84% 4.9%;--popover: 0 0% 100%;--popover-foreground: 222.2 84% 4.9%;--primary: 221.2 83.2% 53.3%;--primary-foreground: 210 40% 98%;--secondary: 210 40% 96.1%;--secondary-foreground: 222.2 47.4% 11.2%;--muted: 210 40% 96.1%;--muted-foreground: 215.4 16.3% 46.9%;--accent: 210 40% 96.1%;--accent-foreground: 222.2 47.4% 11.2%;--destructive: 0 84.2% 60.2%;--destructive-foreground: 210 40% 98%;--border: 214.3 31.8% 91.4%;--input: 214.3 31.8% 91.4%;--ring: 221.2 83.2% 53.3%;--radius: .5rem;--terminal-background: 210 40% 98%;--terminal-foreground: 222.2 47.4% 11.2%;--terminal-cursor: 221.2 83.2% 53.3%;--terminal-selection: 221.2 83.2% 53.3%;--terminal-selection-opacity: .22;--font-mono: "Ubuntu Mono", "JetBrains Mono", "Fira Code", "SFMono-Regular", "Menlo", "Monaco", "Consolas", "Liberation Mono", "Courier New", monospace}.dark{--background: 222.2 84% 4.9%;--foreground: 210 40% 98%;--card: 222.2 84% 4.9%;--card-foreground: 210 40% 98%;--popover: 222.2 84% 4.9%;--popover-foreground: 210 40% 98%;--primary: 217.2 91.2% 59.8%;--primary-foreground: 222.2 47.4% 11.2%;--secondary: 217.2 32.6% 17.5%;--secondary-foreground: 210 40% 98%;--muted: 217.2 32.6% 17.5%;--muted-foreground: 215 20.2% 65.1%;--accent: 217.2 32.6% 17.5%;--accent-foreground: 210 40% 98%;--destructive: 0 62.8% 30.6%;--destructive-foreground: 210 40% 98%;--border: 217.2 32.6% 17.5%;--input: 217.2 32.6% 17.5%;--ring: 224.3 76.3% 48%;--terminal-background: 222.2 32% 14%;--terminal-foreground: 210 40% 94%;--terminal-cursor: 217.2 91.2% 59.8%;--terminal-selection: 217.2 91.2% 65%;--terminal-selection-opacity: .38;--font-mono: "Ubuntu Mono", "JetBrains Mono", "Fira Code", "SFMono-Regular", "Menlo", "Monaco", "Consolas", "Liberation Mono", "Courier New", monospace}.theme-ocean{--background: 204 80% 98%;--foreground: 210 40% 15%;--card: 204 80% 98%;--card-foreground: 210 40% 15%;--popover: 204 80% 98%;--popover-foreground: 210 40% 15%;--primary: 199 89% 48%;--primary-foreground: 210 40% 98%;--secondary: 200 60% 92%;--secondary-foreground: 210 40% 25%;--muted: 200 50% 95%;--muted-foreground: 210 20% 40%;--accent: 200 55% 93%;--accent-foreground: 210 40% 25%;--destructive: 0 70% 55%;--destructive-foreground: 210 40% 98%;--border: 200 30% 85%;--input: 200 30% 85%;--ring: 199 89% 48%;--terminal-background: 200 65% 96%;--terminal-foreground: 210 40% 22%;--terminal-cursor: 199 89% 48%;--terminal-selection: 199 89% 48%;--terminal-selection-opacity: .28;--font-mono: "Ubuntu Mono", "JetBrains Mono", "Fira Code", "SFMono-Regular", "Menlo", "Monaco", "Consolas", "Liberation Mono", "Courier New", monospace}*{border-color:hsl(var(--border))}body{background-color:hsl(var(--background));color:hsl(var(--foreground));font-feature-settings:"rlig" 1,"calt" 1}.container{width:100%;margin-right:auto;margin-left:auto;padding-right:2rem;padding-left:2rem}@media (min-width: 1400px){.container{max-width:1400px}}.prose{color:var(--tw-prose-body);max-width:65ch}.prose :where(p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em}.prose :where([class~=lead]):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-lead);font-size:1.25em;line-height:1.6;margin-top:1.2em;margin-bottom:1.2em}.prose :where(a):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-links);text-decoration:underline;font-weight:500}.prose :where(strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-bold);font-weight:600}.prose :where(a strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(blockquote strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(thead th strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(ol):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:decimal;margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em}.prose :where(ol[type=A]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-alpha}.prose :where(ol[type=a]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-alpha}.prose :where(ol[type=A s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-alpha}.prose :where(ol[type=a s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-alpha}.prose :where(ol[type=I]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-roman}.prose :where(ol[type=i]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-roman}.prose :where(ol[type=I s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-roman}.prose :where(ol[type=i s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-roman}.prose :where(ol[type="1"]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:decimal}.prose :where(ul):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:disc;margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em}.prose :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *))::marker{font-weight:400;color:var(--tw-prose-counters)}.prose :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *))::marker{color:var(--tw-prose-bullets)}.prose :where(dt):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;margin-top:1.25em}.prose :where(hr):not(:where([class~=not-prose],[class~=not-prose] *)){border-color:var(--tw-prose-hr);border-top-width:1px;margin-top:3em;margin-bottom:3em}.prose :where(blockquote):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:500;font-style:italic;color:var(--tw-prose-quotes);border-inline-start-width:.25rem;border-inline-start-color:var(--tw-prose-quote-borders);quotes:"“""”""‘""’";margin-top:1.6em;margin-bottom:1.6em;padding-inline-start:1em}.prose :where(blockquote p:first-of-type):not(:where([class~=not-prose],[class~=not-prose] *)):before{content:open-quote}.prose :where(blockquote p:last-of-type):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:close-quote}.prose :where(h1):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:800;font-size:2.25em;margin-top:0;margin-bottom:.8888889em;line-height:1.1111111}.prose :where(h1 strong):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:900;color:inherit}.prose :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:700;font-size:1.5em;margin-top:2em;margin-bottom:1em;line-height:1.3333333}.prose :where(h2 strong):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:800;color:inherit}.prose :where(h3):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;font-size:1.25em;margin-top:1.6em;margin-bottom:.6em;line-height:1.6}.prose :where(h3 strong):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:700;color:inherit}.prose :where(h4):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;margin-top:1.5em;margin-bottom:.5em;line-height:1.5}.prose :where(h4 strong):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:700;color:inherit}.prose :where(img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(picture):not(:where([class~=not-prose],[class~=not-prose] *)){display:block;margin-top:2em;margin-bottom:2em}.prose :where(video):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:500;font-family:inherit;color:var(--tw-prose-kbd);box-shadow:0 0 0 1px var(--tw-prose-kbd-shadows),0 3px 0 var(--tw-prose-kbd-shadows);font-size:.875em;border-radius:.3125rem;padding-top:.1875em;padding-inline-end:.375em;padding-bottom:.1875em;padding-inline-start:.375em}.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-code);font-weight:600;font-size:.875em}.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)):before{content:"`"}.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:"`"}.prose :where(a code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(h1 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(h2 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-size:.875em}.prose :where(h3 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-size:.9em}.prose :where(h4 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(blockquote code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(thead th code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(pre):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-pre-code);background-color:var(--tw-prose-pre-bg);overflow-x:auto;font-weight:400;font-size:.875em;line-height:1.7142857;margin-top:1.7142857em;margin-bottom:1.7142857em;border-radius:.375rem;padding-top:.8571429em;padding-inline-end:1.1428571em;padding-bottom:.8571429em;padding-inline-start:1.1428571em}.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)){background-color:transparent;border-width:0;border-radius:0;padding:0;font-weight:inherit;color:inherit;font-size:inherit;font-family:inherit;line-height:inherit}.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)):before{content:none}.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:none}.prose :where(table):not(:where([class~=not-prose],[class~=not-prose] *)){width:100%;table-layout:auto;margin-top:2em;margin-bottom:2em;font-size:.875em;line-height:1.7142857}.prose :where(thead):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:1px;border-bottom-color:var(--tw-prose-th-borders)}.prose :where(thead th):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;vertical-align:bottom;padding-inline-end:.5714286em;padding-bottom:.5714286em;padding-inline-start:.5714286em}.prose :where(tbody tr):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:1px;border-bottom-color:var(--tw-prose-td-borders)}.prose :where(tbody tr:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:0}.prose :where(tbody td):not(:where([class~=not-prose],[class~=not-prose] *)){vertical-align:baseline}.prose :where(tfoot):not(:where([class~=not-prose],[class~=not-prose] *)){border-top-width:1px;border-top-color:var(--tw-prose-th-borders)}.prose :where(tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){vertical-align:top}.prose :where(th,td):not(:where([class~=not-prose],[class~=not-prose] *)){text-align:start}.prose :where(figure>*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose :where(figcaption):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-captions);font-size:.875em;line-height:1.4285714;margin-top:.8571429em}.prose{--tw-prose-body: #374151;--tw-prose-headings: #111827;--tw-prose-lead: #4b5563;--tw-prose-links: #111827;--tw-prose-bold: #111827;--tw-prose-counters: #6b7280;--tw-prose-bullets: #d1d5db;--tw-prose-hr: #e5e7eb;--tw-prose-quotes: #111827;--tw-prose-quote-borders: #e5e7eb;--tw-prose-captions: #6b7280;--tw-prose-kbd: #111827;--tw-prose-kbd-shadows: rgb(17 24 39 / 10%);--tw-prose-code: #111827;--tw-prose-pre-code: #e5e7eb;--tw-prose-pre-bg: #1f2937;--tw-prose-th-borders: #d1d5db;--tw-prose-td-borders: #e5e7eb;--tw-prose-invert-body: #d1d5db;--tw-prose-invert-headings: #fff;--tw-prose-invert-lead: #9ca3af;--tw-prose-invert-links: #fff;--tw-prose-invert-bold: #fff;--tw-prose-invert-counters: #9ca3af;--tw-prose-invert-bullets: #4b5563;--tw-prose-invert-hr: #374151;--tw-prose-invert-quotes: #f3f4f6;--tw-prose-invert-quote-borders: #374151;--tw-prose-invert-captions: #9ca3af;--tw-prose-invert-kbd: #fff;--tw-prose-invert-kbd-shadows: rgb(255 255 255 / 10%);--tw-prose-invert-code: #fff;--tw-prose-invert-pre-code: #d1d5db;--tw-prose-invert-pre-bg: rgb(0 0 0 / 50%);--tw-prose-invert-th-borders: #4b5563;--tw-prose-invert-td-borders: #374151;font-size:1rem;line-height:1.75}.prose :where(picture>img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose :where(li):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5em;margin-bottom:.5em}.prose :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:.375em}.prose :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:.375em}.prose :where(.prose>ul>li p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.75em;margin-bottom:.75em}.prose :where(.prose>ul>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose :where(.prose>ul>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.prose :where(.prose>ol>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose :where(.prose>ol>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.prose :where(ul ul,ul ol,ol ul,ol ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.75em;margin-bottom:.75em}.prose :where(dl):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em}.prose :where(dd):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5em;padding-inline-start:1.625em}.prose :where(hr+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(h2+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(h3+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(h4+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(thead th:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose :where(thead th:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose :where(tbody td,tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){padding-top:.5714286em;padding-inline-end:.5714286em;padding-bottom:.5714286em;padding-inline-start:.5714286em}.prose :where(tbody td:first-child,tfoot td:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose :where(tbody td:last-child,tfoot td:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose :where(figure):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(.prose>:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(.prose>:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:0}.prose-sm{font-size:.875rem;line-height:1.7142857}.prose-sm :where(p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.1428571em;margin-bottom:1.1428571em}.prose-sm :where([class~=lead]):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:1.2857143em;line-height:1.5555556;margin-top:.8888889em;margin-bottom:.8888889em}.prose-sm :where(blockquote):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.3333333em;margin-bottom:1.3333333em;padding-inline-start:1.1111111em}.prose-sm :where(h1):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:2.1428571em;margin-top:0;margin-bottom:.8em;line-height:1.2}.prose-sm :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:1.4285714em;margin-top:1.6em;margin-bottom:.8em;line-height:1.4}.prose-sm :where(h3):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:1.2857143em;margin-top:1.5555556em;margin-bottom:.4444444em;line-height:1.5555556}.prose-sm :where(h4):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.4285714em;margin-bottom:.5714286em;line-height:1.4285714}.prose-sm :where(img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.7142857em;margin-bottom:1.7142857em}.prose-sm :where(picture):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.7142857em;margin-bottom:1.7142857em}.prose-sm :where(picture>img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose-sm :where(video):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.7142857em;margin-bottom:1.7142857em}.prose-sm :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:.8571429em;border-radius:.3125rem;padding-top:.1428571em;padding-inline-end:.3571429em;padding-bottom:.1428571em;padding-inline-start:.3571429em}.prose-sm :where(code):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:.8571429em}.prose-sm :where(h2 code):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:.9em}.prose-sm :where(h3 code):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:.8888889em}.prose-sm :where(pre):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:.8571429em;line-height:1.6666667;margin-top:1.6666667em;margin-bottom:1.6666667em;border-radius:.25rem;padding-top:.6666667em;padding-inline-end:1em;padding-bottom:.6666667em;padding-inline-start:1em}.prose-sm :where(ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.1428571em;margin-bottom:1.1428571em;padding-inline-start:1.5714286em}.prose-sm :where(ul):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.1428571em;margin-bottom:1.1428571em;padding-inline-start:1.5714286em}.prose-sm :where(li):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.2857143em;margin-bottom:.2857143em}.prose-sm :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:.4285714em}.prose-sm :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:.4285714em}.prose-sm :where(.prose-sm>ul>li p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5714286em;margin-bottom:.5714286em}.prose-sm :where(.prose-sm>ul>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.1428571em}.prose-sm :where(.prose-sm>ul>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.1428571em}.prose-sm :where(.prose-sm>ol>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.1428571em}.prose-sm :where(.prose-sm>ol>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.1428571em}.prose-sm :where(ul ul,ul ol,ol ul,ol ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5714286em;margin-bottom:.5714286em}.prose-sm :where(dl):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.1428571em;margin-bottom:1.1428571em}.prose-sm :where(dt):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.1428571em}.prose-sm :where(dd):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.2857143em;padding-inline-start:1.5714286em}.prose-sm :where(hr):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2.8571429em;margin-bottom:2.8571429em}.prose-sm :where(hr+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose-sm :where(h2+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose-sm :where(h3+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose-sm :where(h4+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose-sm :where(table):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:.8571429em;line-height:1.5}.prose-sm :where(thead th):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:1em;padding-bottom:.6666667em;padding-inline-start:1em}.prose-sm :where(thead th:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose-sm :where(thead th:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose-sm :where(tbody td,tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){padding-top:.6666667em;padding-inline-end:1em;padding-bottom:.6666667em;padding-inline-start:1em}.prose-sm :where(tbody td:first-child,tfoot td:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose-sm :where(tbody td:last-child,tfoot td:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose-sm :where(figure):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.7142857em;margin-bottom:1.7142857em}.prose-sm :where(figure>*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose-sm :where(figcaption):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:.8571429em;line-height:1.3333333;margin-top:.6666667em}.prose-sm :where(.prose-sm>:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose-sm :where(.prose-sm>:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:0}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.pointer-events-none{pointer-events:none}.pointer-events-auto{pointer-events:auto}.visible{visibility:visible}.collapse{visibility:collapse}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{top:0;right:0;bottom:0;left:0}.inset-x-0{left:0;right:0}.inset-y-0{top:0;bottom:0}.bottom-0{bottom:0}.bottom-full{bottom:100%}.left-0{left:0}.left-16{left:4rem}.left-2{left:.5rem}.left-3{left:.75rem}.left-\[50\%\]{left:50%}.right-0{right:0}.right-2{right:.5rem}.right-4{right:1rem}.top-0{top:0}.top-1\/2{top:50%}.top-2{top:.5rem}.top-2\.5{top:.625rem}.top-4{top:1rem}.top-\[50\%\]{top:50%}.z-10{z-index:10}.z-20{z-index:20}.z-40{z-index:40}.z-50{z-index:50}.z-\[100\]{z-index:100}.z-\[120\]{z-index:120}.z-\[80\]{z-index:80}.-m-6{margin:-1.5rem}.-mx-1{margin-left:-.25rem;margin-right:-.25rem}.-mx-6{margin-left:-1.5rem;margin-right:-1.5rem}.mx-3{margin-left:.75rem;margin-right:.75rem}.mx-auto{margin-left:auto;margin-right:auto}.my-1{margin-top:.25rem;margin-bottom:.25rem}.mb-1{margin-bottom:.25rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-6{margin-bottom:1.5rem}.ml-1{margin-left:.25rem}.ml-2{margin-left:.5rem}.ml-4{margin-left:1rem}.ml-auto{margin-left:auto}.mr-1{margin-right:.25rem}.mr-1\.5{margin-right:.375rem}.mr-2{margin-right:.5rem}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-24{margin-top:6rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-6{margin-top:1.5rem}.mt-auto{margin-top:auto}.line-clamp-1{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1}.line-clamp-2{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2}.line-clamp-3{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3}.line-clamp-4{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:4}.line-clamp-5{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:5}.line-clamp-6{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:6}.block{display:block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.\!hidden{display:none!important}.hidden{display:none}.h-1\.5{height:.375rem}.h-10{height:2.5rem}.h-11{height:2.75rem}.h-12{height:3rem}.h-16{height:4rem}.h-2{height:.5rem}.h-2\.5{height:.625rem}.h-3{height:.75rem}.h-3\.5{height:.875rem}.h-4{height:1rem}.h-40{height:10rem}.h-48{height:12rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-7{height:1.75rem}.h-8{height:2rem}.h-9{height:2.25rem}.h-\[160px\]{height:160px}.h-\[200px\]{height:200px}.h-\[220px\]{height:220px}.h-\[320px\]{height:320px}.h-\[calc\(100\%-3rem\)\]{height:calc(100% - 3rem)}.h-\[calc\(100vh-24rem\)\]{height:calc(100vh - 24rem)}.h-\[var\(--radix-select-trigger-height\)\]{height:var(--radix-select-trigger-height)}.h-auto{height:auto}.h-full{height:100%}.h-px{height:1px}.h-screen{height:100vh}.max-h-48{max-height:12rem}.max-h-60{max-height:15rem}.max-h-64{max-height:16rem}.max-h-96{max-height:24rem}.max-h-\[200px\]{max-height:200px}.max-h-\[70vh\]{max-height:70vh}.max-h-\[90vh\]{max-height:90vh}.max-h-\[96\%\]{max-height:96%}.max-h-screen{max-height:100vh}.min-h-0{min-height:0px}.min-h-\[200px\]{min-height:200px}.min-h-\[220px\]{min-height:220px}.min-h-\[300px\]{min-height:300px}.min-h-\[320px\]{min-height:320px}.min-h-\[42px\]{min-height:42px}.min-h-\[60px\]{min-height:60px}.min-h-\[60vh\]{min-height:60vh}.min-h-\[80px\]{min-height:80px}.min-h-full{min-height:100%}.w-0{width:0px}.w-1\.5{width:.375rem}.w-10{width:2.5rem}.w-12{width:3rem}.w-16{width:4rem}.w-2{width:.5rem}.w-2\.5{width:.625rem}.w-20{width:5rem}.w-3{width:.75rem}.w-3\.5{width:.875rem}.w-4{width:1rem}.w-40{width:10rem}.w-48{width:12rem}.w-5{width:1.25rem}.w-56{width:14rem}.w-6{width:1.5rem}.w-64{width:16rem}.w-7{width:1.75rem}.w-72{width:18rem}.w-8{width:2rem}.w-80{width:20rem}.w-9{width:2.25rem}.w-\[140px\]{width:140px}.w-\[160px\]{width:160px}.w-\[180px\]{width:180px}.w-\[200px\]{width:200px}.w-\[22rem\]{width:22rem}.w-\[260px\]{width:260px}.w-\[340px\]{width:340px}.w-full{width:100%}.w-px{width:1px}.min-w-0{min-width:0px}.min-w-\[100px\]{min-width:100px}.min-w-\[120px\]{min-width:120px}.min-w-\[200px\]{min-width:200px}.min-w-\[80px\]{min-width:80px}.min-w-\[8rem\]{min-width:8rem}.min-w-\[var\(--radix-select-trigger-width\)\]{min-width:var(--radix-select-trigger-width)}.max-w-2xl{max-width:42rem}.max-w-3xl{max-width:48rem}.max-w-4xl{max-width:56rem}.max-w-5xl{max-width:64rem}.max-w-\[360px\]{max-width:360px}.max-w-\[80px\]{max-width:80px}.max-w-lg{max-width:32rem}.max-w-md{max-width:28rem}.max-w-none{max-width:none}.max-w-xl{max-width:36rem}.flex-1{flex:1 1 0%}.flex-none{flex:none}.flex-shrink-0,.shrink-0{flex-shrink:0}.grow{flex-grow:1}.caption-bottom{caption-side:bottom}.-translate-x-full{--tw-translate-x: -100%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-y-1\/2{--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-0{--tw-translate-x: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-\[-50\%\]{--tw-translate-x: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-y-\[-50\%\]{--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.rotate-90{--tw-rotate: 90deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.scale-95{--tw-scale-x: .95;--tw-scale-y: .95;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.cursor-default{cursor:default}.cursor-move{cursor:move}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.touch-none{touch-action:none}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.resize-none{resize:none}.resize-y{resize:vertical}.resize{resize:both}.snap-x{scroll-snap-type:x var(--tw-scroll-snap-strictness)}.snap-mandatory{--tw-scroll-snap-strictness: mandatory}.snap-start{scroll-snap-align:start}.list-disc{list-style-type:disc}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.items-baseline{align-items:baseline}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-0\.5{gap:.125rem}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-6{gap:1.5rem}.space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(.5rem * var(--tw-space-x-reverse));margin-left:calc(.5rem * calc(1 - var(--tw-space-x-reverse)))}.space-x-4>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(1rem * var(--tw-space-x-reverse));margin-left:calc(1rem * calc(1 - var(--tw-space-x-reverse)))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-1\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.375rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.375rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse))}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-line{white-space:pre-line}.whitespace-pre-wrap{white-space:pre-wrap}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.rounded{border-radius:.25rem}.rounded-\[inherit\]{border-radius:inherit}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:var(--radius)}.rounded-md{border-radius:calc(var(--radius) - 2px)}.rounded-sm{border-radius:calc(var(--radius) - 4px)}.rounded-xl{border-radius:.75rem}.rounded-t-\[10px\]{border-top-left-radius:10px;border-top-right-radius:10px}.rounded-t-lg{border-top-left-radius:var(--radius);border-top-right-radius:var(--radius)}.border{border-width:1px}.border-0{border-width:0px}.border-b{border-bottom-width:1px}.border-l{border-left-width:1px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-dashed{border-style:dashed}.border-amber-200{--tw-border-opacity: 1;border-color:rgb(253 230 138 / var(--tw-border-opacity, 1))}.border-amber-500{--tw-border-opacity: 1;border-color:rgb(245 158 11 / var(--tw-border-opacity, 1))}.border-amber-500\/40{border-color:#f59e0b66}.border-border{border-color:hsl(var(--border))}.border-border\/60{border-color:hsl(var(--border) / .6)}.border-destructive{border-color:hsl(var(--destructive))}.border-destructive\/40{border-color:hsl(var(--destructive) / .4)}.border-destructive\/50{border-color:hsl(var(--destructive) / .5)}.border-emerald-500{--tw-border-opacity: 1;border-color:rgb(16 185 129 / var(--tw-border-opacity, 1))}.border-emerald-500\/40{border-color:#10b98166}.border-green-600{--tw-border-opacity: 1;border-color:rgb(22 163 74 / var(--tw-border-opacity, 1))}.border-input{border-color:hsl(var(--input))}.border-muted{border-color:hsl(var(--muted))}.border-primary{border-color:hsl(var(--primary))}.border-primary\/50{border-color:hsl(var(--primary) / .5)}.border-primary\/60{border-color:hsl(var(--primary) / .6)}.border-transparent{border-color:transparent}.border-yellow-600{--tw-border-opacity: 1;border-color:rgb(202 138 4 / var(--tw-border-opacity, 1))}.border-l-transparent{border-left-color:transparent}.border-t-transparent{border-top-color:transparent}.bg-accent{background-color:hsl(var(--accent))}.bg-amber-400{--tw-bg-opacity: 1;background-color:rgb(251 191 36 / var(--tw-bg-opacity, 1))}.bg-amber-50{--tw-bg-opacity: 1;background-color:rgb(255 251 235 / var(--tw-bg-opacity, 1))}.bg-amber-500{--tw-bg-opacity: 1;background-color:rgb(245 158 11 / var(--tw-bg-opacity, 1))}.bg-amber-500\/10{background-color:#f59e0b1a}.bg-background{background-color:hsl(var(--background))}.bg-background\/50{background-color:hsl(var(--background) / .5)}.bg-background\/60{background-color:hsl(var(--background) / .6)}.bg-background\/95{background-color:hsl(var(--background) / .95)}.bg-black\/50{background-color:#00000080}.bg-black\/80{background-color:#000c}.bg-border{background-color:hsl(var(--border))}.bg-card{background-color:hsl(var(--card))}.bg-card\/50{background-color:hsl(var(--card) / .5)}.bg-current{background-color:currentColor}.bg-destructive{background-color:hsl(var(--destructive))}.bg-destructive\/10{background-color:hsl(var(--destructive) / .1)}.bg-emerald-500{--tw-bg-opacity: 1;background-color:rgb(16 185 129 / var(--tw-bg-opacity, 1))}.bg-emerald-500\/10{background-color:#10b9811a}.bg-muted{background-color:hsl(var(--muted))}.bg-muted-foreground{background-color:hsl(var(--muted-foreground))}.bg-muted\/20{background-color:hsl(var(--muted) / .2)}.bg-muted\/30{background-color:hsl(var(--muted) / .3)}.bg-muted\/40{background-color:hsl(var(--muted) / .4)}.bg-muted\/50{background-color:hsl(var(--muted) / .5)}.bg-muted\/60{background-color:hsl(var(--muted) / .6)}.bg-muted\/80{background-color:hsl(var(--muted) / .8)}.bg-popover{background-color:hsl(var(--popover))}.bg-primary{background-color:hsl(var(--primary))}.bg-primary\/10{background-color:hsl(var(--primary) / .1)}.bg-primary\/5{background-color:hsl(var(--primary) / .05)}.bg-secondary{background-color:hsl(var(--secondary))}.bg-terminal{background-color:hsl(var(--terminal-background))}.bg-terminal\/80{background-color:hsl(var(--terminal-background) / .8)}.bg-transparent{background-color:transparent}.bg-yellow-500\/10{background-color:#eab3081a}.fill-amber-500{fill:#f59e0b}.fill-current{fill:currentColor}.object-cover{-o-object-fit:cover;object-fit:cover}.p-0{padding:0}.p-1{padding:.25rem}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-6{padding:1.5rem}.p-8{padding:2rem}.p-\[1px\]{padding:1px}.px-0{padding-left:0;padding-right:0}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-8{padding-left:2rem;padding-right:2rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-10{padding-top:2.5rem;padding-bottom:2.5rem}.py-12{padding-top:3rem;padding-bottom:3rem}.py-16{padding-top:4rem;padding-bottom:4rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pb-2{padding-bottom:.5rem}.pb-4{padding-bottom:1rem}.pl-0{padding-left:0}.pl-10{padding-left:2.5rem}.pl-3{padding-left:.75rem}.pl-6{padding-left:1.5rem}.pl-8{padding-left:2rem}.pl-9{padding-left:2.25rem}.pr-1{padding-right:.25rem}.pr-2{padding-right:.5rem}.pr-4{padding-right:1rem}.pr-8{padding-right:2rem}.pt-0{padding-top:0}.pt-1{padding-top:.25rem}.pt-2{padding-top:.5rem}.pt-3{padding-top:.75rem}.pt-4{padding-top:1rem}.pt-6{padding-top:1.5rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.align-middle{vertical-align:middle}.font-mono{font-family:var(--font-mono),SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-9xl{font-size:8rem;line-height:1}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[13px\]{font-size:13px}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-normal{font-weight:400}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.capitalize{text-transform:capitalize}.leading-none{line-height:1}.leading-relaxed{line-height:1.625}.leading-snug{line-height:1.375}.leading-tight{line-height:1.25}.tracking-tight{letter-spacing:-.025em}.tracking-wide{letter-spacing:.025em}.tracking-widest{letter-spacing:.1em}.text-accent-foreground{color:hsl(var(--accent-foreground))}.text-amber-500{--tw-text-opacity: 1;color:rgb(245 158 11 / var(--tw-text-opacity, 1))}.text-amber-600{--tw-text-opacity: 1;color:rgb(217 119 6 / var(--tw-text-opacity, 1))}.text-amber-800{--tw-text-opacity: 1;color:rgb(146 64 14 / var(--tw-text-opacity, 1))}.text-card-foreground{color:hsl(var(--card-foreground))}.text-current{color:currentColor}.text-destructive{color:hsl(var(--destructive))}.text-destructive-foreground{color:hsl(var(--destructive-foreground))}.text-emerald-600{--tw-text-opacity: 1;color:rgb(5 150 105 / var(--tw-text-opacity, 1))}.text-foreground{color:hsl(var(--foreground))}.text-foreground\/50{color:hsl(var(--foreground) / .5)}.text-green-500{--tw-text-opacity: 1;color:rgb(34 197 94 / var(--tw-text-opacity, 1))}.text-green-600{--tw-text-opacity: 1;color:rgb(22 163 74 / var(--tw-text-opacity, 1))}.text-muted-foreground{color:hsl(var(--muted-foreground))}.text-muted-foreground\/70{color:hsl(var(--muted-foreground) / .7)}.text-muted-foreground\/80{color:hsl(var(--muted-foreground) / .8)}.text-popover-foreground{color:hsl(var(--popover-foreground))}.text-primary{color:hsl(var(--primary))}.text-primary-foreground{color:hsl(var(--primary-foreground))}.text-red-500{--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity, 1))}.text-secondary-foreground{color:hsl(var(--secondary-foreground))}.text-terminal-foreground{color:hsl(var(--terminal-foreground))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.text-yellow-600{--tw-text-opacity: 1;color:rgb(202 138 4 / var(--tw-text-opacity, 1))}.text-yellow-700{--tw-text-opacity: 1;color:rgb(161 98 7 / var(--tw-text-opacity, 1))}.underline{text-decoration-line:underline}.decoration-dotted{text-decoration-style:dotted}.decoration-2{text-decoration-thickness:2px}.underline-offset-4{text-underline-offset:4px}.accent-foreground{accent-color:hsl(var(--foreground))}.opacity-0{opacity:0}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.opacity-75{opacity:.75}.opacity-90{opacity:.9}.shadow-\[0_20px_45px_rgba\(0\,0\,0\,0\.35\)\]{--tw-shadow: 0 20px 45px rgba(0,0,0,.35);--tw-shadow-colored: 0 20px 45px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-md{--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-none{--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.outline-none{outline:2px solid transparent;outline-offset:2px}.outline{outline-style:solid}.ring{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-2{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-inset{--tw-ring-inset: inset}.ring-primary{--tw-ring-color: hsl(var(--primary))}.ring-ring{--tw-ring-color: hsl(var(--ring))}.ring-offset-background{--tw-ring-offset-color: hsl(var(--background))}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.backdrop-blur{--tw-backdrop-blur: blur(8px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.backdrop-blur-sm{--tw-backdrop-blur: blur(4px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition-\[height\]{transition-property:height;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-shadow{transition-property:box-shadow;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-200{transition-duration:.2s}.duration-300{transition-duration:.3s}.ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}.\!loading,.loading{display:flex;height:100vh;align-items:center;justify-content:center;font-size:1.25rem;line-height:1.75rem}.dark\:prose-invert:is(.dark *){--tw-prose-body: var(--tw-prose-invert-body);--tw-prose-headings: var(--tw-prose-invert-headings);--tw-prose-lead: var(--tw-prose-invert-lead);--tw-prose-links: var(--tw-prose-invert-links);--tw-prose-bold: var(--tw-prose-invert-bold);--tw-prose-counters: var(--tw-prose-invert-counters);--tw-prose-bullets: var(--tw-prose-invert-bullets);--tw-prose-hr: var(--tw-prose-invert-hr);--tw-prose-quotes: var(--tw-prose-invert-quotes);--tw-prose-quote-borders: var(--tw-prose-invert-quote-borders);--tw-prose-captions: var(--tw-prose-invert-captions);--tw-prose-kbd: var(--tw-prose-invert-kbd);--tw-prose-kbd-shadows: var(--tw-prose-invert-kbd-shadows);--tw-prose-code: var(--tw-prose-invert-code);--tw-prose-pre-code: var(--tw-prose-invert-pre-code);--tw-prose-pre-bg: var(--tw-prose-invert-pre-bg);--tw-prose-th-borders: var(--tw-prose-invert-th-borders);--tw-prose-td-borders: var(--tw-prose-invert-td-borders)}.file\:border-0::file-selector-button{border-width:0px}.file\:bg-transparent::file-selector-button{background-color:transparent}.file\:text-sm::file-selector-button{font-size:.875rem;line-height:1.25rem}.file\:font-medium::file-selector-button{font-weight:500}.placeholder\:text-muted-foreground::-moz-placeholder{color:hsl(var(--muted-foreground))}.placeholder\:text-muted-foreground::placeholder{color:hsl(var(--muted-foreground))}.last\:border-b-0:last-child{border-bottom-width:0px}.hover\:bg-accent:hover{background-color:hsl(var(--accent))}.hover\:bg-amber-500\/20:hover{background-color:#f59e0b33}.hover\:bg-destructive\/10:hover{background-color:hsl(var(--destructive) / .1)}.hover\:bg-destructive\/20:hover{background-color:hsl(var(--destructive) / .2)}.hover\:bg-destructive\/80:hover{background-color:hsl(var(--destructive) / .8)}.hover\:bg-destructive\/90:hover{background-color:hsl(var(--destructive) / .9)}.hover\:bg-emerald-500\/20:hover{background-color:#10b98133}.hover\:bg-muted:hover{background-color:hsl(var(--muted))}.hover\:bg-muted\/40:hover{background-color:hsl(var(--muted) / .4)}.hover\:bg-muted\/50:hover{background-color:hsl(var(--muted) / .5)}.hover\:bg-muted\/60:hover{background-color:hsl(var(--muted) / .6)}.hover\:bg-muted\/70:hover{background-color:hsl(var(--muted) / .7)}.hover\:bg-muted\/80:hover{background-color:hsl(var(--muted) / .8)}.hover\:bg-primary\/80:hover{background-color:hsl(var(--primary) / .8)}.hover\:bg-primary\/90:hover{background-color:hsl(var(--primary) / .9)}.hover\:bg-secondary:hover{background-color:hsl(var(--secondary))}.hover\:bg-secondary\/80:hover{background-color:hsl(var(--secondary) / .8)}.hover\:bg-transparent:hover{background-color:transparent}.hover\:text-accent-foreground:hover{color:hsl(var(--accent-foreground))}.hover\:text-destructive:hover{color:hsl(var(--destructive))}.hover\:text-foreground:hover{color:hsl(var(--foreground))}.hover\:text-primary:hover{color:hsl(var(--primary))}.hover\:text-primary\/80:hover{color:hsl(var(--primary) / .8)}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-100:hover{opacity:1}.hover\:shadow-md:hover{--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.focus\:bg-accent:focus{background-color:hsl(var(--accent))}.focus\:bg-destructive\/10:focus{background-color:hsl(var(--destructive) / .1)}.focus\:bg-muted:focus{background-color:hsl(var(--muted))}.focus\:text-accent-foreground:focus{color:hsl(var(--accent-foreground))}.focus\:opacity-100:focus{opacity:1}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-2:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-ring:focus{--tw-ring-color: hsl(var(--ring))}.focus\:ring-offset-2:focus{--tw-ring-offset-width: 2px}.focus-visible\:outline-none:focus-visible{outline:2px solid transparent;outline-offset:2px}.focus-visible\:ring-1:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\:ring-2:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\:ring-destructive:focus-visible{--tw-ring-color: hsl(var(--destructive))}.focus-visible\:ring-ring:focus-visible{--tw-ring-color: hsl(var(--ring))}.focus-visible\:ring-offset-2:focus-visible{--tw-ring-offset-width: 2px}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}.group:focus-within .group-focus-within\:opacity-100{opacity:1}.group:hover .group-hover\:opacity-100{opacity:1}.group.destructive .group-\[\.destructive\]\:border-muted\/40{border-color:hsl(var(--muted) / .4)}.group.destructive .group-\[\.destructive\]\:text-red-300{--tw-text-opacity: 1;color:rgb(252 165 165 / var(--tw-text-opacity, 1))}.group.destructive .group-\[\.destructive\]\:hover\:border-destructive\/30:hover{border-color:hsl(var(--destructive) / .3)}.group.destructive .group-\[\.destructive\]\:hover\:bg-destructive:hover{background-color:hsl(var(--destructive))}.group.destructive .group-\[\.destructive\]\:hover\:text-destructive-foreground:hover{color:hsl(var(--destructive-foreground))}.group.destructive .group-\[\.destructive\]\:hover\:text-red-50:hover{--tw-text-opacity: 1;color:rgb(254 242 242 / var(--tw-text-opacity, 1))}.group.destructive .group-\[\.destructive\]\:focus\:ring-destructive:focus{--tw-ring-color: hsl(var(--destructive))}.group.destructive .group-\[\.destructive\]\:focus\:ring-red-400:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(248 113 113 / var(--tw-ring-opacity, 1))}.group.destructive .group-\[\.destructive\]\:focus\:ring-offset-red-600:focus{--tw-ring-offset-color: #dc2626}.peer:disabled~.peer-disabled\:cursor-not-allowed{cursor:not-allowed}.peer:disabled~.peer-disabled\:opacity-70{opacity:.7}.data-\[disabled\]\:pointer-events-none[data-disabled]{pointer-events:none}.data-\[side\=bottom\]\:translate-y-1[data-side=bottom]{--tw-translate-y: .25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[side\=left\]\:-translate-x-1[data-side=left]{--tw-translate-x: -.25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[side\=right\]\:translate-x-1[data-side=right]{--tw-translate-x: .25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[side\=top\]\:-translate-y-1[data-side=top]{--tw-translate-y: -.25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[swipe\=cancel\]\:translate-x-0[data-swipe=cancel]{--tw-translate-x: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[swipe\=end\]\:translate-x-\[var\(--radix-toast-swipe-end-x\)\][data-swipe=end]{--tw-translate-x: var(--radix-toast-swipe-end-x);transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[swipe\=move\]\:translate-x-\[var\(--radix-toast-swipe-move-x\)\][data-swipe=move]{--tw-translate-x: var(--radix-toast-swipe-move-x);transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[state\=checked\]\:bg-primary[data-state=checked]{background-color:hsl(var(--primary))}.data-\[state\=open\]\:bg-accent[data-state=open]{background-color:hsl(var(--accent))}.data-\[state\=selected\]\:bg-muted[data-state=selected]{background-color:hsl(var(--muted))}.data-\[state\=checked\]\:text-primary-foreground[data-state=checked]{color:hsl(var(--primary-foreground))}.data-\[state\=open\]\:text-muted-foreground[data-state=open]{color:hsl(var(--muted-foreground))}.data-\[disabled\]\:opacity-50[data-disabled]{opacity:.5}.data-\[swipe\=move\]\:transition-none[data-swipe=move]{transition-property:none}.sidebar-collapsed .sidebar-collapsed\:gap-3{gap:.75rem}.dark\:border-amber-800:is(.dark *){--tw-border-opacity: 1;border-color:rgb(146 64 14 / var(--tw-border-opacity, 1))}.dark\:border-destructive:is(.dark *){border-color:hsl(var(--destructive))}.dark\:bg-amber-950:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(69 26 3 / var(--tw-bg-opacity, 1))}.dark\:text-amber-200:is(.dark *){--tw-text-opacity: 1;color:rgb(253 230 138 / var(--tw-text-opacity, 1))}.dark\:text-amber-500:is(.dark *){--tw-text-opacity: 1;color:rgb(245 158 11 / var(--tw-text-opacity, 1))}@media (min-width: 640px){.sm\:bottom-0{bottom:0}.sm\:right-0{right:0}.sm\:top-auto{top:auto}.sm\:block{display:block}.sm\:hidden{display:none}.sm\:max-w-3xl{max-width:48rem}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.sm\:grid-cols-\[2fr\,1\.2fr\,1\.2fr\]{grid-template-columns:2fr 1.2fr 1.2fr}.sm\:flex-row{flex-direction:row}.sm\:flex-col{flex-direction:column}.sm\:items-center{align-items:center}.sm\:justify-end{justify-content:flex-end}.sm\:justify-center{justify-content:center}.sm\:justify-between{justify-content:space-between}.sm\:gap-4{gap:1rem}.sm\:space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(.5rem * var(--tw-space-x-reverse));margin-left:calc(.5rem * calc(1 - var(--tw-space-x-reverse)))}.sm\:rounded-lg{border-radius:var(--radius)}.sm\:text-left{text-align:left}}@media (min-width: 768px){.md\:flex{display:flex}.md\:max-w-\[420px\]{max-width:420px}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-\[minmax\(0\,1fr\)_280px\]{grid-template-columns:minmax(0,1fr) 280px}}@media (min-width: 1024px){.lg\:relative{position:relative}.lg\:left-0{left:0}.lg\:flex{display:flex}.lg\:inline-flex{display:inline-flex}.lg\:hidden{display:none}.lg\:max-h-\[520px\]{max-height:520px}.lg\:w-0{width:0px}.lg\:w-1\/2{width:50%}.lg\:min-w-\[360px\]{min-width:360px}.lg\:min-w-\[420px\]{min-width:420px}.lg\:max-w-5xl{max-width:64rem}.lg\:max-w-\[45\%\]{max-width:45%}.lg\:basis-\[45\%\]{flex-basis:45%}.lg\:basis-\[55\%\]{flex-basis:55%}.lg\:translate-x-0{--tw-translate-x: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.lg\:grid-cols-\[1fr_1\.5fr\]{grid-template-columns:1fr 1.5fr}.lg\:grid-cols-\[minmax\(0\,2fr\)_minmax\(260px\,1fr\)\]{grid-template-columns:minmax(0,2fr) minmax(260px,1fr)}.lg\:flex-row{flex-direction:row}.lg\:flex-col{flex-direction:column}.lg\:items-start{align-items:flex-start}.lg\:overflow-auto{overflow:auto}.lg\:px-6{padding-left:1.5rem;padding-right:1.5rem}}@media (min-width: 1280px){.xl\:max-w-6xl{max-width:72rem}}.\[\&\:has\(\[role\=checkbox\]\)\]\:pr-0:has([role=checkbox]){padding-right:0}.\[\&\>span\]\:line-clamp-1>span{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1}.\[\&\>svg\+div\]\:translate-y-\[-3px\]>svg+div{--tw-translate-y: -3px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.\[\&\>svg\]\:absolute>svg{position:absolute}.\[\&\>svg\]\:left-4>svg{left:1rem}.\[\&\>svg\]\:top-4>svg{top:1rem}.\[\&\>svg\]\:h-3\.5>svg{height:.875rem}.\[\&\>svg\]\:w-3\.5>svg{width:.875rem}.\[\&\>svg\]\:text-destructive>svg{color:hsl(var(--destructive))}.\[\&\>svg\]\:text-foreground>svg{color:hsl(var(--foreground))}.\[\&\>svg\~\*\]\:pl-7>svg~*{padding-left:1.75rem}.\[\&\>tr\]\:last\:border-b-0:last-child>tr{border-bottom-width:0px}.\[\&_a\:hover\]\:text-foreground a:hover{color:hsl(var(--foreground))}.\[\&_a\]\:text-muted-foreground a{color:hsl(var(--muted-foreground))}.\[\&_p\]\:leading-relaxed p{line-height:1.625}.\[\&_tr\:last-child\]\:border-0 tr:last-child{border-width:0px}.\[\&_tr\]\:border-b tr{border-bottom-width:1px}