@hasna/files 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +148 -0
- package/dashboard/dist/assets/index-DBpbr5zm.css +1 -0
- package/dashboard/dist/assets/index-zazl9Rbx.js +129 -0
- package/dashboard/dist/index.html +13 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +46386 -0
- package/dist/db/collections.d.ts +8 -0
- package/dist/db/collections.d.ts.map +1 -0
- package/dist/db/database.d.ts +5 -0
- package/dist/db/database.d.ts.map +1 -0
- package/dist/db/files.d.ts +12 -0
- package/dist/db/files.d.ts.map +1 -0
- package/dist/db/machines.d.ts +6 -0
- package/dist/db/machines.d.ts.map +1 -0
- package/dist/db/peers.d.ts +15 -0
- package/dist/db/peers.d.ts.map +1 -0
- package/dist/db/projects.d.ts +8 -0
- package/dist/db/projects.d.ts.map +1 -0
- package/dist/db/resolve.d.ts +9 -0
- package/dist/db/resolve.d.ts.map +1 -0
- package/dist/db/search.d.ts +6 -0
- package/dist/db/search.d.ts.map +1 -0
- package/dist/db/sources.d.ts +17 -0
- package/dist/db/sources.d.ts.map +1 -0
- package/dist/db/tags.d.ts +8 -0
- package/dist/db/tags.d.ts.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +43739 -0
- package/dist/lib/config.d.ts +13 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/hasher.d.ts +3 -0
- package/dist/lib/hasher.d.ts.map +1 -0
- package/dist/lib/ignore.d.ts +11 -0
- package/dist/lib/ignore.d.ts.map +1 -0
- package/dist/lib/indexer.d.ts +3 -0
- package/dist/lib/indexer.d.ts.map +1 -0
- package/dist/lib/s3.d.ts +12 -0
- package/dist/lib/s3.d.ts.map +1 -0
- package/dist/lib/sync.d.ts +19 -0
- package/dist/lib/sync.d.ts.map +1 -0
- package/dist/lib/watcher.d.ts +5 -0
- package/dist/lib/watcher.d.ts.map +1 -0
- package/dist/mcp/index.d.ts +3 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +55905 -0
- package/dist/server/index.d.ts +3 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +42191 -0
- package/dist/server/serve.d.ts +2 -0
- package/dist/server/serve.d.ts.map +1 -0
- package/dist/types/index.d.ts +104 -0
- package/dist/types/index.d.ts.map +1 -0
- package/package.json +77 -0
package/README.md
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# @hasna/files
|
|
2
|
+
|
|
3
|
+
Agent-first file management — index local folders and S3 buckets, tag, search, and retrieve files via CLI + MCP.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
bun install -g @hasna/files
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## CLI
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# Add sources
|
|
15
|
+
files sources add ./my-documents
|
|
16
|
+
files sources add s3://my-bucket --region us-east-1 --access-key KEY --secret-key SECRET
|
|
17
|
+
|
|
18
|
+
# Index
|
|
19
|
+
files index # index all sources on this machine
|
|
20
|
+
files index src_abc123 # index one source
|
|
21
|
+
|
|
22
|
+
# Search & list
|
|
23
|
+
files search "invoice 2024"
|
|
24
|
+
files list --tag important --ext pdf
|
|
25
|
+
files list --source src_abc123
|
|
26
|
+
|
|
27
|
+
# File operations
|
|
28
|
+
files info f_abc123
|
|
29
|
+
files tag f_abc123 invoice important
|
|
30
|
+
files untag f_abc123 invoice
|
|
31
|
+
files download f_abc123 # downloads to ~/Downloads/<name>
|
|
32
|
+
files upload ./report.pdf src_abc123
|
|
33
|
+
|
|
34
|
+
# Organize
|
|
35
|
+
files collections create "Q1 Reports"
|
|
36
|
+
files collections add col_abc123 f_abc123
|
|
37
|
+
files projects create "Tax 2025"
|
|
38
|
+
files projects add prj_abc123 f_abc123
|
|
39
|
+
|
|
40
|
+
# Multi-machine sync
|
|
41
|
+
files sync http://192.168.1.10:19432
|
|
42
|
+
|
|
43
|
+
# Info
|
|
44
|
+
files machines
|
|
45
|
+
files tags
|
|
46
|
+
files sources list
|
|
47
|
+
files db # show DB path
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## MCP Server
|
|
51
|
+
|
|
52
|
+
Add to your `claude_desktop_config.json` or `.mcp.json`:
|
|
53
|
+
|
|
54
|
+
```json
|
|
55
|
+
{
|
|
56
|
+
"mcpServers": {
|
|
57
|
+
"files": {
|
|
58
|
+
"command": "files-mcp"
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### MCP Tools
|
|
65
|
+
|
|
66
|
+
| Tool | Description |
|
|
67
|
+
|------|-------------|
|
|
68
|
+
| `list_sources` | List configured sources |
|
|
69
|
+
| `add_source` | Add local or S3 source |
|
|
70
|
+
| `remove_source` | Remove a source |
|
|
71
|
+
| `index_source` | Re-index source(s) |
|
|
72
|
+
| `list_files` | List files with filters |
|
|
73
|
+
| `search_files` | Full-text search |
|
|
74
|
+
| `get_file` | Get file details |
|
|
75
|
+
| `download_file` | Download file to disk |
|
|
76
|
+
| `upload_file` | Upload file to S3 |
|
|
77
|
+
| `list_tags` | List all tags |
|
|
78
|
+
| `tag_file` | Tag a file |
|
|
79
|
+
| `untag_file` | Remove tags |
|
|
80
|
+
| `list_collections` | List collections |
|
|
81
|
+
| `create_collection` | Create collection |
|
|
82
|
+
| `add_to_collection` | Add file to collection |
|
|
83
|
+
| `list_projects` | List projects |
|
|
84
|
+
| `create_project` | Create project |
|
|
85
|
+
| `add_to_project` | Add file to project |
|
|
86
|
+
| `list_machines` | List known machines |
|
|
87
|
+
|
|
88
|
+
## REST API
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
files-serve # starts on port 19432
|
|
92
|
+
files-serve --port 8080
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
| Endpoint | Method | Description |
|
|
96
|
+
|----------|--------|-------------|
|
|
97
|
+
| `/sources` | GET, POST | List / create sources |
|
|
98
|
+
| `/sources/:id` | DELETE | Remove source |
|
|
99
|
+
| `/sources/:id/index` | POST | Index source |
|
|
100
|
+
| `/files` | GET | List/search files (`?q=`, `?tag=`, `?ext=`, `?source_id=`) |
|
|
101
|
+
| `/files/:id` | GET | Get file |
|
|
102
|
+
| `/files/:id/download` | GET | Download file |
|
|
103
|
+
| `/files/:id/tags` | POST, DELETE | Tag / untag |
|
|
104
|
+
| `/tags` | GET | List tags |
|
|
105
|
+
| `/collections` | GET, POST | List / create |
|
|
106
|
+
| `/collections/:id/files` | POST | Add file |
|
|
107
|
+
| `/collections/:id/files/:fid` | DELETE | Remove file |
|
|
108
|
+
| `/projects` | GET, POST | List / create |
|
|
109
|
+
| `/projects/:id/files` | POST | Add file |
|
|
110
|
+
| `/machines` | GET | List machines |
|
|
111
|
+
| `/machines/current` | GET | Current machine |
|
|
112
|
+
| `/sync` | POST | Sync from peers `{ peers: ["http://..."] }` |
|
|
113
|
+
| `/health` | GET | Health check |
|
|
114
|
+
|
|
115
|
+
## Dashboard
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
files-serve # then open http://localhost:19432
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Or in dev: `cd dashboard && bun run dev`
|
|
122
|
+
|
|
123
|
+
## Multi-machine sync
|
|
124
|
+
|
|
125
|
+
Each machine has its own SQLite database at `~/.files/files.db`. To sync file indexes between machines:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
# On machine B, pull from machine A
|
|
129
|
+
files sync http://machine-a.local:19432
|
|
130
|
+
|
|
131
|
+
# Or via API
|
|
132
|
+
curl -X POST http://localhost:19432/sync \
|
|
133
|
+
-H "Content-Type: application/json" \
|
|
134
|
+
-d '{"peers": ["http://machine-a.local:19432"]}'
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
This merges remote file records into your local DB so you can search across all machines.
|
|
138
|
+
|
|
139
|
+
## Storage
|
|
140
|
+
|
|
141
|
+
- **SQLite DB**: `~/.files/files.db` (override with `FILES_DB_PATH`)
|
|
142
|
+
- **Data dir**: `~/.files/` (override with `FILES_DATA_DIR`)
|
|
143
|
+
- **S3 credentials**: stored per source in the DB config column (JSON)
|
|
144
|
+
- **Hashing**: BLAKE3 via `@noble/hashes`
|
|
145
|
+
|
|
146
|
+
## License
|
|
147
|
+
|
|
148
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/*! tailwindcss v4.2.1 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-space-y-reverse:0;--tw-border-style:solid;--tw-font-weight:initial;--tw-tracking:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-red-400:oklch(70.4% .191 22.216);--color-emerald-400:oklch(76.5% .177 163.223);--color-emerald-900:oklch(37.8% .077 168.94);--color-indigo-300:oklch(78.5% .115 274.713);--color-indigo-400:oklch(67.3% .182 276.935);--color-indigo-500:oklch(58.5% .233 277.117);--color-indigo-600:oklch(51.1% .262 276.966);--color-indigo-900:oklch(35.9% .144 278.697);--color-slate-300:oklch(86.9% .022 252.894);--color-slate-400:oklch(70.4% .04 256.788);--color-slate-500:oklch(55.4% .046 257.417);--color-slate-600:oklch(44.6% .043 257.281);--color-slate-700:oklch(37.2% .044 257.287);--color-slate-800:oklch(27.9% .041 260.031);--color-slate-900:oklch(20.8% .042 265.755);--color-white:#fff;--spacing:.25rem;--container-xs:20rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--font-weight-medium:500;--font-weight-semibold:600;--tracking-wide:.025em;--radius-lg:.5rem;--radius-xl:.75rem;--animate-spin:spin 1s linear infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}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;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.sticky{position:sticky}.top-0{top:calc(var(--spacing) * 0)}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-auto{margin-top:auto}.mr-1{margin-right:calc(var(--spacing) * 1)}.mb-1{margin-bottom:calc(var(--spacing) * 1)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.ml-2{margin-left:calc(var(--spacing) * 2)}.flex{display:flex}.table{display:table}.h-2\.5{height:calc(var(--spacing) * 2.5)}.h-3{height:calc(var(--spacing) * 3)}.h-3\.5{height:calc(var(--spacing) * 3.5)}.h-4{height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-8{height:calc(var(--spacing) * 8)}.h-full{height:100%}.h-screen{height:100vh}.w-2\.5{width:calc(var(--spacing) * 2.5)}.w-3{width:calc(var(--spacing) * 3)}.w-3\.5{width:calc(var(--spacing) * 3.5)}.w-4{width:calc(var(--spacing) * 4)}.w-5{width:calc(var(--spacing) * 5)}.w-8{width:calc(var(--spacing) * 8)}.w-20{width:calc(var(--spacing) * 20)}.w-52{width:calc(var(--spacing) * 52)}.w-64{width:calc(var(--spacing) * 64)}.w-96{width:calc(var(--spacing) * 96)}.w-full{width:100%}.max-w-xs{max-width:var(--container-xs)}.min-w-0{min-width:calc(var(--spacing) * 0)}.flex-1{flex:1}.shrink-0{flex-shrink:0}.animate-spin{animation:var(--animate-spin)}.cursor-pointer{cursor:pointer}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-1{gap:calc(var(--spacing) * 1)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-xl{border-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-slate-700{border-color:var(--color-slate-700)}.border-slate-800{border-color:var(--color-slate-800)}.border-slate-800\/50{border-color:#1d293d80}@supports (color:color-mix(in lab,red,red)){.border-slate-800\/50{border-color:color-mix(in oklab,var(--color-slate-800) 50%,transparent)}}.bg-emerald-900\/50{background-color:#004e3b80}@supports (color:color-mix(in lab,red,red)){.bg-emerald-900\/50{background-color:color-mix(in oklab,var(--color-emerald-900) 50%,transparent)}}.bg-indigo-600{background-color:var(--color-indigo-600)}.bg-indigo-900\/20{background-color:#312c8533}@supports (color:color-mix(in lab,red,red)){.bg-indigo-900\/20{background-color:color-mix(in oklab,var(--color-indigo-900) 20%,transparent)}}.bg-indigo-900\/50{background-color:#312c8580}@supports (color:color-mix(in lab,red,red)){.bg-indigo-900\/50{background-color:color-mix(in oklab,var(--color-indigo-900) 50%,transparent)}}.bg-slate-800{background-color:var(--color-slate-800)}.bg-slate-900{background-color:var(--color-slate-900)}.bg-transparent{background-color:#0000}.p-0\.5{padding:calc(var(--spacing) * .5)}.p-1{padding:calc(var(--spacing) * 1)}.p-2{padding:calc(var(--spacing) * 2)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-6{padding:calc(var(--spacing) * 6)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:calc(var(--spacing) * 1)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-12{padding-block:calc(var(--spacing) * 12)}.pb-1{padding-bottom:calc(var(--spacing) * 1)}.text-center{text-align:center}.text-left{text-align:left}.font-mono{font-family:var(--font-mono)}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.whitespace-nowrap{white-space:nowrap}.text-emerald-400{color:var(--color-emerald-400)}.text-indigo-300{color:var(--color-indigo-300)}.text-indigo-400{color:var(--color-indigo-400)}.text-slate-300{color:var(--color-slate-300)}.text-slate-400{color:var(--color-slate-400)}.text-slate-500{color:var(--color-slate-500)}.text-slate-600{color:var(--color-slate-600)}.text-white{color:var(--color-white)}.uppercase{text-transform:uppercase}.opacity-60{opacity:.6}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.outline-none{--tw-outline-style:none;outline-style:none}.placeholder\:text-slate-500::placeholder{color:var(--color-slate-500)}@media(hover:hover){.hover\:bg-indigo-500:hover{background-color:var(--color-indigo-500)}.hover\:bg-slate-800:hover{background-color:var(--color-slate-800)}.hover\:bg-slate-800\/30:hover{background-color:#1d293d4d}@supports (color:color-mix(in lab,red,red)){.hover\:bg-slate-800\/30:hover{background-color:color-mix(in oklab,var(--color-slate-800) 30%,transparent)}}.hover\:text-red-400:hover{color:var(--color-red-400)}.hover\:text-white:hover{color:var(--color-white)}}.focus\:border-indigo-500:focus{border-color:var(--color-indigo-500)}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-50:disabled{opacity:.5}}*{box-sizing:border-box}body{color:#e2e8f0;background:#0f172a;margin:0;font-family:system-ui,-apple-system,sans-serif}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@keyframes spin{to{transform:rotate(360deg)}}
|