wraith-cli 1.1.0__tar.gz → 1.3.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 (41) hide show
  1. wraith_cli-1.3.0/.env.example +13 -0
  2. {wraith_cli-1.1.0 → wraith_cli-1.3.0}/.gitea/workflows/pages.yml +1 -0
  3. {wraith_cli-1.1.0 → wraith_cli-1.3.0}/.gitea/workflows/test.yml +15 -4
  4. {wraith_cli-1.1.0 → wraith_cli-1.3.0}/.gitignore +1 -0
  5. {wraith_cli-1.1.0 → wraith_cli-1.3.0}/.pre-commit-config.yaml +16 -0
  6. wraith_cli-1.3.0/.secrets.baseline +131 -0
  7. {wraith_cli-1.1.0 → wraith_cli-1.3.0}/CHANGELOG.md +4 -0
  8. {wraith_cli-1.1.0 → wraith_cli-1.3.0}/PKG-INFO +65 -38
  9. wraith_cli-1.3.0/README.md +98 -0
  10. wraith_cli-1.3.0/docs/architecture.md +86 -0
  11. {wraith_cli-1.1.0 → wraith_cli-1.3.0}/docs/index.md +1 -1
  12. wraith_cli-1.3.0/docs/reference.md +62 -0
  13. wraith_cli-1.3.0/docs/security.md +42 -0
  14. wraith_cli-1.3.0/docs/usage.md +80 -0
  15. {wraith_cli-1.1.0 → wraith_cli-1.3.0}/mkdocs.yml +2 -0
  16. {wraith_cli-1.1.0 → wraith_cli-1.3.0}/pyproject.toml +7 -3
  17. wraith_cli-1.3.0/src/wraith_cli/main.py +339 -0
  18. wraith_cli-1.3.0/src/wraith_cli/qol.py +47 -0
  19. wraith_cli-1.3.0/src/wraith_cli/repo_make.py +88 -0
  20. wraith_cli-1.3.0/src/wraith_cli/shield.py +187 -0
  21. wraith_cli-1.3.0/tests/test_cli.py +301 -0
  22. wraith_cli-1.3.0/tests/test_qol.py +58 -0
  23. wraith_cli-1.3.0/tests/test_repo_make.py +115 -0
  24. wraith_cli-1.3.0/tests/test_shield.py +236 -0
  25. {wraith_cli-1.1.0 → wraith_cli-1.3.0}/uv.lock +56 -1
  26. wraith_cli-1.1.0/.env.example +0 -17
  27. wraith_cli-1.1.0/README.md +0 -74
  28. wraith_cli-1.1.0/docs/reference.md +0 -18
  29. wraith_cli-1.1.0/docs/usage.md +0 -26
  30. wraith_cli-1.1.0/src/wraith_cli/main.py +0 -89
  31. wraith_cli-1.1.0/tests/test_cli.py +0 -97
  32. {wraith_cli-1.1.0 → wraith_cli-1.3.0}/.cz.yaml +0 -0
  33. {wraith_cli-1.1.0 → wraith_cli-1.3.0}/.gitea/CODEOWNERS.md +0 -0
  34. {wraith_cli-1.1.0 → wraith_cli-1.3.0}/.gitea/PULL_REQUEST_TEMPLATE.md +0 -0
  35. {wraith_cli-1.1.0 → wraith_cli-1.3.0}/.gitea/workflows/release.yml +0 -0
  36. {wraith_cli-1.1.0 → wraith_cli-1.3.0}/CONTRIBUTING.md +0 -0
  37. {wraith_cli-1.1.0 → wraith_cli-1.3.0}/LICENSE +0 -0
  38. {wraith_cli-1.1.0 → wraith_cli-1.3.0}/bin/build.sh +0 -0
  39. {wraith_cli-1.1.0 → wraith_cli-1.3.0}/bin/run_tests.sh +0 -0
  40. {wraith_cli-1.1.0 → wraith_cli-1.3.0}/bin/setup_venv.sh +0 -0
  41. {wraith_cli-1.1.0 → wraith_cli-1.3.0}/src/wraith_cli/__init__.py +0 -0
