qwik 0.1.0__tar.gz

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 (61) hide show
  1. qwik-0.1.0/.github/dependabot.yml +11 -0
  2. qwik-0.1.0/.github/workflows/publish.yml +39 -0
  3. qwik-0.1.0/.github/workflows/test.yml +32 -0
  4. qwik-0.1.0/.gitignore +123 -0
  5. qwik-0.1.0/.pre-commit-config.yaml +20 -0
  6. qwik-0.1.0/LICENSE +21 -0
  7. qwik-0.1.0/PKG-INFO +468 -0
  8. qwik-0.1.0/README.md +438 -0
  9. qwik-0.1.0/docs/arguments.md +245 -0
  10. qwik-0.1.0/pyproject.toml +63 -0
  11. qwik-0.1.0/qwik/__init__.py +3 -0
  12. qwik-0.1.0/qwik/__main__.py +6 -0
  13. qwik-0.1.0/qwik/cli.py +142 -0
  14. qwik-0.1.0/qwik/commands/add.py +110 -0
  15. qwik-0.1.0/qwik/commands/doctor.py +153 -0
  16. qwik-0.1.0/qwik/commands/edit.py +110 -0
  17. qwik-0.1.0/qwik/commands/enable_disable.py +50 -0
  18. qwik-0.1.0/qwik/commands/exporter.py +53 -0
  19. qwik-0.1.0/qwik/commands/importer.py +79 -0
  20. qwik-0.1.0/qwik/commands/init_shell.py +120 -0
  21. qwik-0.1.0/qwik/commands/list.py +32 -0
  22. qwik-0.1.0/qwik/commands/pick.py +76 -0
  23. qwik-0.1.0/qwik/commands/remove.py +36 -0
  24. qwik-0.1.0/qwik/commands/rename.py +52 -0
  25. qwik-0.1.0/qwik/commands/run.py +69 -0
  26. qwik-0.1.0/qwik/commands/search.py +40 -0
  27. qwik-0.1.0/qwik/commands/show.py +29 -0
  28. qwik-0.1.0/qwik/commands/tag.py +57 -0
  29. qwik-0.1.0/qwik/config.py +110 -0
  30. qwik-0.1.0/qwik/core/conflicts.py +186 -0
  31. qwik-0.1.0/qwik/core/models.py +196 -0
  32. qwik-0.1.0/qwik/core/search.py +86 -0
  33. qwik-0.1.0/qwik/core/store.py +154 -0
  34. qwik-0.1.0/qwik/core/substitute.py +158 -0
  35. qwik-0.1.0/qwik/shells/base.py +122 -0
  36. qwik-0.1.0/qwik/shells/bash.py +44 -0
  37. qwik-0.1.0/qwik/shells/cmd.py +51 -0
  38. qwik-0.1.0/qwik/shells/fish.py +43 -0
  39. qwik-0.1.0/qwik/shells/pwsh.py +42 -0
  40. qwik-0.1.0/qwik/shells/zsh.py +40 -0
  41. qwik-0.1.0/qwik/ui/picker.py +188 -0
  42. qwik-0.1.0/qwik/ui/prompts.py +123 -0
  43. qwik-0.1.0/qwik/ui/tables.py +97 -0
  44. qwik-0.1.0/qwik/ui/theme.py +58 -0
  45. qwik-0.1.0/tests/test_callback_coverage.py +69 -0
  46. qwik-0.1.0/tests/test_cli.py +353 -0
  47. qwik-0.1.0/tests/test_conflicts.py +43 -0
  48. qwik-0.1.0/tests/test_coverage_gaps.py +293 -0
  49. qwik-0.1.0/tests/test_coverage_gaps2.py +300 -0
  50. qwik-0.1.0/tests/test_edit.py +124 -0
  51. qwik-0.1.0/tests/test_final_coverage.py +215 -0
  52. qwik-0.1.0/tests/test_final_push.py +98 -0
  53. qwik-0.1.0/tests/test_last_gaps.py +129 -0
  54. qwik-0.1.0/tests/test_main.py +14 -0
  55. qwik-0.1.0/tests/test_models.py +74 -0
  56. qwik-0.1.0/tests/test_shells.py +71 -0
  57. qwik-0.1.0/tests/test_store.py +64 -0
  58. qwik-0.1.0/tests/test_sub_and_shells.py +389 -0
  59. qwik-0.1.0/tests/test_substitute.py +71 -0
  60. qwik-0.1.0/tests/test_ui_and_models.py +157 -0
  61. qwik-0.1.0/tests/test_unit_gaps.py +102 -0
