reware-lighthouse 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.
- reware_lighthouse-0.1.0/CHANGELOG.md +13 -0
- reware_lighthouse-0.1.0/LICENSE +13 -0
- reware_lighthouse-0.1.0/PKG-INFO +152 -0
- reware_lighthouse-0.1.0/README.md +121 -0
- reware_lighthouse-0.1.0/pyproject.toml +64 -0
- reware_lighthouse-0.1.0/src/lighthouse_cli/__init__.py +9 -0
- reware_lighthouse-0.1.0/src/lighthouse_cli/__main__.py +4 -0
- reware_lighthouse-0.1.0/src/lighthouse_cli/api.py +39 -0
- reware_lighthouse-0.1.0/src/lighthouse_cli/cli.py +100 -0
- reware_lighthouse-0.1.0/src/lighthouse_cli/commands/__init__.py +1 -0
- reware_lighthouse-0.1.0/src/lighthouse_cli/commands/deinit.py +57 -0
- reware_lighthouse-0.1.0/src/lighthouse_cli/commands/init.py +137 -0
- reware_lighthouse-0.1.0/src/lighthouse_cli/commands/login.py +99 -0
- reware_lighthouse-0.1.0/src/lighthouse_cli/commands/logout.py +24 -0
- reware_lighthouse-0.1.0/src/lighthouse_cli/commands/scan.py +229 -0
- reware_lighthouse-0.1.0/src/lighthouse_cli/commands/status.py +119 -0
- reware_lighthouse-0.1.0/src/lighthouse_cli/config.py +163 -0
- reware_lighthouse-0.1.0/src/lighthouse_cli/git_remote.py +67 -0
- reware_lighthouse-0.1.0/src/lighthouse_cli/hook.py +249 -0
- reware_lighthouse-0.1.0/src/lighthouse_cli/http.py +144 -0
- reware_lighthouse-0.1.0/src/lighthouse_cli/identity.py +22 -0
- reware_lighthouse-0.1.0/src/lighthouse_cli/link.py +77 -0
- reware_lighthouse-0.1.0/src/lighthouse_cli/mcp.py +126 -0
- reware_lighthouse-0.1.0/src/lighthouse_cli/parsing.py +14 -0
- reware_lighthouse-0.1.0/src/lighthouse_cli/resolution.py +100 -0
- reware_lighthouse-0.1.0/src/lighthouse_cli/setup.py +704 -0
- reware_lighthouse-0.1.0/src/lighthouse_cli/skill.py +53 -0
- reware_lighthouse-0.1.0/src/lighthouse_cli/ui.py +180 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.0 (2026-10-06)
|
|
4
|
+
|
|
5
|
+
First public release of `reware-lighthouse`.
|
|
6
|
+
|
|
7
|
+
- One `reware-lighthouse` command: `login`, `logout`, `init`, `deinit`, `status`, `scan`, `mcp`.
|
|
8
|
+
- Production endpoint by default; key verified before it is saved; noninteractive login.
|
|
9
|
+
- `init` installs an explicit-only `lighthouse-enhance` skill for Claude Code and Codex, an MCP
|
|
10
|
+
config, and a pre-commit scan hook. `deinit` removes only unchanged owned content.
|
|
11
|
+
- Branch-aware enhancement (explicit branch, attached branch, then default) with visible warnings.
|
|
12
|
+
- Minimum-version upgrade guidance (`uv tool upgrade` / `pipx upgrade`).
|
|
13
|
+
- Runs on macOS, Linux and Windows (the hook runs through Git for Windows).
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Copyright (c) 2026 RewareLabs. All rights reserved.
|
|
2
|
+
|
|
3
|
+
You may install and run this software, unmodified, to use the Lighthouse service
|
|
4
|
+
(https://lighthouse.rewarelabs.com).
|
|
5
|
+
|
|
6
|
+
You may not copy, modify, merge, publish, distribute, sublicense or sell it, or
|
|
7
|
+
reverse engineer it, except as this notice allows or applicable law permits.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
|
10
|
+
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
|
11
|
+
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL REWARELABS BE LIABLE FOR
|
|
12
|
+
ANY CLAIM, DAMAGES OR OTHER LIABILITY ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
13
|
+
SOFTWARE OR ITS USE.
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: reware-lighthouse
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Lighthouse developer CLI — link a repo to a project, enhance prompts, and scan commits
|
|
5
|
+
Project-URL: Homepage, https://lighthouse.rewarelabs.com
|
|
6
|
+
Author: RewareLabs
|
|
7
|
+
License-Expression: LicenseRef-Proprietary
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Keywords: ai-agents,claude-code,code-scanning,codex,mcp,pre-commit,security
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Environment :: Console
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Operating System :: MacOS
|
|
14
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
15
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
20
|
+
Classifier: Topic :: Security
|
|
21
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
22
|
+
Requires-Python: >=3.11
|
|
23
|
+
Requires-Dist: httpx<1,>=0.28
|
|
24
|
+
Requires-Dist: mcp<3,>=2.0.0
|
|
25
|
+
Provides-Extra: dev
|
|
26
|
+
Requires-Dist: pytest-asyncio<2,>=0.25; extra == 'dev'
|
|
27
|
+
Requires-Dist: pytest<10,>=8.3; extra == 'dev'
|
|
28
|
+
Requires-Dist: respx<1,>=0.22; extra == 'dev'
|
|
29
|
+
Requires-Dist: ruff<1,>=0.12; extra == 'dev'
|
|
30
|
+
Description-Content-Type: text/markdown
|
|
31
|
+
|
|
32
|
+
# reware-lighthouse
|
|
33
|
+
|
|
34
|
+
`reware-lighthouse` connects your Git repository to [Lighthouse](https://lighthouse.rewarelabs.com), so your coding agent gets security guidance for your codebase and every commit is scanned before it lands.
|
|
35
|
+
|
|
36
|
+
It works with Claude Code and Codex on macOS, Linux, and Windows, and needs Python 3.11 or newer. On Windows, the pre-commit hook runs through [Git for Windows](https://gitforwindows.org).
|
|
37
|
+
|
|
38
|
+
## Quickstart
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
$ uv tool install reware-lighthouse # or: pipx install reware-lighthouse
|
|
42
|
+
$ reware-lighthouse login # paste the API key from your dashboard
|
|
43
|
+
$ cd your-repo
|
|
44
|
+
$ reware-lighthouse init
|
|
45
|
+
$ reware-lighthouse status
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Restart your coding agent afterward so it picks up the new skill and MCP server.
|
|
49
|
+
|
|
50
|
+
What just happened?
|
|
51
|
+
|
|
52
|
+
1. `login` verified your API key and saved it to `~/.config/lighthouse/config.env`.
|
|
53
|
+
2. `init` linked the repository to its Lighthouse project, installed a pre-commit hook, and added the agent skill.
|
|
54
|
+
3. `status` checked that your account, project link, and tooling all work.
|
|
55
|
+
|
|
56
|
+
You'll need an API key first. Create one on the Lighthouse dashboard. It's shown once, so copy it right away.
|
|
57
|
+
|
|
58
|
+
## Enhance a coding request
|
|
59
|
+
|
|
60
|
+
Enhancement adds your repository's security rules to a request before your agent starts coding. It only runs when you ask for it, so ordinary requests are never changed.
|
|
61
|
+
|
|
62
|
+
In Claude Code:
|
|
63
|
+
|
|
64
|
+
```text
|
|
65
|
+
/lighthouse-enhance add a password reset endpoint
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
In Codex, invoke the `lighthouse-enhance` skill with the same request.
|
|
69
|
+
|
|
70
|
+
Your agent tells you which branch's rules it used, plus any warnings, such as a branch that has no repository-specific rules yet. If enhancement fails, the agent stops and asks before continuing without it. Every enhancement appears in your dashboard history.
|
|
71
|
+
|
|
72
|
+
To pick a branch, start the request with `--branch`:
|
|
73
|
+
|
|
74
|
+
```text
|
|
75
|
+
/lighthouse-enhance --branch release add a password reset endpoint
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Without the flag, Lighthouse uses the branch attached to your checkout, then the project's default branch.
|
|
79
|
+
|
|
80
|
+
## Scan commits
|
|
81
|
+
|
|
82
|
+
The pre-commit hook runs `reware-lighthouse scan` on your staged changes. Whether a finding blocks the commit depends on the blocking policy saved for your project.
|
|
83
|
+
|
|
84
|
+
If the API is unreachable or the scan times out, the commit goes through. To change the timeout, set `LIGHTHOUSE_SCAN_TIMEOUT` to a number of seconds.
|
|
85
|
+
|
|
86
|
+
## What `init` creates
|
|
87
|
+
|
|
88
|
+
| Path | Purpose |
|
|
89
|
+
| --- | --- |
|
|
90
|
+
| `~/.config/lighthouse/config.env` (mode `0600`) | Your API key, written by `login`. Never inside a repository. |
|
|
91
|
+
| `.lighthouse/project.toml` | The link to your project (`owner/name`). It holds no secret, so it's safe to commit. |
|
|
92
|
+
| `.git/hooks/pre-commit` | A marked block that runs the scan. If a hook already exists, the block is appended. |
|
|
93
|
+
| `.mcp.json`, `.codex/config.toml` | The MCP server entry that runs `reware-lighthouse mcp`. |
|
|
94
|
+
| `.claude/skills/lighthouse-enhance/`, `.agents/skills/lighthouse-enhance/` | The enhance skill, set to run only when you invoke it. |
|
|
95
|
+
|
|
96
|
+
Use `--agent`, `--no-hook`, or `--no-mcp` to set up less. If a step can't finish, `init` reports which items were created, which were already in place, and which need you. Rerunning it is safe.
|
|
97
|
+
|
|
98
|
+
Note that `init` never edits shared hook setups. If Git uses a shared or global hooks directory (`core.hooksPath` pointing outside the repository), or you use the pre-commit framework, add `reware-lighthouse scan` to that hook yourself. Edits you make to files `init` created are preserved.
|
|
99
|
+
|
|
100
|
+
## Commands
|
|
101
|
+
|
|
102
|
+
| Command | What it does |
|
|
103
|
+
| --- | --- |
|
|
104
|
+
| `login` | Saves and verifies your API key. Accepts `--api-key`, `--api-base`, and `--yes` to skip prompts. |
|
|
105
|
+
| `logout` | Removes the saved key. A key set in the environment stays active. |
|
|
106
|
+
| `init` | Links the repository and sets up the hook, MCP config, and skill. |
|
|
107
|
+
| `deinit` | Removes what `init` created here, as long as you haven't edited it. Your key and scan reports stay. |
|
|
108
|
+
| `status` | Checks your account, project link, and tooling. Exits nonzero if something's wrong. |
|
|
109
|
+
| `scan` | Scans staged changes. Accepts `--project`, `--repo`, and `--branch`. The hook runs it for you. |
|
|
110
|
+
| `mcp` | Runs the MCP server over stdio. Your agent starts it, so you rarely run it by hand. |
|
|
111
|
+
|
|
112
|
+
Run any command with `--help` for an example.
|
|
113
|
+
|
|
114
|
+
## Environment variables
|
|
115
|
+
|
|
116
|
+
| Variable | Meaning |
|
|
117
|
+
| --- | --- |
|
|
118
|
+
| `LIGHTHOUSE_API_KEY` | Your API key. It works without `login`, and `logout` doesn't remove it. |
|
|
119
|
+
| `LIGHTHOUSE_API_BASE_URL` | Use a different Lighthouse API endpoint. |
|
|
120
|
+
| `LIGHTHOUSE_PROJECT` | Use this project instead of the link file or Git remote. |
|
|
121
|
+
| `LIGHTHOUSE_SCAN_TIMEOUT` | Scan timeout in seconds. |
|
|
122
|
+
|
|
123
|
+
## What leaves your machine
|
|
124
|
+
|
|
125
|
+
- **Enhancement** sends the request you give the skill, plus the repository and branch. Lighthouse stores the original and enhanced prompts and shows them in your dashboard history.
|
|
126
|
+
- **Pre-commit scans** send your staged diff.
|
|
127
|
+
|
|
128
|
+
Scanning has known gaps in coverage and reporting that we're still working on. Treat it as one safeguard, not the only one.
|
|
129
|
+
|
|
130
|
+
## Update
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
$ uv tool upgrade reware-lighthouse # or: pipx upgrade reware-lighthouse
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
If the API needs a newer version, commands tell you to upgrade and show the commands above.
|
|
137
|
+
|
|
138
|
+
## Uninstall
|
|
139
|
+
|
|
140
|
+
Clean up before you remove the tool. Once it's gone, nothing is left to run `deinit` or `logout`.
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
$ reware-lighthouse deinit # in each repository you set up
|
|
144
|
+
$ reware-lighthouse logout
|
|
145
|
+
$ uv tool uninstall reware-lighthouse # or: pipx uninstall reware-lighthouse
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
`logout` only removes the key from your machine. To revoke it, ask an admin to rotate or delete it on the dashboard.
|
|
149
|
+
|
|
150
|
+
## License
|
|
151
|
+
|
|
152
|
+
Proprietary. See `LICENSE`.
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# reware-lighthouse
|
|
2
|
+
|
|
3
|
+
`reware-lighthouse` connects your Git repository to [Lighthouse](https://lighthouse.rewarelabs.com), so your coding agent gets security guidance for your codebase and every commit is scanned before it lands.
|
|
4
|
+
|
|
5
|
+
It works with Claude Code and Codex on macOS, Linux, and Windows, and needs Python 3.11 or newer. On Windows, the pre-commit hook runs through [Git for Windows](https://gitforwindows.org).
|
|
6
|
+
|
|
7
|
+
## Quickstart
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
$ uv tool install reware-lighthouse # or: pipx install reware-lighthouse
|
|
11
|
+
$ reware-lighthouse login # paste the API key from your dashboard
|
|
12
|
+
$ cd your-repo
|
|
13
|
+
$ reware-lighthouse init
|
|
14
|
+
$ reware-lighthouse status
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Restart your coding agent afterward so it picks up the new skill and MCP server.
|
|
18
|
+
|
|
19
|
+
What just happened?
|
|
20
|
+
|
|
21
|
+
1. `login` verified your API key and saved it to `~/.config/lighthouse/config.env`.
|
|
22
|
+
2. `init` linked the repository to its Lighthouse project, installed a pre-commit hook, and added the agent skill.
|
|
23
|
+
3. `status` checked that your account, project link, and tooling all work.
|
|
24
|
+
|
|
25
|
+
You'll need an API key first. Create one on the Lighthouse dashboard. It's shown once, so copy it right away.
|
|
26
|
+
|
|
27
|
+
## Enhance a coding request
|
|
28
|
+
|
|
29
|
+
Enhancement adds your repository's security rules to a request before your agent starts coding. It only runs when you ask for it, so ordinary requests are never changed.
|
|
30
|
+
|
|
31
|
+
In Claude Code:
|
|
32
|
+
|
|
33
|
+
```text
|
|
34
|
+
/lighthouse-enhance add a password reset endpoint
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
In Codex, invoke the `lighthouse-enhance` skill with the same request.
|
|
38
|
+
|
|
39
|
+
Your agent tells you which branch's rules it used, plus any warnings, such as a branch that has no repository-specific rules yet. If enhancement fails, the agent stops and asks before continuing without it. Every enhancement appears in your dashboard history.
|
|
40
|
+
|
|
41
|
+
To pick a branch, start the request with `--branch`:
|
|
42
|
+
|
|
43
|
+
```text
|
|
44
|
+
/lighthouse-enhance --branch release add a password reset endpoint
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Without the flag, Lighthouse uses the branch attached to your checkout, then the project's default branch.
|
|
48
|
+
|
|
49
|
+
## Scan commits
|
|
50
|
+
|
|
51
|
+
The pre-commit hook runs `reware-lighthouse scan` on your staged changes. Whether a finding blocks the commit depends on the blocking policy saved for your project.
|
|
52
|
+
|
|
53
|
+
If the API is unreachable or the scan times out, the commit goes through. To change the timeout, set `LIGHTHOUSE_SCAN_TIMEOUT` to a number of seconds.
|
|
54
|
+
|
|
55
|
+
## What `init` creates
|
|
56
|
+
|
|
57
|
+
| Path | Purpose |
|
|
58
|
+
| --- | --- |
|
|
59
|
+
| `~/.config/lighthouse/config.env` (mode `0600`) | Your API key, written by `login`. Never inside a repository. |
|
|
60
|
+
| `.lighthouse/project.toml` | The link to your project (`owner/name`). It holds no secret, so it's safe to commit. |
|
|
61
|
+
| `.git/hooks/pre-commit` | A marked block that runs the scan. If a hook already exists, the block is appended. |
|
|
62
|
+
| `.mcp.json`, `.codex/config.toml` | The MCP server entry that runs `reware-lighthouse mcp`. |
|
|
63
|
+
| `.claude/skills/lighthouse-enhance/`, `.agents/skills/lighthouse-enhance/` | The enhance skill, set to run only when you invoke it. |
|
|
64
|
+
|
|
65
|
+
Use `--agent`, `--no-hook`, or `--no-mcp` to set up less. If a step can't finish, `init` reports which items were created, which were already in place, and which need you. Rerunning it is safe.
|
|
66
|
+
|
|
67
|
+
Note that `init` never edits shared hook setups. If Git uses a shared or global hooks directory (`core.hooksPath` pointing outside the repository), or you use the pre-commit framework, add `reware-lighthouse scan` to that hook yourself. Edits you make to files `init` created are preserved.
|
|
68
|
+
|
|
69
|
+
## Commands
|
|
70
|
+
|
|
71
|
+
| Command | What it does |
|
|
72
|
+
| --- | --- |
|
|
73
|
+
| `login` | Saves and verifies your API key. Accepts `--api-key`, `--api-base`, and `--yes` to skip prompts. |
|
|
74
|
+
| `logout` | Removes the saved key. A key set in the environment stays active. |
|
|
75
|
+
| `init` | Links the repository and sets up the hook, MCP config, and skill. |
|
|
76
|
+
| `deinit` | Removes what `init` created here, as long as you haven't edited it. Your key and scan reports stay. |
|
|
77
|
+
| `status` | Checks your account, project link, and tooling. Exits nonzero if something's wrong. |
|
|
78
|
+
| `scan` | Scans staged changes. Accepts `--project`, `--repo`, and `--branch`. The hook runs it for you. |
|
|
79
|
+
| `mcp` | Runs the MCP server over stdio. Your agent starts it, so you rarely run it by hand. |
|
|
80
|
+
|
|
81
|
+
Run any command with `--help` for an example.
|
|
82
|
+
|
|
83
|
+
## Environment variables
|
|
84
|
+
|
|
85
|
+
| Variable | Meaning |
|
|
86
|
+
| --- | --- |
|
|
87
|
+
| `LIGHTHOUSE_API_KEY` | Your API key. It works without `login`, and `logout` doesn't remove it. |
|
|
88
|
+
| `LIGHTHOUSE_API_BASE_URL` | Use a different Lighthouse API endpoint. |
|
|
89
|
+
| `LIGHTHOUSE_PROJECT` | Use this project instead of the link file or Git remote. |
|
|
90
|
+
| `LIGHTHOUSE_SCAN_TIMEOUT` | Scan timeout in seconds. |
|
|
91
|
+
|
|
92
|
+
## What leaves your machine
|
|
93
|
+
|
|
94
|
+
- **Enhancement** sends the request you give the skill, plus the repository and branch. Lighthouse stores the original and enhanced prompts and shows them in your dashboard history.
|
|
95
|
+
- **Pre-commit scans** send your staged diff.
|
|
96
|
+
|
|
97
|
+
Scanning has known gaps in coverage and reporting that we're still working on. Treat it as one safeguard, not the only one.
|
|
98
|
+
|
|
99
|
+
## Update
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
$ uv tool upgrade reware-lighthouse # or: pipx upgrade reware-lighthouse
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
If the API needs a newer version, commands tell you to upgrade and show the commands above.
|
|
106
|
+
|
|
107
|
+
## Uninstall
|
|
108
|
+
|
|
109
|
+
Clean up before you remove the tool. Once it's gone, nothing is left to run `deinit` or `logout`.
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
$ reware-lighthouse deinit # in each repository you set up
|
|
113
|
+
$ reware-lighthouse logout
|
|
114
|
+
$ uv tool uninstall reware-lighthouse # or: pipx uninstall reware-lighthouse
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
`logout` only removes the key from your machine. To revoke it, ask an admin to rotate or delete it on the dashboard.
|
|
118
|
+
|
|
119
|
+
## License
|
|
120
|
+
|
|
121
|
+
Proprietary. See `LICENSE`.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "reware-lighthouse"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Lighthouse developer CLI — link a repo to a project, enhance prompts, and scan commits"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = "LicenseRef-Proprietary"
|
|
7
|
+
license-files = ["LICENSE"]
|
|
8
|
+
authors = [{ name = "RewareLabs" }]
|
|
9
|
+
keywords = ["security", "ai-agents", "mcp", "pre-commit", "code-scanning", "claude-code", "codex"]
|
|
10
|
+
classifiers = [
|
|
11
|
+
"Development Status :: 4 - Beta",
|
|
12
|
+
"Environment :: Console",
|
|
13
|
+
"Intended Audience :: Developers",
|
|
14
|
+
"Topic :: Security",
|
|
15
|
+
"Topic :: Software Development :: Quality Assurance",
|
|
16
|
+
"Operating System :: MacOS",
|
|
17
|
+
"Operating System :: POSIX :: Linux",
|
|
18
|
+
"Operating System :: Microsoft :: Windows", "Programming Language :: Python :: 3.11",
|
|
19
|
+
"Programming Language :: Python :: 3.12",
|
|
20
|
+
"Programming Language :: Python :: 3.13",
|
|
21
|
+
"Programming Language :: Python :: 3.14",
|
|
22
|
+
]
|
|
23
|
+
requires-python = ">=3.11"
|
|
24
|
+
dependencies = [
|
|
25
|
+
"httpx>=0.28,<1",
|
|
26
|
+
"mcp>=2.0.0,<3",
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
[project.urls]
|
|
30
|
+
Homepage = "https://lighthouse.rewarelabs.com"
|
|
31
|
+
|
|
32
|
+
[project.optional-dependencies]
|
|
33
|
+
dev = [
|
|
34
|
+
"pytest>=8.3,<10",
|
|
35
|
+
"pytest-asyncio>=0.25,<2",
|
|
36
|
+
"respx>=0.22,<1",
|
|
37
|
+
"ruff>=0.12,<1",
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
[project.scripts]
|
|
41
|
+
reware-lighthouse = "lighthouse_cli.cli:run"
|
|
42
|
+
|
|
43
|
+
[build-system]
|
|
44
|
+
requires = ["hatchling"]
|
|
45
|
+
build-backend = "hatchling.build"
|
|
46
|
+
|
|
47
|
+
[tool.hatch.build.targets.wheel]
|
|
48
|
+
packages = ["src/lighthouse_cli"]
|
|
49
|
+
|
|
50
|
+
[tool.hatch.build.targets.sdist]
|
|
51
|
+
include = ["src", "README.md", "CHANGELOG.md", "LICENSE", "pyproject.toml"]
|
|
52
|
+
|
|
53
|
+
[tool.pytest.ini_options]
|
|
54
|
+
asyncio_mode = "auto"
|
|
55
|
+
testpaths = ["tests"]
|
|
56
|
+
pythonpath = ["src"]
|
|
57
|
+
markers = ["posix: needs POSIX file modes or a POSIX shell; skipped on Windows"]
|
|
58
|
+
|
|
59
|
+
[tool.ruff]
|
|
60
|
+
line-length = 100
|
|
61
|
+
target-version = "py311"
|
|
62
|
+
|
|
63
|
+
[tool.ruff.lint]
|
|
64
|
+
select = ["E", "F", "I", "UP", "B", "SIM"]
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"""Typed wrappers over the Lighthouse product API endpoints the CLI uses."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, TypedDict
|
|
4
|
+
|
|
5
|
+
from lighthouse_cli.config import ClientConfig
|
|
6
|
+
from lighthouse_cli.git_remote import normalize_repo_full_name
|
|
7
|
+
from lighthouse_cli.http import get_json
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class Project(TypedDict, total=False):
|
|
11
|
+
name: str
|
|
12
|
+
slug: str
|
|
13
|
+
repo_full_name: str | None
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def whoami(config: ClientConfig) -> dict[str, Any]:
|
|
17
|
+
"""GET /v1/me — verify the API key and return {user, team}."""
|
|
18
|
+
body = get_json(config, "/v1/me")
|
|
19
|
+
return body if isinstance(body, dict) else {}
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def list_projects(config: ClientConfig) -> list[Project]:
|
|
23
|
+
"""GET /v1/projects — the team's registered projects."""
|
|
24
|
+
body = get_json(config, "/v1/projects")
|
|
25
|
+
return [p for p in body if isinstance(p, dict)] if isinstance(body, list) else []
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def match_project(projects: list[Project], identifier: str) -> Project | None:
|
|
29
|
+
"""Find the project whose repo_full_name or slug matches the identifier."""
|
|
30
|
+
wanted = identifier.strip().lower()
|
|
31
|
+
normalized = normalize_repo_full_name(identifier) or wanted
|
|
32
|
+
for project in projects:
|
|
33
|
+
repo = (project.get("repo_full_name") or "").lower()
|
|
34
|
+
if (repo and repo == normalized) or project.get("slug", "").lower() == wanted:
|
|
35
|
+
return project
|
|
36
|
+
return None
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
__all__ = ["Project", "list_projects", "match_project", "whoami"]
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"""The `reware-lighthouse` command dispatcher.
|
|
2
|
+
|
|
3
|
+
Each subcommand owns its own argument parsing, so the dispatcher just routes the
|
|
4
|
+
first token and forwards the rest. New subcommands register in ``_COMMANDS``.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import sys
|
|
8
|
+
from collections.abc import Callable
|
|
9
|
+
|
|
10
|
+
from lighthouse_cli import ui
|
|
11
|
+
from lighthouse_cli.commands import deinit, init, login, logout, scan, status
|
|
12
|
+
from lighthouse_cli.config import ClientConfigError
|
|
13
|
+
from lighthouse_cli.http import ClientRequestError
|
|
14
|
+
from lighthouse_cli.identity import COMMAND, NotInstalledError, version
|
|
15
|
+
from lighthouse_cli.link import LinkError
|
|
16
|
+
from lighthouse_cli.mcp import run as run_mcp
|
|
17
|
+
|
|
18
|
+
_COMMANDS: dict[str, Callable[[list[str]], int]] = {
|
|
19
|
+
"login": login.run,
|
|
20
|
+
"logout": logout.run,
|
|
21
|
+
"init": init.run,
|
|
22
|
+
"deinit": deinit.run,
|
|
23
|
+
"scan": scan.run,
|
|
24
|
+
"status": status.run,
|
|
25
|
+
"mcp": run_mcp,
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
_USAGE = f"""{COMMAND} — developer CLI for Lighthouse
|
|
29
|
+
|
|
30
|
+
Usage: {COMMAND} <command> [options]
|
|
31
|
+
{COMMAND} --version
|
|
32
|
+
|
|
33
|
+
Commands:
|
|
34
|
+
login Store and verify your API key
|
|
35
|
+
logout Remove the saved API key
|
|
36
|
+
init Link this repository to a project and set up tooling
|
|
37
|
+
deinit Remove what init set up in this repository
|
|
38
|
+
scan Run the pre-commit security scan
|
|
39
|
+
status Check your account, project and tooling (exit 0 means it works)
|
|
40
|
+
mcp Run the stdio MCP server (usually launched by your coding agent)
|
|
41
|
+
help Show help for a command: {COMMAND} help <command>
|
|
42
|
+
|
|
43
|
+
Prompt enhancement runs only when you ask for it in your coding agent:
|
|
44
|
+
/lighthouse-enhance <request> in Claude Code, the lighthouse-enhance skill in Codex.
|
|
45
|
+
|
|
46
|
+
Run `{COMMAND} <command> --help` for command-specific options."""
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def _print_version(_argv: list[str]) -> int:
|
|
50
|
+
print(f"{COMMAND} {version()}")
|
|
51
|
+
return 0
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
_ORDINARY = (ClientConfigError, ClientRequestError, LinkError, OSError, ui.NoTerminalError)
|
|
55
|
+
_OWN_ERRORS = frozenset({"scan", "mcp"}) # scan fails open itself; mcp owns stdout
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def _guarded(
|
|
59
|
+
handler: Callable[[list[str]], int], argv: list[str], *, ordinary: bool = False
|
|
60
|
+
) -> int:
|
|
61
|
+
try:
|
|
62
|
+
return handler(argv)
|
|
63
|
+
except NotInstalledError as exc:
|
|
64
|
+
print(f"{COMMAND}: {exc}", file=sys.stderr)
|
|
65
|
+
return 1
|
|
66
|
+
except Exception as exc:
|
|
67
|
+
if not (ordinary and isinstance(exc, _ORDINARY)):
|
|
68
|
+
raise
|
|
69
|
+
ui.error(str(exc))
|
|
70
|
+
return 2 if isinstance(exc, ui.NoTerminalError) else 1
|
|
71
|
+
except KeyboardInterrupt:
|
|
72
|
+
if not ordinary:
|
|
73
|
+
raise
|
|
74
|
+
print("Interrupted.", file=sys.stderr)
|
|
75
|
+
return 130
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def run(argv: list[str] | None = None) -> int:
|
|
79
|
+
for stream in (sys.stdout, sys.stderr):
|
|
80
|
+
# A git hook on Windows pipes output through a legacy codepage that lacks ✓ and •.
|
|
81
|
+
if hasattr(stream, "reconfigure"):
|
|
82
|
+
stream.reconfigure(errors="replace")
|
|
83
|
+
args = list(sys.argv[1:] if argv is None else argv)
|
|
84
|
+
if args[:1] == ["help"] and len(args) > 1:
|
|
85
|
+
args = [args[1], "--help"]
|
|
86
|
+
if not args or args[0] in {"-h", "--help", "help"}:
|
|
87
|
+
print(_USAGE)
|
|
88
|
+
return 0
|
|
89
|
+
if args[0] in {"-V", "--version"}:
|
|
90
|
+
return _guarded(_print_version, [])
|
|
91
|
+
command, rest = args[0], args[1:]
|
|
92
|
+
handler = _COMMANDS.get(command)
|
|
93
|
+
if handler is None:
|
|
94
|
+
print(f"{COMMAND}: unknown command '{command}'.\n\n{_USAGE}", file=sys.stderr)
|
|
95
|
+
return 2
|
|
96
|
+
return _guarded(handler, rest, ordinary=command not in _OWN_ERRORS)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
if __name__ == "__main__":
|
|
100
|
+
raise SystemExit(run())
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""`lighthouse` subcommands."""
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"""`lighthouse deinit` — undo what `init` set up in this repository.
|
|
2
|
+
|
|
3
|
+
Removes only content `init` recorded and the developer has not edited. Saved credentials
|
|
4
|
+
(`logout`), scan reports and the installed tool are left alone.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import contextlib
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
from lighthouse_cli import ui
|
|
11
|
+
from lighthouse_cli.config import has_saved_api_key
|
|
12
|
+
from lighthouse_cli.git_remote import git_toplevel
|
|
13
|
+
from lighthouse_cli.identity import COMMAND
|
|
14
|
+
from lighthouse_cli.link import LINK_DIR, LinkError, remove_link
|
|
15
|
+
from lighthouse_cli.parsing import parser
|
|
16
|
+
from lighthouse_cli.setup import remove
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _remove_link(root: Path) -> bool:
|
|
20
|
+
try:
|
|
21
|
+
path = remove_link(root)
|
|
22
|
+
except (LinkError, OSError) as exc:
|
|
23
|
+
ui.warn(f"Left the project link as is: {exc}")
|
|
24
|
+
return False
|
|
25
|
+
if path:
|
|
26
|
+
ui.success(f"Removed {path}.")
|
|
27
|
+
with contextlib.suppress(OSError):
|
|
28
|
+
(root / LINK_DIR).rmdir() # only succeeds when nothing else lives there
|
|
29
|
+
return True
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def run(argv: list[str] | None = None) -> int:
|
|
33
|
+
parser("deinit", "Remove what init set up in this repository.", "deinit").parse_args(argv)
|
|
34
|
+
|
|
35
|
+
root_path = git_toplevel()
|
|
36
|
+
if root_path is None:
|
|
37
|
+
ui.error(f"Run `{COMMAND} deinit` from inside a Git repository.")
|
|
38
|
+
return 1
|
|
39
|
+
root = Path(root_path)
|
|
40
|
+
|
|
41
|
+
report = remove(root)
|
|
42
|
+
for step in report.steps:
|
|
43
|
+
(ui.success if step.ok else ui.warn)(step.message)
|
|
44
|
+
linked = _remove_link(root)
|
|
45
|
+
if not report.complete or not linked:
|
|
46
|
+
ui.error("Cleanup is incomplete. Finish the items above by hand.")
|
|
47
|
+
return 1
|
|
48
|
+
if has_saved_api_key():
|
|
49
|
+
ui.hint(
|
|
50
|
+
f"Your API key stays saved (`{COMMAND} logout` removes it) and scan reports are kept."
|
|
51
|
+
)
|
|
52
|
+
else:
|
|
53
|
+
ui.hint("Scan reports are kept.")
|
|
54
|
+
return 0
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
__all__ = ["run"]
|