@@ -0,0 +1,13 @@
1
+ # Environment Variables Example file
2
+ VIKING_TOKEN=your_token_here
3
+ VIKING_ACCOUNT=default
4
+ VIKING_USER=admin
5
+
6
+ WRAITH_COMPOSE_PATH=/home/user/example/docker
7
+
8
+ GITEA_COMPOSE_PATH=/home/user/example/gitea
9
+ GITEA_API_URL="http://your-gitea-instance:3000"
10
+ GITEA_TOKEN="your_personal_access_token"
11
+ GITEA_TEMPLATE_URL="https://gitea.domain.com/user/repo-template.git"
12
+
13
+ SCRUTINY_URL=http://127.0.0.1:8090
@@ -1,5 +1,6 @@
1
1
  name: Deploy Gitea Pages
2
2
  on:
3
+ workflow_dispatch:
3
4
  push:
4
5
  branches:
5
6
  - main
@@ -1,4 +1,4 @@
1
- name: Discourse-Bot CI
1
+ name: Wraith-CLI CI
2
2
 
3
3
  on:
4
4
  push:
@@ -9,18 +9,29 @@ jobs:
9
9
  test-and-verify:
10
10
  runs-on: ghost-runner
11
11
  steps:
12
+
12
13
  - name: Check out code
13
14
  uses: actions/checkout@v4
14
15
  with:
15
16
  fetch-depth: 0
17
+
18
+ - name: Install Wraith-CLI
19
+ run: |
20
+ uv pip install --system --break-system-packages -e .
21
+
16
22
  - name: Run Production Tests
17
23
  run: |
18
24
  chmod +x bin/run_tests.sh
19
25
  ./bin/run_tests.sh --no-venv
20
26
  env:
21
- SOVEREIGN_FORUM_URL: "https://mock.forum"
22
- SOVEREIGN_API_KEY: "mock_key"
23
- SOVEREIGN_USERNAME: "mock_user"
27
+ VIKING_TOKEN: "your_token_here"
28
+ VIKING_ACCOUNT: "default"
29
+ VIKING_USER: "admin"
30
+ WRAITH_COMPOSE_PATH: "/home/user/example/docker"
31
+ GITEA_COMPOSE_PATH: "/home/user/example/gitea"
32
+ GITEA_API_URL: "http://your-gitea-instance:3000"
33
+ GITEA_TOKEN: "your_personal_access_token"
34
+ GITEA_TEMPLATE_URL: "https://gitea.domain.com/user/repo-template.git"
24
35
  PYTHONPATH: .
25
36
 
26
37
  auto-merge:
@@ -165,3 +165,4 @@ cython_debug/
165
165
  # and can be added to the global gitignore or merged into this file. For a more nuclear
166
166
  # option (not recommended) you can uncomment the following to ignore the entire idea folder.
167
167
  #.idea/
168
+ .aider*
@@ -14,6 +14,22 @@ repos:
14
14
  args: ["--fix"]
15
15
  - id: ruff-format
16
16
 
17
+ - repo: local
18
+ hooks:
19
+ - id: ty
20
+ name: ty
21
+ entry: uv run ty check
22
+ language: system
23
+ types: [python]
24
+ pass_filenames: false
25
+
26
+ - repo: https://github.com/Yelp/detect-secrets
27
+ rev: v1.5.0
28
+ hooks:
29
+ - id: detect-secrets
30
+ args: ['--baseline', '.secrets.baseline']
31
+ exclude: package-lock.json
32
+
17
33
  - repo: local
18
34
  hooks:
19
35
  - id: pytest-coverage
