goodeye 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.
- goodeye-0.1.0/.github/workflows/ci.yml +30 -0
- goodeye-0.1.0/.github/workflows/publish.yml +30 -0
- goodeye-0.1.0/.gitignore +48 -0
- goodeye-0.1.0/.pre-commit-config.yaml +15 -0
- goodeye-0.1.0/CONTRIBUTING.md +55 -0
- goodeye-0.1.0/LICENSE +21 -0
- goodeye-0.1.0/PKG-INFO +184 -0
- goodeye-0.1.0/README.md +136 -0
- goodeye-0.1.0/pyproject.toml +81 -0
- goodeye-0.1.0/src/goodeye_cli/__init__.py +3 -0
- goodeye-0.1.0/src/goodeye_cli/__main__.py +16 -0
- goodeye-0.1.0/src/goodeye_cli/app.py +69 -0
- goodeye-0.1.0/src/goodeye_cli/auth_flows.py +168 -0
- goodeye-0.1.0/src/goodeye_cli/client.py +299 -0
- goodeye-0.1.0/src/goodeye_cli/commands/__init__.py +1 -0
- goodeye-0.1.0/src/goodeye_cli/commands/auth.py +117 -0
- goodeye-0.1.0/src/goodeye_cli/commands/design.py +47 -0
- goodeye-0.1.0/src/goodeye_cli/commands/login.py +52 -0
- goodeye-0.1.0/src/goodeye_cli/commands/logout.py +27 -0
- goodeye-0.1.0/src/goodeye_cli/commands/signup.py +29 -0
- goodeye-0.1.0/src/goodeye_cli/commands/skills.py +249 -0
- goodeye-0.1.0/src/goodeye_cli/commands/whoami.py +35 -0
- goodeye-0.1.0/src/goodeye_cli/config.py +146 -0
- goodeye-0.1.0/src/goodeye_cli/errors.py +98 -0
- goodeye-0.1.0/src/goodeye_cli/wire.py +116 -0
- goodeye-0.1.0/tests/__init__.py +0 -0
- goodeye-0.1.0/tests/conftest.py +29 -0
- goodeye-0.1.0/tests/test_auth_flows.py +228 -0
- goodeye-0.1.0/tests/test_client.py +218 -0
- goodeye-0.1.0/tests/test_commands_auth.py +84 -0
- goodeye-0.1.0/tests/test_commands_meta.py +134 -0
- goodeye-0.1.0/tests/test_commands_skills.py +208 -0
- goodeye-0.1.0/tests/test_config.py +102 -0
- goodeye-0.1.0/uv.lock +715 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
lint-and-test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
|
|
15
|
+
- name: Install uv
|
|
16
|
+
uses: astral-sh/setup-uv@v3
|
|
17
|
+
with:
|
|
18
|
+
enable-cache: true
|
|
19
|
+
|
|
20
|
+
- name: Set up Python
|
|
21
|
+
run: uv python install 3.12
|
|
22
|
+
|
|
23
|
+
- name: Install dependencies
|
|
24
|
+
run: uv sync --group dev --frozen
|
|
25
|
+
|
|
26
|
+
- name: Run pre-commit (ruff + pyright)
|
|
27
|
+
run: uv run pre-commit run --all-files
|
|
28
|
+
|
|
29
|
+
- name: Run tests
|
|
30
|
+
run: uv run pytest
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
name: Publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
build-and-publish:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
environment: pypi
|
|
12
|
+
permissions:
|
|
13
|
+
id-token: write # required for OIDC trusted publishing
|
|
14
|
+
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
|
|
18
|
+
- name: Install uv
|
|
19
|
+
uses: astral-sh/setup-uv@v3
|
|
20
|
+
with:
|
|
21
|
+
enable-cache: true
|
|
22
|
+
|
|
23
|
+
- name: Set up Python
|
|
24
|
+
run: uv python install 3.12
|
|
25
|
+
|
|
26
|
+
- name: Build
|
|
27
|
+
run: uv build
|
|
28
|
+
|
|
29
|
+
- name: Publish to PyPI
|
|
30
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
goodeye-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Environment
|
|
2
|
+
.env
|
|
3
|
+
.env.*
|
|
4
|
+
!.env.example
|
|
5
|
+
|
|
6
|
+
# Python
|
|
7
|
+
__pycache__/
|
|
8
|
+
*.py[cod]
|
|
9
|
+
*$py.class
|
|
10
|
+
*.so
|
|
11
|
+
.Python
|
|
12
|
+
.venv/
|
|
13
|
+
venv/
|
|
14
|
+
env/
|
|
15
|
+
ENV/
|
|
16
|
+
|
|
17
|
+
# Distribution / packaging
|
|
18
|
+
build/
|
|
19
|
+
dist/
|
|
20
|
+
*.egg-info/
|
|
21
|
+
*.egg
|
|
22
|
+
wheels/
|
|
23
|
+
pip-wheel-metadata/
|
|
24
|
+
|
|
25
|
+
# Testing / coverage
|
|
26
|
+
.pytest_cache/
|
|
27
|
+
.coverage
|
|
28
|
+
.coverage.*
|
|
29
|
+
htmlcov/
|
|
30
|
+
.tox/
|
|
31
|
+
.nox/
|
|
32
|
+
coverage.xml
|
|
33
|
+
*.cover
|
|
34
|
+
|
|
35
|
+
# Type checkers / linters
|
|
36
|
+
.mypy_cache/
|
|
37
|
+
.pyright/
|
|
38
|
+
.ruff_cache/
|
|
39
|
+
|
|
40
|
+
# Editors
|
|
41
|
+
.idea/
|
|
42
|
+
.vscode/
|
|
43
|
+
*.swp
|
|
44
|
+
*.swo
|
|
45
|
+
.DS_Store
|
|
46
|
+
|
|
47
|
+
# uv
|
|
48
|
+
.python-version
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
3
|
+
rev: v0.6.9
|
|
4
|
+
hooks:
|
|
5
|
+
- id: ruff
|
|
6
|
+
args: [--fix]
|
|
7
|
+
- id: ruff-format
|
|
8
|
+
- repo: local
|
|
9
|
+
hooks:
|
|
10
|
+
- id: pyright
|
|
11
|
+
name: pyright
|
|
12
|
+
entry: uv run pyright
|
|
13
|
+
language: system
|
|
14
|
+
types: [python]
|
|
15
|
+
pass_filenames: false
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Thanks for your interest in goodeye-cli.
|
|
4
|
+
|
|
5
|
+
## Dev setup
|
|
6
|
+
|
|
7
|
+
Prerequisite: [uv](https://github.com/astral-sh/uv) (Python package manager).
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
git clone https://github.com/Goodeye-Labs/goodeye-cli.git
|
|
11
|
+
cd goodeye-cli
|
|
12
|
+
uv sync --group dev
|
|
13
|
+
uv run pre-commit install
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Run the same checks CI runs
|
|
17
|
+
|
|
18
|
+
```sh
|
|
19
|
+
uv sync --group dev --frozen
|
|
20
|
+
uv run pre-commit run --all-files
|
|
21
|
+
uv run pytest
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Project layout
|
|
25
|
+
|
|
26
|
+
- `src/goodeye_cli/` - CLI package
|
|
27
|
+
- `app.py` - Typer app root
|
|
28
|
+
- `commands/` - one module per subcommand group
|
|
29
|
+
- `client.py` - sync HTTP client around the Goodeye REST API
|
|
30
|
+
- `auth_flows.py` - device-code and magic-auth flows
|
|
31
|
+
- `config.py` - credentials + client config file I/O
|
|
32
|
+
- `wire.py` - pydantic wire models for REST responses
|
|
33
|
+
- `errors.py` - structured CLI errors (mirror server slugs)
|
|
34
|
+
- `tests/` - pytest suite. Network is mocked with `respx`; no live calls.
|
|
35
|
+
|
|
36
|
+
## Conventions
|
|
37
|
+
|
|
38
|
+
- Python 3.12+, ruff for lint + format, pyright for types.
|
|
39
|
+
- Line length 100.
|
|
40
|
+
- No em dashes in prose, comments, or docs; use `-`, `:`, or rephrase.
|
|
41
|
+
- Never commit secrets. Tests should mock WorkOS and the Goodeye server.
|
|
42
|
+
- Use obvious placeholders in example tokens (e.g. `good_live_EXAMPLE_...`).
|
|
43
|
+
|
|
44
|
+
## PR process
|
|
45
|
+
|
|
46
|
+
1. Branch from `main`.
|
|
47
|
+
2. Keep changes scoped; one logical change per PR.
|
|
48
|
+
3. Ensure `pre-commit` and `pytest` pass locally.
|
|
49
|
+
4. Open a PR against `main`. CI runs ruff + pyright + pytest.
|
|
50
|
+
5. A maintainer will review.
|
|
51
|
+
|
|
52
|
+
## Reporting security issues
|
|
53
|
+
|
|
54
|
+
Please do not open public issues for security reports. Email the maintainers
|
|
55
|
+
or use GitHub's private vulnerability reporting feature on this repository.
|
goodeye-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Goodeye Labs
|
|
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.
|
goodeye-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: goodeye
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Public CLI for Goodeye - manage AI workflow skills from the terminal.
|
|
5
|
+
Project-URL: Repository, https://github.com/Goodeye-Labs/goodeye-cli
|
|
6
|
+
Project-URL: Issues, https://github.com/Goodeye-Labs/goodeye-cli/issues
|
|
7
|
+
Author: Goodeye Labs
|
|
8
|
+
License: MIT License
|
|
9
|
+
|
|
10
|
+
Copyright (c) 2026 Goodeye Labs
|
|
11
|
+
|
|
12
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
13
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
14
|
+
in the Software without restriction, including without limitation the rights
|
|
15
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
16
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
17
|
+
furnished to do so, subject to the following conditions:
|
|
18
|
+
|
|
19
|
+
The above copyright notice and this permission notice shall be included in all
|
|
20
|
+
copies or substantial portions of the Software.
|
|
21
|
+
|
|
22
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
23
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
24
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
25
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
26
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
27
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
28
|
+
SOFTWARE.
|
|
29
|
+
License-File: LICENSE
|
|
30
|
+
Keywords: ai,cli,goodeye,mcp,workflows
|
|
31
|
+
Classifier: Development Status :: 3 - Alpha
|
|
32
|
+
Classifier: Environment :: Console
|
|
33
|
+
Classifier: Intended Audience :: Developers
|
|
34
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
35
|
+
Classifier: Operating System :: OS Independent
|
|
36
|
+
Classifier: Programming Language :: Python :: 3
|
|
37
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
38
|
+
Classifier: Topic :: Software Development
|
|
39
|
+
Classifier: Topic :: Utilities
|
|
40
|
+
Requires-Python: >=3.12
|
|
41
|
+
Requires-Dist: httpx>=0.27
|
|
42
|
+
Requires-Dist: pydantic-settings>=2.4
|
|
43
|
+
Requires-Dist: pydantic>=2.7
|
|
44
|
+
Requires-Dist: pyyaml>=6
|
|
45
|
+
Requires-Dist: rich>=13
|
|
46
|
+
Requires-Dist: typer>=0.12
|
|
47
|
+
Description-Content-Type: text/markdown
|
|
48
|
+
|
|
49
|
+
# goodeye-cli
|
|
50
|
+
|
|
51
|
+
Command-line client for Goodeye - manage AI workflow skills from the terminal.
|
|
52
|
+
|
|
53
|
+
Goodeye is an outcome-aligned AI workflow registry: you author skills (markdown
|
|
54
|
+
bodies + manifests) and verifiers that score an AI agent against a measurable
|
|
55
|
+
business outcome. This CLI is wired to the public `/v1/` REST API.
|
|
56
|
+
|
|
57
|
+
## Install
|
|
58
|
+
|
|
59
|
+
Requires Python 3.12+.
|
|
60
|
+
|
|
61
|
+
```sh
|
|
62
|
+
uv tool install goodeye
|
|
63
|
+
# or
|
|
64
|
+
pipx install goodeye
|
|
65
|
+
# or
|
|
66
|
+
pip install goodeye
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Once installed, the `goodeye` command is available on your `PATH`.
|
|
70
|
+
|
|
71
|
+
## Quickstart
|
|
72
|
+
|
|
73
|
+
```sh
|
|
74
|
+
# Browse the public registry without an account
|
|
75
|
+
goodeye skills list --filter public
|
|
76
|
+
|
|
77
|
+
# Create an account (emails a one-time code)
|
|
78
|
+
goodeye signup --email you@example.com
|
|
79
|
+
|
|
80
|
+
# Or log in on a machine with a browser
|
|
81
|
+
goodeye login
|
|
82
|
+
|
|
83
|
+
# Confirm who you are
|
|
84
|
+
goodeye whoami
|
|
85
|
+
|
|
86
|
+
# Fetch a public skill as markdown
|
|
87
|
+
goodeye skills get brand-voice > brand-voice.md
|
|
88
|
+
|
|
89
|
+
# Push a local skill
|
|
90
|
+
goodeye skills push ./my-skill.md --public
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Skill files
|
|
94
|
+
|
|
95
|
+
`goodeye skills push` reads a markdown file with optional YAML front-matter:
|
|
96
|
+
|
|
97
|
+
```markdown
|
|
98
|
+
---
|
|
99
|
+
slug: my-skill
|
|
100
|
+
visibility: private
|
|
101
|
+
manifest:
|
|
102
|
+
title: My skill
|
|
103
|
+
tags: [data, cleanup]
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
# Body
|
|
107
|
+
|
|
108
|
+
The rest of the file is the skill body rendered to the agent at runtime.
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
`--public` on the command line overrides `visibility`. `--slug` on the command
|
|
112
|
+
line overrides the front-matter `slug`.
|
|
113
|
+
|
|
114
|
+
## Command reference
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
goodeye login [--email EMAIL]
|
|
118
|
+
Without --email: opens the browser for WorkOS device-code approval.
|
|
119
|
+
With --email: sends a one-time code to your inbox.
|
|
120
|
+
|
|
121
|
+
goodeye signup --email EMAIL
|
|
122
|
+
Creates an account and mints your initial API key.
|
|
123
|
+
|
|
124
|
+
goodeye logout
|
|
125
|
+
Deletes local credentials. Does not revoke the key server-side; see
|
|
126
|
+
`goodeye auth list-keys` and `goodeye auth revoke-key`.
|
|
127
|
+
|
|
128
|
+
goodeye whoami
|
|
129
|
+
Shows the current user identified by your credentials.
|
|
130
|
+
|
|
131
|
+
goodeye auth create-key --name NAME [--copy]
|
|
132
|
+
Mints a new API key. The secret is printed once.
|
|
133
|
+
|
|
134
|
+
goodeye auth list-keys
|
|
135
|
+
Table of your API keys (secrets are never returned).
|
|
136
|
+
|
|
137
|
+
goodeye auth revoke-key <id>
|
|
138
|
+
Revokes (soft-deletes) a key.
|
|
139
|
+
|
|
140
|
+
goodeye skills list [--filter all|public|own] [--tag TAG] [--search QUERY] [--json]
|
|
141
|
+
Paginated listing; auto-follows cursor.
|
|
142
|
+
|
|
143
|
+
goodeye skills get <id-or-slug> [--version N] [--output PATH] [--json]
|
|
144
|
+
Emits raw markdown by default; --json returns the envelope.
|
|
145
|
+
|
|
146
|
+
goodeye skills push <file.md> [--id ID] [--public] [--slug SLUG]
|
|
147
|
+
Creates or appends a skill version.
|
|
148
|
+
|
|
149
|
+
goodeye skills set-visibility <id> <private|public>
|
|
150
|
+
goodeye skills delete <id> [--yes]
|
|
151
|
+
|
|
152
|
+
goodeye design
|
|
153
|
+
Prints the workflow-designer prompt pack to stdout.
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Configuration
|
|
157
|
+
|
|
158
|
+
### Credentials
|
|
159
|
+
|
|
160
|
+
- `GOODEYE_API_KEY` env var (highest precedence).
|
|
161
|
+
- `~/.config/goodeye/credentials.json` (or `$XDG_CONFIG_HOME/goodeye/`).
|
|
162
|
+
|
|
163
|
+
Credential files are created with mode `0600`.
|
|
164
|
+
|
|
165
|
+
### Server
|
|
166
|
+
|
|
167
|
+
- `GOODEYE_SERVER` env var.
|
|
168
|
+
- `server` field inside `credentials.json`.
|
|
169
|
+
- Default: `https://mcp.goodeyelabs.com`.
|
|
170
|
+
|
|
171
|
+
## REST API, not the CLI
|
|
172
|
+
|
|
173
|
+
This CLI is pinned to the `/v1/` REST API contract. If you are integrating
|
|
174
|
+
programmatically and want a stable contract, prefer the REST API directly;
|
|
175
|
+
the CLI is a convenience layer over it.
|
|
176
|
+
|
|
177
|
+
## Contributing
|
|
178
|
+
|
|
179
|
+
See [CONTRIBUTING.md](./CONTRIBUTING.md) for local-dev setup and the PR
|
|
180
|
+
process. Issues and PRs welcome.
|
|
181
|
+
|
|
182
|
+
## License
|
|
183
|
+
|
|
184
|
+
MIT. See [LICENSE](./LICENSE).
|
goodeye-0.1.0/README.md
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# goodeye-cli
|
|
2
|
+
|
|
3
|
+
Command-line client for Goodeye - manage AI workflow skills from the terminal.
|
|
4
|
+
|
|
5
|
+
Goodeye is an outcome-aligned AI workflow registry: you author skills (markdown
|
|
6
|
+
bodies + manifests) and verifiers that score an AI agent against a measurable
|
|
7
|
+
business outcome. This CLI is wired to the public `/v1/` REST API.
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
Requires Python 3.12+.
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
uv tool install goodeye
|
|
15
|
+
# or
|
|
16
|
+
pipx install goodeye
|
|
17
|
+
# or
|
|
18
|
+
pip install goodeye
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Once installed, the `goodeye` command is available on your `PATH`.
|
|
22
|
+
|
|
23
|
+
## Quickstart
|
|
24
|
+
|
|
25
|
+
```sh
|
|
26
|
+
# Browse the public registry without an account
|
|
27
|
+
goodeye skills list --filter public
|
|
28
|
+
|
|
29
|
+
# Create an account (emails a one-time code)
|
|
30
|
+
goodeye signup --email you@example.com
|
|
31
|
+
|
|
32
|
+
# Or log in on a machine with a browser
|
|
33
|
+
goodeye login
|
|
34
|
+
|
|
35
|
+
# Confirm who you are
|
|
36
|
+
goodeye whoami
|
|
37
|
+
|
|
38
|
+
# Fetch a public skill as markdown
|
|
39
|
+
goodeye skills get brand-voice > brand-voice.md
|
|
40
|
+
|
|
41
|
+
# Push a local skill
|
|
42
|
+
goodeye skills push ./my-skill.md --public
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Skill files
|
|
46
|
+
|
|
47
|
+
`goodeye skills push` reads a markdown file with optional YAML front-matter:
|
|
48
|
+
|
|
49
|
+
```markdown
|
|
50
|
+
---
|
|
51
|
+
slug: my-skill
|
|
52
|
+
visibility: private
|
|
53
|
+
manifest:
|
|
54
|
+
title: My skill
|
|
55
|
+
tags: [data, cleanup]
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
# Body
|
|
59
|
+
|
|
60
|
+
The rest of the file is the skill body rendered to the agent at runtime.
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
`--public` on the command line overrides `visibility`. `--slug` on the command
|
|
64
|
+
line overrides the front-matter `slug`.
|
|
65
|
+
|
|
66
|
+
## Command reference
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
goodeye login [--email EMAIL]
|
|
70
|
+
Without --email: opens the browser for WorkOS device-code approval.
|
|
71
|
+
With --email: sends a one-time code to your inbox.
|
|
72
|
+
|
|
73
|
+
goodeye signup --email EMAIL
|
|
74
|
+
Creates an account and mints your initial API key.
|
|
75
|
+
|
|
76
|
+
goodeye logout
|
|
77
|
+
Deletes local credentials. Does not revoke the key server-side; see
|
|
78
|
+
`goodeye auth list-keys` and `goodeye auth revoke-key`.
|
|
79
|
+
|
|
80
|
+
goodeye whoami
|
|
81
|
+
Shows the current user identified by your credentials.
|
|
82
|
+
|
|
83
|
+
goodeye auth create-key --name NAME [--copy]
|
|
84
|
+
Mints a new API key. The secret is printed once.
|
|
85
|
+
|
|
86
|
+
goodeye auth list-keys
|
|
87
|
+
Table of your API keys (secrets are never returned).
|
|
88
|
+
|
|
89
|
+
goodeye auth revoke-key <id>
|
|
90
|
+
Revokes (soft-deletes) a key.
|
|
91
|
+
|
|
92
|
+
goodeye skills list [--filter all|public|own] [--tag TAG] [--search QUERY] [--json]
|
|
93
|
+
Paginated listing; auto-follows cursor.
|
|
94
|
+
|
|
95
|
+
goodeye skills get <id-or-slug> [--version N] [--output PATH] [--json]
|
|
96
|
+
Emits raw markdown by default; --json returns the envelope.
|
|
97
|
+
|
|
98
|
+
goodeye skills push <file.md> [--id ID] [--public] [--slug SLUG]
|
|
99
|
+
Creates or appends a skill version.
|
|
100
|
+
|
|
101
|
+
goodeye skills set-visibility <id> <private|public>
|
|
102
|
+
goodeye skills delete <id> [--yes]
|
|
103
|
+
|
|
104
|
+
goodeye design
|
|
105
|
+
Prints the workflow-designer prompt pack to stdout.
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Configuration
|
|
109
|
+
|
|
110
|
+
### Credentials
|
|
111
|
+
|
|
112
|
+
- `GOODEYE_API_KEY` env var (highest precedence).
|
|
113
|
+
- `~/.config/goodeye/credentials.json` (or `$XDG_CONFIG_HOME/goodeye/`).
|
|
114
|
+
|
|
115
|
+
Credential files are created with mode `0600`.
|
|
116
|
+
|
|
117
|
+
### Server
|
|
118
|
+
|
|
119
|
+
- `GOODEYE_SERVER` env var.
|
|
120
|
+
- `server` field inside `credentials.json`.
|
|
121
|
+
- Default: `https://mcp.goodeyelabs.com`.
|
|
122
|
+
|
|
123
|
+
## REST API, not the CLI
|
|
124
|
+
|
|
125
|
+
This CLI is pinned to the `/v1/` REST API contract. If you are integrating
|
|
126
|
+
programmatically and want a stable contract, prefer the REST API directly;
|
|
127
|
+
the CLI is a convenience layer over it.
|
|
128
|
+
|
|
129
|
+
## Contributing
|
|
130
|
+
|
|
131
|
+
See [CONTRIBUTING.md](./CONTRIBUTING.md) for local-dev setup and the PR
|
|
132
|
+
process. Issues and PRs welcome.
|
|
133
|
+
|
|
134
|
+
## License
|
|
135
|
+
|
|
136
|
+
MIT. See [LICENSE](./LICENSE).
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "goodeye"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Public CLI for Goodeye - manage AI workflow skills from the terminal."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = { file = "LICENSE" }
|
|
7
|
+
requires-python = ">=3.12"
|
|
8
|
+
authors = [
|
|
9
|
+
{ name = "Goodeye Labs" },
|
|
10
|
+
]
|
|
11
|
+
keywords = ["goodeye", "cli", "ai", "workflows", "mcp"]
|
|
12
|
+
classifiers = [
|
|
13
|
+
"Development Status :: 3 - Alpha",
|
|
14
|
+
"Environment :: Console",
|
|
15
|
+
"Intended Audience :: Developers",
|
|
16
|
+
"License :: OSI Approved :: MIT License",
|
|
17
|
+
"Operating System :: OS Independent",
|
|
18
|
+
"Programming Language :: Python :: 3",
|
|
19
|
+
"Programming Language :: Python :: 3.12",
|
|
20
|
+
"Topic :: Software Development",
|
|
21
|
+
"Topic :: Utilities",
|
|
22
|
+
]
|
|
23
|
+
dependencies = [
|
|
24
|
+
"typer>=0.12",
|
|
25
|
+
"httpx>=0.27",
|
|
26
|
+
"rich>=13",
|
|
27
|
+
"pydantic>=2.7",
|
|
28
|
+
"pydantic-settings>=2.4",
|
|
29
|
+
"pyyaml>=6",
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
[project.scripts]
|
|
33
|
+
goodeye = "goodeye_cli.__main__:main"
|
|
34
|
+
|
|
35
|
+
[project.urls]
|
|
36
|
+
Repository = "https://github.com/Goodeye-Labs/goodeye-cli"
|
|
37
|
+
Issues = "https://github.com/Goodeye-Labs/goodeye-cli/issues"
|
|
38
|
+
|
|
39
|
+
[dependency-groups]
|
|
40
|
+
dev = [
|
|
41
|
+
"pytest>=8.3",
|
|
42
|
+
"pytest-asyncio>=0.23",
|
|
43
|
+
"pytest-cov>=5.0",
|
|
44
|
+
"respx>=0.21",
|
|
45
|
+
"ruff>=0.6",
|
|
46
|
+
"pyright>=1.1.380",
|
|
47
|
+
"pre-commit>=3.8",
|
|
48
|
+
"types-pyyaml>=6.0",
|
|
49
|
+
]
|
|
50
|
+
|
|
51
|
+
[build-system]
|
|
52
|
+
requires = ["hatchling>=1.25"]
|
|
53
|
+
build-backend = "hatchling.build"
|
|
54
|
+
|
|
55
|
+
[tool.hatch.build.targets.wheel]
|
|
56
|
+
packages = ["src/goodeye_cli"]
|
|
57
|
+
|
|
58
|
+
[tool.ruff]
|
|
59
|
+
line-length = 100
|
|
60
|
+
target-version = "py312"
|
|
61
|
+
|
|
62
|
+
[tool.ruff.lint]
|
|
63
|
+
select = ["E", "F", "I", "B", "UP", "SIM", "PL", "RUF"]
|
|
64
|
+
# PLR0913: too many args is OK for typer commands.
|
|
65
|
+
# PLC0415: non-top-level imports for lazy loading / testability.
|
|
66
|
+
# PLR2004: magic-number comparisons are common in tests and HTTP-status checks.
|
|
67
|
+
# B008: typer / FastAPI-style default-value calls are idiomatic.
|
|
68
|
+
ignore = ["PLR0913", "PLC0415", "PLR2004", "B008"]
|
|
69
|
+
|
|
70
|
+
[tool.pyright]
|
|
71
|
+
include = ["src", "tests"]
|
|
72
|
+
pythonVersion = "3.12"
|
|
73
|
+
typeCheckingMode = "standard"
|
|
74
|
+
reportMissingTypeStubs = false
|
|
75
|
+
|
|
76
|
+
[tool.pytest.ini_options]
|
|
77
|
+
asyncio_mode = "auto"
|
|
78
|
+
asyncio_default_fixture_loop_scope = "session"
|
|
79
|
+
asyncio_default_test_loop_scope = "session"
|
|
80
|
+
testpaths = ["tests"]
|
|
81
|
+
addopts = "-ra --strict-markers"
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"""Module entrypoint.
|
|
2
|
+
|
|
3
|
+
Enables ``python -m goodeye_cli`` and the ``goodeye`` console script.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
from goodeye_cli.app import app
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def main() -> None:
|
|
12
|
+
app()
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
if __name__ == "__main__":
|
|
16
|
+
main()
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"""Typer app root. Wires subcommands and a global error handler."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import sys
|
|
6
|
+
|
|
7
|
+
import typer
|
|
8
|
+
from rich.console import Console
|
|
9
|
+
|
|
10
|
+
from goodeye_cli import __version__
|
|
11
|
+
from goodeye_cli.commands import auth as auth_cmds
|
|
12
|
+
from goodeye_cli.commands import design as design_cmd
|
|
13
|
+
from goodeye_cli.commands import login as login_cmd
|
|
14
|
+
from goodeye_cli.commands import logout as logout_cmd
|
|
15
|
+
from goodeye_cli.commands import signup as signup_cmd
|
|
16
|
+
from goodeye_cli.commands import skills as skills_cmds
|
|
17
|
+
from goodeye_cli.commands import whoami as whoami_cmd
|
|
18
|
+
from goodeye_cli.errors import GoodeyeError
|
|
19
|
+
|
|
20
|
+
app = typer.Typer(
|
|
21
|
+
name="goodeye",
|
|
22
|
+
help="Public CLI for Goodeye - manage AI workflow skills from the terminal.",
|
|
23
|
+
no_args_is_help=True,
|
|
24
|
+
add_completion=False,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
# Top-level commands.
|
|
28
|
+
app.command("login")(login_cmd.login)
|
|
29
|
+
app.command("signup")(signup_cmd.signup)
|
|
30
|
+
app.command("logout")(logout_cmd.logout)
|
|
31
|
+
app.command("whoami")(whoami_cmd.whoami)
|
|
32
|
+
app.command("design")(design_cmd.design)
|
|
33
|
+
|
|
34
|
+
# Command groups.
|
|
35
|
+
app.add_typer(auth_cmds.app, name="auth", help="Manage API keys.")
|
|
36
|
+
app.add_typer(skills_cmds.app, name="skills", help="Browse and manage skills.")
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _version_callback(value: bool) -> None:
|
|
40
|
+
if value:
|
|
41
|
+
typer.echo(f"goodeye {__version__}")
|
|
42
|
+
raise typer.Exit()
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
@app.callback()
|
|
46
|
+
def _root(
|
|
47
|
+
version: bool = typer.Option(
|
|
48
|
+
False,
|
|
49
|
+
"--version",
|
|
50
|
+
callback=_version_callback,
|
|
51
|
+
is_eager=True,
|
|
52
|
+
help="Show the CLI version and exit.",
|
|
53
|
+
),
|
|
54
|
+
) -> None:
|
|
55
|
+
"""Global options processed before any subcommand."""
|
|
56
|
+
# Body intentionally empty; the callback fires only to register the option.
|
|
57
|
+
_ = version
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def main() -> None:
|
|
61
|
+
"""Console-script entrypoint with a structured-error-friendly wrapper."""
|
|
62
|
+
console = Console(stderr=True)
|
|
63
|
+
try:
|
|
64
|
+
app()
|
|
65
|
+
except GoodeyeError as exc:
|
|
66
|
+
console.print(f"[bold red]{exc.slug}[/bold red]: {exc.message}")
|
|
67
|
+
if exc.hint:
|
|
68
|
+
console.print(f"[dim]hint: {exc.hint}[/dim]")
|
|
69
|
+
sys.exit(1)
|