@@ -0,0 +1,11 @@
1
+ # To get started with Dependabot version updates, you'll need to specify which
2
+ # package ecosystems to update and where the package manifests are located.
3
+ # Please see the documentation for all configuration options:
4
+ # https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
5
+
6
+ version: 2
7
+ updates:
8
+ - package-ecosystem: "pip"
9
+ directory: "/"
10
+ schedule:
11
+ interval: "weekly"
@@ -0,0 +1,39 @@
1
+ name: Test, Build & Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+ workflow_dispatch:
7
+
8
+ jobs:
9
+ test-build-publish:
10
+ runs-on: ubuntu-latest
11
+
12
+ steps:
13
+ - name: Checkout repository
14
+ uses: actions/checkout@v4
15
+
16
+ - name: Set up Python
17
+ uses: actions/setup-python@v5
18
+ with:
19
+ python-version: "3.12"
20
+
21
+ - name: Install dependencies
22
+ run: |
23
+ python -m pip install --upgrade pip
24
+ pip install .[dev]
25
+ pip install pytest build twine
26
+
27
+ - name: Run tests
28
+ run: pytest -v
29
+
30
+ - name: Build package
31
+ if: success()
32
+ run: python -m build
33
+
34
+ - name: Publish to PyPI
35
+ if: success()
36
+ env:
37
+ TWINE_USERNAME: __token__
38
+ TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
39
+ run: twine upload dist/*
@@ -0,0 +1,32 @@
1
+ name: Tests
2
+
3
+ on:
4
+ push:
5
+ branches: [master]
6
+ pull_request:
7
+ branches: [master]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ python-version: ["3.12"]
15
+
16
+ steps:
17
+ - name: Checkout repository
18
+ uses: actions/checkout@v4
19
+
20
+ - name: Set up Python ${{ matrix.python-version }}
21
+ uses: actions/setup-python@v5
22
+ with:
23
+ python-version: ${{ matrix.python-version }}
24
+
25
+ - name: Install dependencies
26
+ run: |
27
+ python -m pip install --upgrade pip
28
+ pip install .[dev]
29
+ pip install pytest
30
+
31
+ - name: Run tests
32
+ run: pytest -q -o addopts=""
qwik-0.1.0/.gitignore ADDED
@@ -0,0 +1,123 @@
1
+ # Created by https://www.gitignore.io/api/python
2
+ # Edit at https://www.gitignore.io/?templates=python
3
+
4
+ # internal
5
+ log/*
6
+
7
+ ### Python ###
8
+ # Byte-compiled / optimized / DLL files
9
+ __pycache__/
10
+ *.py[cod]
11
+ *$py.class
12
+
13
+ # C extensions
14
+ *.so
15
+
16
+ # Distribution / packaging
17
+ .Python
18
+ build/
19
+ jars/
20
+ develop-eggs/
21
+ dist/
22
+ downloads/
23
+ eggs/
24
+ .eggs/
25
+ lib/
26
+ lib64/
27
+ parts/
28
+ sdist/
29
+ var/
30
+ wheels/
31
+ pip-wheel-metadata/
32
+ share/python-wheels/
33
+ *.egg-info/
34
+ .installed.cfg
35
+ *.egg
36
+ MANIFEST
37
+
38
+ # PyInstaller
39
+ # Usually these files are written by a python script from a template
40
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
41
+ *.manifest
42
+ *.spec
43
+
44
+ # Installer logs
45
+ pip-log.txt
46
+ pip-delete-this-directory.txt
47
+
48
+ # Unit test / coverage reports
49
+ htmlcov/
50
+ .tox/
51
+ .nox/
52
+ .coverage.*
53
+ .cache
54
+ nosetests.xml
55
+ coverage.xml
56
+ *.cover
57
+ .hypothesis/
58
+ .pytest_cache/
59
+
60
+ # Translations
61
+ *.mo
62
+ *.pot
63
+
64
+ # Sphinx documentation
65
+ docs/_build/
66
+
67
+ # PyBuilder
68
+ target/
69
+
70
+ # Jupyter Notebook
71
+ .ipynb_checkpoints
72
+
73
+ # IPython
74
+ profile_default/
75
+ ipython_config.py
76
+
77
+ # pyenv
78
+ .python-version
79
+
80
+ # pipenv
81
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
82
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
83
+ # having no cross-platform support, pipenv may install dependencies that don’t work, or not
84
+ # install all needed dependencies.
85
+ #Pipfile.lock
86
+
87
+ # celery beat schedule file
88
+ celerybeat-schedule
89
+
90
+ # SageMath parsed files
91
+ *.sage.py
92
+
93
+ # Environments
94
+ .env
95
+ .venv
96
+ env/
97
+ venv/
98
+ ENV/
99
+ env.bak/
100
+ venv.bak/
101
+
102
+ # Spyder project settings
103
+ .spyderproject
104
+ .spyproject
105
+
106
+ # Rope project settings
107
+ .ropeproject
108
+
109
+ # mkdocs documentation
110
+ /site
111
+
112
+ # End of https://www.gitignore.io/api/python
113
+
114
+ build/*
115
+ test/data/demand_forecaster/save_model.model
116
+ condaenv.t1e302om.requirements.txt
117
+
118
+ *.env
119
+ *.aes
120
+
121
+ # local IDE stuffs
122
+ .idea/*
123
+ .coverage
@@ -0,0 +1,20 @@
1
+ repos:
2
+ - repo: https://github.com/pre-commit/pre-commit-hooks
3
+ rev: v4.5.0
4
+ hooks:
5
+ - id: check-merge-conflict
6
+ - id: no-commit-to-branch
7
+ args: [--branch, master]
8
+ - id: trailing-whitespace
9
+ - id: end-of-file-fixer
10
+ - id: check-added-large-files
11
+
12
+ # Ruff for both linting and formatting
13
+ - repo: https://github.com/astral-sh/ruff-pre-commit
14
+ rev: v0.6.8
15
+ hooks:
16
+ - id: ruff
17
+ args: [--fix]
18
+ types: [python]
19
+ - id: ruff-format
20
+ types: [python]
qwik-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ragil Prasetyo
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
qwik-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,468 @@
1
+ Metadata-Version: 2.4
2
+ Name: qwik
3
+ Version: 0.1.0
4
+ Summary: A Friendly CLI Alias Manager
5
+ Author: qwik contributors
6
+ License: MIT
7
+ License-File: LICENSE
8
+ Keywords: alias,cli,productivity,shell
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Environment :: Console
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Topic :: Utilities
17
+ Requires-Python: >=3.12
18
+ Requires-Dist: platformdirs>=4.0.0
19
+ Requires-Dist: prompt-toolkit>=3.0.0
20
+ Requires-Dist: pydantic>=2.0.0
21
+ Requires-Dist: rapidfuzz>=3.0.0
22
+ Requires-Dist: rich>=13.0.0
23
+ Requires-Dist: tomlkit>=0.12.0
24
+ Requires-Dist: typer>=0.12.0
25
+ Provides-Extra: dev
26
+ Requires-Dist: pytest-cov>=5.0.0; extra == 'dev'
27
+ Requires-Dist: pytest>=8.0.0; extra == 'dev'
28
+ Requires-Dist: syrupy>=4.0.0; extra == 'dev'
29
+ Description-Content-Type: text/markdown
30
+
31
+ # qwik — A Friendly CLI Alias Manager
32
+
33
+ Create, manage, and run shell aliases from a single interface. Works cross-platform with bash, zsh, fish, PowerShell, and cmd.
34
+
35
+ **Two ways to run any alias:**
36
+ - **`gs`** — native shell command (after one-time hook install)
37
+ - **`qwik -r gs`** — works anywhere, no setup needed
38
+
39
+ ---
40
+
41
+ ## Table of Contents
42
+
43
+ - [Installation](#installation)
44
+ - [Quick Start](#quick-start)
45
+ - [Core Concepts](#core-concepts)
46
+ - [Commands](#commands)
47
+ - [Alias Templates & Arguments](#alias-templates--arguments)
48
+ - [Shell Integration](#shell-integration)
49
+ - [Conflict Detection](#conflict-detection)
50
+ - [Storage & Backups](#storage--backups)
51
+ - [Environment Variables](#environment-variables)
52
+ - [Development](#development)
53
+
54
+ ---
55
+
56
+ ## Installation
57
+
58
+ ```bash
59
+ pipx install qwik
60
+ ```
61
+
62
+ Or with `uv`:
63
+
64
+ ```bash
65
+ uv tool install qwik
66
+ ```
67
+
68
+ ## Quick Start
69
+
70
+ ```bash
71
+ qwik add gs "git status"
72
+ qwik init zsh --install
73
+ source ~/.zshrc
74
+
75
+ gs # native shell alias
76
+ qwik -r gs # same thing, no hook needed
77
+ ```
78
+
79
+ ## Core Concepts
80
+
81
+ ### Two ways to run
82
+
83
+ | Way | Example | When to use |
84
+ |---|---|---|
85
+ | **Native** | `gs` | Daily use after one-time shell hook setup |
86
+ | **Via qwik** | `qwik -r gs` | Scripts, CI, restricted shells, or pre-setup |
87
+
88
+ Both share the **same store and substitution engine** — behavior is identical.
89
+
90
+ ### How it works
91
+
92
+ 1. You **register** aliases with `qwik add`
93
+ 2. You **install** a one-line shell hook with `qwik init --install`
94
+ 3. Every new shell session **regenerates** shell-native aliases from the store
95
+ 4. You type `gs` just like a normal alias — because it is one
96
+
97
+ ---
98
+
99
+ ## Commands
100
+
101
+ ### `add` — Create alias
102
+
103
+ ```bash
104
+ qwik add gs "git status"
105
+ qwik add gs "git status" --tag git --description "Repo status"
106
+ qwik add gs "git status" --force # overwrite existing
107
+ qwik add # interactive mode
108
+ ```
109
+
110
+ ### `rm` — Delete alias
111
+
112
+ ```bash
113
+ qwik rm gs
114
+ qwik rm gs --yes # skip confirmation
115
+ ```
116
+
117
+ ### `rename` — Rename alias
118
+
119
+ ```bash
120
+ qwik rename gs gstat # preserves stats
121
+ ```
122
+
123
+ ### `edit` — Edit in $EDITOR
124
+
125
+ ```bash
126
+ qwik edit gs
127
+ # Opens TOML snippet in your $EDITOR:
128
+ # command = "git status"
129
+ # tag = ["git"]
130
+ # description = ""
131
+ # enabled = true
132
+ # Save and quit to apply changes.
133
+ ```
134
+
135
+ ### `enable` / `disable` — Toggle without deleting
136
+
137
+ ```bash
138
+ qwik disable gs # hides from shell hook
139
+ qwik enable gs # re-enables
140
+ ```
141
+
142
+ ### `list` — Pretty table
143
+
144
+ ```bash
145
+ qwik list # all aliases
146
+ qwik -l # shortcut
147
+ qwik list --tag git # filter by tag
148
+ qwik list --search stat # filter by query
149
+ ```
150
+
151
+ Output:
152
+
153
+ ```
154
+ Name Command Tag Used Last
155
+ ───── ────────────────────────── ───── ───── ───────────
156
+ gs git status git 42 2 min ago
157
+ gco git checkout {1} git 18 1 hour ago
158
+ k kubectl k8s 7 yesterday
159
+ ```
160
+
161
+ ### `show` — Detailed view
162
+
163
+ ```bash
164
+ qwik show gs # full metadata
165
+ ```
166
+
167
+ ### `search` — Fuzzy search
168
+
169
+ ```bash
170
+ qwik search "git"
171
+ qwik -s "git" # shortcut
172
+ ```
173
+
174
+ ### `pick` — Interactive fuzzy picker
175
+
176
+ ```bash
177
+ qwik # bare invocation
178
+ qwik pick
179
+ ```
180
+
181
+ - Type characters to filter matching aliases live
182
+ - `↑`/`↓` navigate
183
+ - `Enter` runs the selected alias
184
+ - `Ctrl+E` edits it
185
+ - `Ctrl+D` deletes it
186
+ - `Esc` cancels
187
+
188
+ ### `run` — Execute alias
189
+
190
+ ```bash
191
+ qwik run gs
192
+ qwik run gs --short # pass extra args
193
+ qwik -r gs --short # shortcut flag
194
+ ```
195
+
196
+ ### `tag` / `untag`
197
+
198
+ ```bash
199
+ qwik tag gs git
200
+ qwik tag gs work
201
+ qwik untag gs work
202
+ ```
203
+
204
+ ### `export` / `import`
205
+
206
+ ```bash
207
+ qwik export ~/aliases.toml # share / backup
208
+ qwik import ~/aliases.toml # merge
209
+ qwik import ~/aliases.toml --overwrite
210
+ ```
211
+
212
+ ### `doctor` — Health check
213
+
214
+ ```bash
215
+ qwik doctor # shell, hook, store, conflicts
216
+ ```
217
+
218
+ ### `init` — Shell hook
219
+
220
+ ```bash
221
+ qwik init zsh # print hook to stdout
222
+ qwik init zsh --install # append to ~/.zshrc with backup
223
+ ```
224
+
225
+ Supported shells: `bash`, `zsh`, `fish`, `pwsh`.
226
+
227
+ ### Version & Help
228
+
229
+ ```bash
230
+ qwik --version
231
+ qwik -v
232
+ qwik --help
233
+ qwik -h
234
+ ```
235
+
236
+ ---
237
+
238
+ ## Alias Templates & Arguments
239
+
240
+ Aliases can pass arguments through unchanged or interpolate them into the command.
241
+
242
+ ### Append mode (default — no placeholders)
243
+
244
+ Extra args are appended after quoting.
245
+
246
+ ```bash
247
+ qwik add gs "git status"
248
+ gs --short # → git status --short
249
+ ```
250
+
251
+ ### Template mode (placeholders)
252
+
253
+ Use `{…}` markers to substitute arguments into the command.
254
+
255
+ | Placeholder | Meaning |
256
+ |---|---|
257
+ | `{1}`, `{2}`, `{3}`… | Nth positional argument (1-based) |
258
+ | `{@}` | All arguments joined with spaces |
259
+ | `{*}` | All arguments as a single quoted string |
260
+ | `{1:-default}` | Nth positional, falling back to `default` if missing |
261
+
262
+ ---
263
+
264
+ **Single positional:**
265
+
266
+ ```bash
267
+ qwik add gco "git checkout {1}"
268
+ gco main # → git checkout main
269
+ ```
270
+
271
+ **Multiple positionals:**
272
+
273
+ ```bash
274
+ qwik add gcm 'git commit -m "{1}: {2}"'
275
+ gcm feat "add login"
276
+ # → git commit -m "feat: add login"
277
+ ```
278
+
279
+ **Default value:**
280
+
281
+ ```bash
282
+ qwik add gpo "git push origin {1:-main}"
283
+ gpo # → git push origin main
284
+ gpo feature/x # → git push origin feature/x
285
+ ```
286
+
287
+ **All args joined:**
288
+
289
+ ```bash
290
+ qwik add gc-chore 'git commit -m "chore: {@}"'
291
+ gc-chore init version
292
+ # → git commit -m "chore: init version"
293
+ ```
294
+
295
+ **All args as one quoted string:**
296
+
297
+ ```bash
298
+ qwik add note 'echo "Note: {*}"'
299
+ note hello world
300
+ # → echo "Note: 'hello world'"
301
+ ```
302
+
303
+ **Mixed — template + appended extras:**
304
+
305
+ ```bash
306
+ qwik add k "kubectl {1}"
307
+ k get pods -n kube-system
308
+ # → kubectl get pods -n kube-system
309
+ # {1}=get, "pods -n kube-system" appended after template
310
+ ```
311
+
312
+ ---
313
+
314
+ ### Placeholder defaults
315
+
316
+ `{N:-default}` is especially useful for aliases with a sensible fallback:
317
+
318
+ ```bash
319
+ qwik add co "git checkout {1:-main}"
320
+ co feature # → git checkout feature
321
+ co # → git checkout main (default)
322
+ ```
323
+
324
+ ### Validation
325
+
326
+ - `{0}` is rejected at add-time — placeholders are 1-based
327
+ - Missing required args produce a clear error at runtime instead of silently expanding to empty strings
328
+
329
+ ---
330
+
331
+ ## Shell Integration
332
+
333
+ Make aliases available as **real shell commands**.
334
+
335
+ ### One-time setup
336
+
337
+ **bash:**
338
+
339
+ ```bash
340
+ qwik init bash --install
341
+ source ~/.bashrc
342
+ ```
343
+
344
+ **zsh:**
345
+
346
+ ```bash
347
+ qwik init zsh --install
348
+ source ~/.zshrc
349
+ ```
350
+
351
+ **fish:**
352
+
353
+ ```bash
354
+ qwik init fish --install
355
+ source ~/.config/fish/config.fish
356
+ ```
357
+
358
+ **PowerShell:**
359
+
360
+ ```powershell
361
+ qwik init pwsh --install
362
+ ```
363
+
364
+ The `--install` flag:
365
+ - Creates a timestamped backup of your rc file
366
+ - Appends the hook (idempotent — safe to run multiple times)
367
+
368
+ ### Manual setup
369
+
370
+ If you prefer to edit your rc file directly, `qwik init <shell>` prints the hook:
371
+
372
+ ```bash
373
+ eval "$(qwik init zsh)"
374
+ ```
375
+
376
+ ### Per-shell rendering
377
+
378
+ The hook generates native aliases/functions for each shell:
379
+
380
+ | Shell | Append mode | Template mode |
381
+ |---|---|---|
382
+ | bash / zsh | `alias gs='git status'` | `gs() { git checkout "$1" ; }` |
383
+ | fish | `alias gs 'git status'` | `function gs ; … ; end` |
384
+ | PowerShell | `function gs { echo hi @args }` | `function gs { echo "{1}" $args[0] }` |
385
+ | cmd | `doskey gs=git status $*` | (best-effort, no template) |
386
+
387
+ ---
388
+
389
+ ## Conflict Detection
390
+
391
+ Every `add` and `rename` validates the new name:
392
+
393
+ | # | Check | Result |
394
+ |---|---|---|
395
+ | 1 | Already an alias? | Refuse unless `--force` |
396
+ | 2 | Shell builtin? (`cd`, `echo`, `alias`, …) | Refuse unless `--force` |
397
+ | 3 | Binary on `$PATH`? | Warn but allow |
398
+ | 4 | Valid syntax? | Refuse if it contains spaces, slashes, `$`, backticks, semicolons |
399
+
400
+ Example UX:
401
+
402
+ ```bash
403
+ qwik add ls "ls --color=auto"
404
+ ⚠ Warning: "ls" shadows /usr/bin/ls.
405
+ Continue? [y/N]
406
+
407
+ qwik add cd "echo nope"
408
+ ✗ "cd" is a shell builtin. Shadowing it can break your shell.
409
+
410
+ qwik add "my alias" "echo hi"
411
+ ✗ Invalid name "my alias": contains whitespace.
412
+ ```
413
+
414
+ ---
415
+
416
+ ## Storage & Backups
417
+
418
+ - **Linux/macOS:** `$XDG_CONFIG_HOME/qwik/aliases.toml` (usually `~/.config/qwik/aliases.toml`)
419
+ - **Windows:** `%APPDATA%\qwik\aliases.toml`
420
+ - **Backups:** every destructive operation writes to `qwik/backups/aliases-<timestamp>.toml` (last 20 kept)
421
+ - **Atomic writes:** temp file + rename to prevent corruption
422
+ - **Format:** human-readable TOML, safe to edit by hand
423
+
424
+ Example store file:
425
+
426
+ ```toml
427
+ [aliases.gs]
428
+ command = "git status"
429
+ tag = ["git"]
430
+ description = "Quick git status"
431
+ enabled = true
432
+ created_at = "2026-05-10T10:00:00Z"
433
+ updated_at = "2026-05-10T10:00:00Z"
434
+ last_used = "2026-05-10T11:30:00Z"
435
+ run_count = 42
436
+ ```
437
+
438
+ ---
439
+
440
+ ## Environment Variables
441
+
442
+ | Variable | Purpose |
443
+ |---|---|
444
+ | `EDITOR` | Editor for `qwik edit` (default: `vi`) |
445
+ | `QWIK_CONFIG_DIR` | Override default config directory |
446
+ | `QWIK_DEBUG=1` | Enable debug logs to stderr |
447
+ | `NO_COLOR` | Disable colored output (also `--no-color`) |
448
+
449
+ ---
450
+
451
+ ## Development
452
+
453
+ ```bash
454
+ # Install with dev dependencies
455
+ pip install -e ".[dev]"
456
+
457
+ # Run the test suite
458
+ pytest
459
+
460
+ # With coverage report
461
+ pytest --cov=qwik --cov-report=term-missing
462
+ ```
463
+
464
+ ---
465
+
466
+ ## License
467
+
468
+ MIT