@@ -0,0 +1,131 @@
1
+ {
2
+ "version": "1.5.0",
3
+ "plugins_used": [
4
+ {
5
+ "name": "ArtifactoryDetector"
6
+ },
7
+ {
8
+ "name": "AWSKeyDetector"
9
+ },
10
+ {
11
+ "name": "AzureStorageKeyDetector"
12
+ },
13
+ {
14
+ "name": "Base64HighEntropyString",
15
+ "limit": 4.5
16
+ },
17
+ {
18
+ "name": "BasicAuthDetector"
19
+ },
20
+ {
21
+ "name": "CloudantDetector"
22
+ },
23
+ {
24
+ "name": "DiscordBotTokenDetector"
25
+ },
26
+ {
27
+ "name": "GitHubTokenDetector"
28
+ },
29
+ {
30
+ "name": "GitLabTokenDetector"
31
+ },
32
+ {
33
+ "name": "HexHighEntropyString",
34
+ "limit": 3.0
35
+ },
36
+ {
37
+ "name": "IbmCloudIamDetector"
38
+ },
39
+ {
40
+ "name": "IbmCosHmacDetector"
41
+ },
42
+ {
43
+ "name": "IPPublicDetector"
44
+ },
45
+ {
46
+ "name": "JwtTokenDetector"
47
+ },
48
+ {
49
+ "name": "KeywordDetector",
50
+ "keyword_exclude": ""
51
+ },
52
+ {
53
+ "name": "MailchimpDetector"
54
+ },
55
+ {
56
+ "name": "NpmDetector"
57
+ },
58
+ {
59
+ "name": "OpenAIDetector"
60
+ },
61
+ {
62
+ "name": "PrivateKeyDetector"
63
+ },
64
+ {
65
+ "name": "PypiTokenDetector"
66
+ },
67
+ {
68
+ "name": "SendGridDetector"
69
+ },
70
+ {
71
+ "name": "SlackDetector"
72
+ },
73
+ {
74
+ "name": "SoftlayerDetector"
75
+ },
76
+ {
77
+ "name": "SquareOAuthDetector"
78
+ },
79
+ {
80
+ "name": "StripeDetector"
81
+ },
82
+ {
83
+ "name": "TelegramBotTokenDetector"
84
+ },
85
+ {
86
+ "name": "TwilioKeyDetector"
87
+ }
88
+ ],
89
+ "filters_used": [
90
+ {
91
+ "path": "detect_secrets.filters.allowlist.is_line_allowlisted"
92
+ },
93
+ {
94
+ "path": "detect_secrets.filters.common.is_baseline_file",
95
+ "filename": ".secrets.baseline"
96
+ },
97
+ {
98
+ "path": "detect_secrets.filters.common.is_ignored_due_to_verification_policies",
99
+ "min_level": 2
100
+ },
101
+ {
102
+ "path": "detect_secrets.filters.heuristic.is_indirect_reference"
103
+ },
104
+ {
105
+ "path": "detect_secrets.filters.heuristic.is_likely_id_string"
106
+ },
107
+ {
108
+ "path": "detect_secrets.filters.heuristic.is_lock_file"
109
+ },
110
+ {
111
+ "path": "detect_secrets.filters.heuristic.is_not_alphanumeric_string"
112
+ },
113
+ {
114
+ "path": "detect_secrets.filters.heuristic.is_potential_uuid"
115
+ },
116
+ {
117
+ "path": "detect_secrets.filters.heuristic.is_prefixed_with_dollar_sign"
118
+ },
119
+ {
120
+ "path": "detect_secrets.filters.heuristic.is_sequential_string"
121
+ },
122
+ {
123
+ "path": "detect_secrets.filters.heuristic.is_swagger_file"
124
+ },
125
+ {
126
+ "path": "detect_secrets.filters.heuristic.is_templated_secret"
127
+ }
128
+ ],
129
+ "results": {},
130
+ "generated_at": "2026-04-02T05:45:06Z"
131
+ }
@@ -1,3 +1,7 @@
1
+ ## v1.3.0 (2026-04-04)
2
+
3
+ ## v1.2.0 (2026-04-02)
4
+
1
5
  ## v1.1.0 (2026-03-31)
2
6
 
3
7
  ## v0.15.0 (2026-03-31)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wraith-cli
3
- Version: 1.1.0
3
+ Version: 1.3.0
4
4
  Summary: Sovereign Command Centre for a Ghost Stack
5
5
  Project-URL: Homepage, https://git.thomaspeoples.com/thomaspeoples/wraith-cli
6
6
  Project-URL: Documentation, https://www.thomaspeoples.com/gitea-repos/wraith-cli/
@@ -38,6 +38,7 @@ Requires-Dist: rich>=13.0.0
38
38
  Requires-Dist: typer>=0.9.0
39
39
  Provides-Extra: dev
40
40
  Requires-Dist: commitizen; extra == 'dev'
41
+ Requires-Dist: detect-secrets; extra == 'dev'
41
42
  Requires-Dist: genbadge[coverage]>=1.1.1; extra == 'dev'
42
43
  Requires-Dist: mkdocs-material<=10.0; extra == 'dev'
43
44
  Requires-Dist: mkdocs<=2.0; extra == 'dev'
@@ -46,79 +47,105 @@ Requires-Dist: pymdown-extensions>=10.7.0; extra == 'dev'
46
47
  Requires-Dist: pytest; extra == 'dev'
47
48
  Requires-Dist: pytest-cov; extra == 'dev'
48
49
  Requires-Dist: ruff; extra == 'dev'
50
+ Requires-Dist: ty; extra == 'dev'
51
+ Requires-Dist: types-requests; extra == 'dev'
49
52
  Description-Content-Type: text/markdown
50
53
 
51
54
  [![Documentation](https://img.shields.io/badge/docs-live-brightgreen)](https://www.thomaspeoples.com/gitea-repos/wraith-cli/)
52
- ![PyPI - Version](https://img.shields.io/pypi/v/wraith_cli)
53
- ![PyPI - License](https://img.shields.io/pypi/l/wraith_cli)
54
- ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/wraith_cli)
55
+ ![PyPI - Version](https://img.shields.io/pypi/v/wraith-cli)
56
+ ![PyPI - License](https://img.shields.io/pypi/l/wraith-cli)
57
+ ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/wraith-cli)
55
58
 
56
59
 
57
60
  # 👻 Wraith-CLI
58
61
  ### *Sovereign Orchestration for the Ghost Stack*
59
62
 
60
- **Wraith-CLI** is the nervous system of the Ghost Stack. It bridges the gap between high-level containers and bare-metal reality.
63
+ **Wraith-CLI** is the nervous system of the Ghost Stack. It bridges the gap between
64
+ high-level container orchestration and bare-metal reality, providing the "Ghost Factory"
65
+ for instant project scaffolding.
61
66
 
62
67
  ---
63
68
 
64
- ## 🚀 Installation
69
+ ## 🏗️ The Ghost Factory (New)
65
70
 
66
- **Wraith-CLI** can be installed via `uv` (recommended) or `pip`:
71
+ The `spawn` command allows you to go from **Idea to Code** in under 5 seconds by
72
+ bleaching a template and provisioning a private Gitea repository automatically.
67
73
 
68
74
  ```bash
69
- # Recommended for CLI tools
70
- uv tool install wraith-cli
71
-
72
- # Standard pip
73
- pip install wraith-cli
75
+ wraith spawn my-new-api
74
76
  ```
75
77
 
76
- > **Note:** Ensure ~/.local/bin is in your $PATH.
78
+ 1. **🧬 Clones** your `GHOST_TEMPLATE_URL`.
79
+ 2. **🧹 Bleaches** all previous git history.
80
+ 3. **🌐 Provisions** a new private repo via the Gitea API.
81
+ 4. **🚀 Pushes** the clean stack to your Sovereign remote.
77
82
 
78
83
  ---
79
84
 
80
85
  ## 🛠️ Operational Manual
81
86
 
82
- | Command | Description |
83
- | :--- | :--- |
84
- | wraith ps | Shows all Docker processes in a neat table |
85
- | wraith status | Heartbeat check for OpenViking (Port 1933). |
86
- | wraith runner-reset | Wipes and re-registers the Gitea Action Runner. |
87
- | wraith --help | View the full manifest of available commands. |
87
+ | Command | Feature | Status |
88
+ |--------------------------|------------------------|---------------------------------------------|
89
+ | `wraith spawn <name>` | **The Ghost Factory** | 🏗️ Scaffolds new repos via Gitea API. |
90
+ | `wraith update` | **Global Update** | 🟢 PyPI-linked & `uv` powered. |
91
+ | `wraith ps` | **Rich Observability** | 🟢 Sovereign Dark styling for Docker. |
92
+ | `wraith tail <svc>` | **Flexible Logging** | 🟢 Supports `--path` & Env Vars. |
93
+ | `wraith status` | **Heartbeat** | 🟢 Monitor OpenViking (Port 1933). |
94
+ | `wraith runner-reset` | **Runner Defence** | 🟢 CI/CD maintenance & registration wipe. |
95
+ | `wraith --version` | **Self-Identity** | 🟢 Eager callback for versioning. |
88
96
 
89
97
  ---
90
98
 
91
- ## 🏗️ Developer Workspace
99
+ ## 🚀 Installation & Updates
92
100
 
93
- We use uv for hermetic environment management.
101
+ **Wraith-CLI** is managed via `uv` for hermetic stability.
94
102
 
95
103
  ```bash
96
- ### 1. Initialise the Environment
97
- uv sync --all-extras
98
- uv run pre-commit install
99
-
100
- ### 2. The Quality Gate
101
- uv run pytest
104
+ # Initial Installation
105
+ uv tool install wraith-cli
102
106
 
103
- ### 3. Sovereign Deployment
104
- chmod +x bin/build.sh
105
- ./bin/build.sh
107
+ # Sovereign Update
108
+ wraith update
106
109
  ```
107
110
 
108
111
  ---
109
112
 
110
113
  ## 🔐 Environment Configuration
111
114
 
112
- Defined in `~/.bashrc` or `.env.private`:
115
+ Defined in your `.env` or system environment. **HTTPS is required** for automated
116
+ Gitea provisioning.
113
117
 
114
- | Variable | Purpose | Default |
115
- | :--- | :--- | :--- |
116
- | VIKING_BASE_URL | The API endpoint for the heartbeat check. | http://127.0.0.1:1933/api/v1 |
117
- | GITEA_COMPOSE_PATH | Path to your Gitea Docker Compose directory. | Required for runner-reset |
118
+ | Variable | Purpose | Required For |
119
+ |------------------------|--------------------------------------------------|-----------------|
120
+ | `GITEA_API_URL` | Base URL (e.g., `https://git.domain.com`) | `spawn` |
121
+ | `GITEA_TOKEN` | Personal Access Token (PAT) | `spawn` |
122
+ | `GITEA_TEMPLATE_URL` | HTTPS URL of your base `ghost-template` | `spawn` |
123
+ | `GITEA_COMPOSE_PATH` | Path to Gitea Docker directory | `runner-reset` |
124
+ | `VIKING_BASE_URL` | API endpoint for heartbeat checks | `status` |
125
+ | `WRAITH_COMPOSE_PATH` | Default path for stack logs/ps | `tail`, `ps` |
126
+
127
+ ---
128
+
129
+ ## 🧪 Developer Quality Gate
130
+
131
+ We use `uv` for hermetic environment management and maintain a strict **>80% coverage**
132
+ requirement.
133
+
134
+ ```bash
135
+ # Initialise the Environment
136
+ uv sync --all-extras
137
+ uv run pre-commit install
138
+
139
+ # The Quality Gate
140
+ uv run pytest --cov=src
141
+ ```
118
142
 
119
143
  ---
120
144
 
121
145
  ## 📜 Sovereign Principles
122
- 1. **Distributed Sovereignty:** Available on PyPI for the world, but optimised for local-first, private-registry mirrors
123
- 2. **Atomic Execution:** Use uv run to ensure consistency.
124
- 3. **Hardware First:** Prioritise bare-metal health and container stability.
146
+
147
+ 1. **Distributed Sovereignty:** Available on PyPI for the world, but optimised for
148
+ local-first, private-registry mirrors.
149
+ 2. **Atomic Execution:** Use `uv run` to ensure consistency across the stack.
150
+ 3. **Hardware First:** Prioritise bare-metal health and container stability over
151
+ abstraction.
@@ -0,0 +1,98 @@
1
+ [![Documentation](https://img.shields.io/badge/docs-live-brightgreen)](https://www.thomaspeoples.com/gitea-repos/wraith-cli/)
2
+ ![PyPI - Version](https://img.shields.io/pypi/v/wraith-cli)
3
+ ![PyPI - License](https://img.shields.io/pypi/l/wraith-cli)
4
+ ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/wraith-cli)
5
+
6
+
7
+ # 👻 Wraith-CLI
8
+ ### *Sovereign Orchestration for the Ghost Stack*
9
+
10
+ **Wraith-CLI** is the nervous system of the Ghost Stack. It bridges the gap between
11
+ high-level container orchestration and bare-metal reality, providing the "Ghost Factory"
12
+ for instant project scaffolding.
13
+
14
+ ---
15
+
16
+ ## 🏗️ The Ghost Factory (New)
17
+
18
+ The `spawn` command allows you to go from **Idea to Code** in under 5 seconds by
19
+ bleaching a template and provisioning a private Gitea repository automatically.
20
+
21
+ ```bash
22
+ wraith spawn my-new-api
23
+ ```
24
+
25
+ 1. **🧬 Clones** your `GHOST_TEMPLATE_URL`.
26
+ 2. **🧹 Bleaches** all previous git history.
27
+ 3. **🌐 Provisions** a new private repo via the Gitea API.
28
+ 4. **🚀 Pushes** the clean stack to your Sovereign remote.
29
+
30
+ ---
31
+
32
+ ## 🛠️ Operational Manual
33
+
34
+ | Command | Feature | Status |
35
+ |--------------------------|------------------------|---------------------------------------------|
36
+ | `wraith spawn <name>` | **The Ghost Factory** | 🏗️ Scaffolds new repos via Gitea API. |
37
+ | `wraith update` | **Global Update** | 🟢 PyPI-linked & `uv` powered. |
38
+ | `wraith ps` | **Rich Observability** | 🟢 Sovereign Dark styling for Docker. |
39
+ | `wraith tail <svc>` | **Flexible Logging** | 🟢 Supports `--path` & Env Vars. |
40
+ | `wraith status` | **Heartbeat** | 🟢 Monitor OpenViking (Port 1933). |
41
+ | `wraith runner-reset` | **Runner Defence** | 🟢 CI/CD maintenance & registration wipe. |
42
+ | `wraith --version` | **Self-Identity** | 🟢 Eager callback for versioning. |
43
+
44
+ ---
45
+
46
+ ## 🚀 Installation & Updates
47
+
48
+ **Wraith-CLI** is managed via `uv` for hermetic stability.
49
+
50
+ ```bash
51
+ # Initial Installation
52
+ uv tool install wraith-cli
53
+
54
+ # Sovereign Update
55
+ wraith update
56
+ ```
57
+
58
+ ---
59
+
60
+ ## 🔐 Environment Configuration
61
+
62
+ Defined in your `.env` or system environment. **HTTPS is required** for automated
63
+ Gitea provisioning.
64
+
65
+ | Variable | Purpose | Required For |
66
+ |------------------------|--------------------------------------------------|-----------------|
67
+ | `GITEA_API_URL` | Base URL (e.g., `https://git.domain.com`) | `spawn` |
68
+ | `GITEA_TOKEN` | Personal Access Token (PAT) | `spawn` |
69
+ | `GITEA_TEMPLATE_URL` | HTTPS URL of your base `ghost-template` | `spawn` |
70
+ | `GITEA_COMPOSE_PATH` | Path to Gitea Docker directory | `runner-reset` |
71
+ | `VIKING_BASE_URL` | API endpoint for heartbeat checks | `status` |
72
+ | `WRAITH_COMPOSE_PATH` | Default path for stack logs/ps | `tail`, `ps` |
73
+
74
+ ---
75
+
76
+ ## 🧪 Developer Quality Gate
77
+
78
+ We use `uv` for hermetic environment management and maintain a strict **>80% coverage**
79
+ requirement.
80
+
81
+ ```bash
82
+ # Initialise the Environment
83
+ uv sync --all-extras
84
+ uv run pre-commit install
85
+
86
+ # The Quality Gate
87
+ uv run pytest --cov=src
88
+ ```
89
+
90
+ ---
91
+
92
+ ## 📜 Sovereign Principles
93
+
94
+ 1. **Distributed Sovereignty:** Available on PyPI for the world, but optimised for
95
+ local-first, private-registry mirrors.
96
+ 2. **Atomic Execution:** Use `uv run` to ensure consistency across the stack.
97
+ 3. **Hardware First:** Prioritise bare-metal health and container stability over
98
+ abstraction.
@@ -0,0 +1,86 @@
1
+ # 🏛️ Architecture & Decision Records
2
+
3
+ ---
4
+
5
+ ## 1. High-Level Design
6
+
7
+ Wraith follows a **Functional Core, Imperative Shell** pattern.
8
+
9
+ - **The Shell (`main.py`):** Handles the "dirty" work of CLI parsing, environment
10
+ loading, and printing to `stdout`.
11
+ - **The Core (`repo_make.py`, `qol.py`):** Pure logic functions that perform the actual
12
+ heavy lifting — API calls, Git operations, Docker formatting.
13
+
14
+ This separation ensures the core remains independently testable without invoking the
15
+ CLI layer, and that the shell stays thin enough to reason about at a glance.
16
+
17
+ ---
18
+
19
+ ## 2. ADR 001 — Tooling Selection
20
+
21
+ > **Status:** Accepted. These dependencies are intentional and should not be replaced
22
+ > without a corresponding ADR entry.
23
+
24
+ | Decision | Choice | Rationale |
25
+ |--------------------|-----------|------------------------------------------------------------------------------------------------|
26
+ | **CLI Framework** | `typer` | Native type-hint support. Built on Click but with significantly less boilerplate. |
27
+ | **Package Manager**| `uv` | Rust-based, hermetic, and fast. Replaces `pip`, `poetry`, and `venv` with a single binary. |
28
+ | **Terminal Output**| `rich` | First-class Markdown and table rendering. Essential for the Sovereign Dark aesthetic. |
29
+ | **Testing** | `pytest` | Industry standard. Excellent `subprocess` mocking support for hermetic offline tests. |
30
+
31
+ ---
32
+
33
+ ## 3. ADR 002 — Sovereign Security & Authentication
34
+
35
+ > **Status:** Accepted. Do not introduce persistent credential storage without
36
+ > revisiting this decision.
37
+
38
+ **Decision:** Environment-only credential configuration via `.env` or shell exports.
39
+
40
+ **Rejected alternative:** Storing Gitea credentials in a local SQLite database or
41
+ config file (e.g., `~/.wraith/config`).
42
+
43
+ **Rationale:** Keeps Wraith stateless between sessions. If a machine is compromised,
44
+ credentials are not sitting in a plaintext config file — they vanish when the shell
45
+ session ends. The attack surface is the user's environment, not Wraith's own storage.
46
+
47
+ ---
48
+
49
+ ## 4. The Quality Gate
50
+
51
+ We treat **type hints** as a functional requirement, not a suggestion. Because `typer`
52
+ relies on Python 3.12+ annotations to construct its CLI interface, a type error is a
53
+ runtime bug — not a style violation.
54
+
55
+ ### Static Analysis — Ruff
56
+
57
+ All code is linted and formatted via `ruff` in opinionated mode, enforced at commit
58
+ time via `pre-commit`. This covers style, import ordering, and security anti-patterns
59
+ in a single pass.
60
+
61
+ ### Type Integrity
62
+
63
+ Type annotations are enforced strictly. Functions accepting a `Path` must not receive
64
+ a `str`; optional environment variables must be handled as `Optional[str]`, not assumed
65
+ present.
66
+
67
+ ### Test Coverage — pytest
68
+
69
+ We maintain a strict **>80% coverage gate**, with all network and `subprocess` calls
70
+ mocked for offline, hermetic execution.
71
+
72
+ ```bash
73
+ # The Lead Engineer's Pre-Flight Check
74
+ uv run ruff check . # Linting & security anti-patterns
75
+ uv run ruff format . # Consistency
76
+ uv run pytest --cov=src # Logical integrity & coverage gate
77
+ ```
78
+
79
+ ---
80
+
81
+ ## 5. Future Roadmap
82
+
83
+ | Path | Codename | Description |
84
+ |------|---------------------|-----------------------------------------------------------------------------|
85
+ | 3 | **Ghost Watcher** | Background daemon to monitor stack health via `status` and auto-restart failed runners. |
86
+ | 4 | **Sovereign UI** | `textual`-based TUI for real-time stack dashboarding. |
@@ -1,7 +1,7 @@
1
1
  # Wraith CLI
2
2
 
3
3
  ![Coverage](coverage.svg)
4
- ![Version](https://img.shields.io/badge/version-1.0.1-blue)
4
+ ![PyPI - Version](https://img.shields.io/pypi/v/wraith_cli)
5
5
 
6
6
  ---
7
7
 
@@ -0,0 +1,62 @@
1
+ # 🔩 Technical Reference
2
+
3
+ ---
4
+
5
+ ## 🏗️ Architecture
6
+
7
+ **Wraith** is engineered on **Python 3.12+**. Like its namesake, it is designed for silent, effortless power. It leverages a modern Sovereign stack:
8
+
9
+ | Concern | Library | Role |
10
+ |--------------------|--------------|-------------------------------------------------------|
11
+ | **Orchestration** | `typer` | CLI interface and command routing. |
12
+ | **Visuals** | `rich` | High-contrast terminal rendering and Markdown support.|
13
+ | **Package Mgmt** | `uv` | Lightning-fast, hermetic dependency locking. |
14
+ | **Networking** | `requests` | Gitea API interactions. |
15
+ | **System** | `subprocess` | Low-level Docker and Git execution. |
16
+
17
+ ---
18
+
19
+ ## 🧬 Modular Logic
20
+
21
+ The codebase is partitioned to ensure high testability and separation of concerns:
22
+
23
+ | Module | Responsibility |
24
+ |---------------|-------------------------------------------------------------------------|
25
+ | `main.py` | **The Switchboard.** CLI routing, UI splash, and env var loading. |
26
+ | `repo_make.py`| **The Factory.** Gitea API calls and Git "Bleach & Push" logic. |
27
+ | `qol.py` | **Quality of Life.** Docker table formatting and version checks. |
28
+
29
+ ### 🔐 Authentication Logic
30
+
31
+ Wraith uses **HTTPS Token Injection** to bypass interactive password prompts. When a command requires Gitea access, the logic identifies the protocol and injects credentials as follows:
32
+
33
+ ```
34
+ https://oauth2:{GITEA_TOKEN}@git.domain.com/repo.git
35
+ ```
36
+
37
+ ---
38
+
39
+ ## 🚨 Error Codes & Troubleshooting
40
+
41
+ | Code | Meaning | Resolution |
42
+ |----------|--------------------------|----------------------------------------------------------------|
43
+ | `0` | Success | Command executed perfectly. |
44
+ | `1` | Configuration Error | Missing `.env` variables or 404 API endpoint. |
45
+ | `128` | Git / Auth Error | Token invalid, or repository already exists on remote. |
46
+ | `Abort` | User Cancelled | Triggered during `runner-reset` if requirements aren't met. |
47
+
48
+ ---
49
+
50
+ ## 🧪 Test Suite & Quality Gate
51
+
52
+ We maintain a strict **Sovereign Quality Gate**. No code enters the main branch without passing the full suite.
53
+
54
+ - **Coverage Target:** >80%, strictly enforced via `pytest-cov`.
55
+ - **Engine:** `pytest` + `coverage.py`.
56
+ - **Mocking:** All network and `subprocess` calls must be mocked under `tests/` to
57
+ permit offline, hermetic testing.
58
+
59
+ ```bash
60
+ # Run the Gate locally
61
+ uv run pytest --cov=src --cov-report=term-missing
62
+ ```