general-augment-cli 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.
- general_augment_cli-0.1.0/.gitignore +55 -0
- general_augment_cli-0.1.0/AGENTS.md +15 -0
- general_augment_cli-0.1.0/PKG-INFO +180 -0
- general_augment_cli-0.1.0/README.md +163 -0
- general_augment_cli-0.1.0/pyproject.toml +44 -0
- general_augment_cli-0.1.0/src/platform_cli/__init__.py +5 -0
- general_augment_cli-0.1.0/src/platform_cli/branding.py +27 -0
- general_augment_cli-0.1.0/src/platform_cli/client.py +179 -0
- general_augment_cli-0.1.0/src/platform_cli/commands/__init__.py +1 -0
- general_augment_cli-0.1.0/src/platform_cli/commands/approvals.py +150 -0
- general_augment_cli-0.1.0/src/platform_cli/commands/auth.py +96 -0
- general_augment_cli-0.1.0/src/platform_cli/commands/billing.py +143 -0
- general_augment_cli-0.1.0/src/platform_cli/commands/channels.py +212 -0
- general_augment_cli-0.1.0/src/platform_cli/commands/deploy.py +72 -0
- general_augment_cli-0.1.0/src/platform_cli/commands/dev.py +38 -0
- general_augment_cli-0.1.0/src/platform_cli/commands/doctor.py +170 -0
- general_augment_cli-0.1.0/src/platform_cli/commands/identity.py +433 -0
- general_augment_cli-0.1.0/src/platform_cli/commands/init.py +55 -0
- general_augment_cli-0.1.0/src/platform_cli/commands/integrate.py +94 -0
- general_augment_cli-0.1.0/src/platform_cli/commands/keys.py +116 -0
- general_augment_cli-0.1.0/src/platform_cli/commands/logs.py +43 -0
- general_augment_cli-0.1.0/src/platform_cli/commands/mcp.py +258 -0
- general_augment_cli-0.1.0/src/platform_cli/commands/memory.py +316 -0
- general_augment_cli-0.1.0/src/platform_cli/commands/mock.py +30 -0
- general_augment_cli-0.1.0/src/platform_cli/commands/model_providers.py +226 -0
- general_augment_cli-0.1.0/src/platform_cli/commands/observability.py +174 -0
- general_augment_cli-0.1.0/src/platform_cli/commands/onboarding.py +72 -0
- general_augment_cli-0.1.0/src/platform_cli/commands/projects.py +302 -0
- general_augment_cli-0.1.0/src/platform_cli/commands/skills.py +116 -0
- general_augment_cli-0.1.0/src/platform_cli/commands/smoke.py +280 -0
- general_augment_cli-0.1.0/src/platform_cli/commands/status.py +49 -0
- general_augment_cli-0.1.0/src/platform_cli/commands/tools.py +179 -0
- general_augment_cli-0.1.0/src/platform_cli/commands/users.py +150 -0
- general_augment_cli-0.1.0/src/platform_cli/commands/validate.py +96 -0
- general_augment_cli-0.1.0/src/platform_cli/commands/verify.py +648 -0
- general_augment_cli-0.1.0/src/platform_cli/config.py +114 -0
- general_augment_cli-0.1.0/src/platform_cli/errors.py +103 -0
- general_augment_cli-0.1.0/src/platform_cli/local_mock.py +1392 -0
- general_augment_cli-0.1.0/src/platform_cli/main.py +130 -0
- general_augment_cli-0.1.0/src/platform_cli/openapi.py +1048 -0
- general_augment_cli-0.1.0/src/platform_cli/output.py +47 -0
- general_augment_cli-0.1.0/src/platform_cli/readiness.py +176 -0
- general_augment_cli-0.1.0/src/platform_cli/runtime.py +22 -0
- general_augment_cli-0.1.0/tests/test_commands.py +3477 -0
- general_augment_cli-0.1.0/tests/test_config.py +90 -0
- general_augment_cli-0.1.0/uv.lock +420 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.so
|
|
5
|
+
.coverage
|
|
6
|
+
.mypy_cache/
|
|
7
|
+
.pytest_cache/
|
|
8
|
+
.ruff_cache/
|
|
9
|
+
.venv/
|
|
10
|
+
packages/cli/uv.lock
|
|
11
|
+
|
|
12
|
+
# Environment
|
|
13
|
+
.env
|
|
14
|
+
.env.local
|
|
15
|
+
.env.gcp
|
|
16
|
+
hermes-tenants/
|
|
17
|
+
|
|
18
|
+
# Secrets
|
|
19
|
+
*.pem
|
|
20
|
+
*.key
|
|
21
|
+
*.p12
|
|
22
|
+
*.pfx
|
|
23
|
+
.jks
|
|
24
|
+
service-account.json
|
|
25
|
+
.clerk/
|
|
26
|
+
|
|
27
|
+
# Docker
|
|
28
|
+
*.log
|
|
29
|
+
docker-data/
|
|
30
|
+
|
|
31
|
+
# IDE
|
|
32
|
+
.idea/
|
|
33
|
+
.vscode/
|
|
34
|
+
|
|
35
|
+
# Build
|
|
36
|
+
build/
|
|
37
|
+
dist/
|
|
38
|
+
*.egg-info/
|
|
39
|
+
node_modules/
|
|
40
|
+
.next/
|
|
41
|
+
dashboard/.vercel/
|
|
42
|
+
coverage/
|
|
43
|
+
playwright-report/
|
|
44
|
+
test-results/
|
|
45
|
+
*.tsbuildinfo
|
|
46
|
+
artifacts/
|
|
47
|
+
dashboard/artifacts/
|
|
48
|
+
|
|
49
|
+
# Kubernetes secrets
|
|
50
|
+
k8s/secrets/*
|
|
51
|
+
!k8s/secrets/.gitkeep
|
|
52
|
+
|
|
53
|
+
# OS
|
|
54
|
+
.DS_Store
|
|
55
|
+
.vercel
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# CLI Agent Instructions
|
|
2
|
+
|
|
3
|
+
These instructions apply under `packages/cli/`.
|
|
4
|
+
|
|
5
|
+
Inherit [`packages/AGENTS.md`](../AGENTS.md) and the repo root
|
|
6
|
+
[`AGENTS.md`](../../AGENTS.md).
|
|
7
|
+
|
|
8
|
+
## Scope
|
|
9
|
+
|
|
10
|
+
- The public CLI command is `genaug`.
|
|
11
|
+
- The primary manifest is `genaug-agent.yaml`.
|
|
12
|
+
- Help text, scaffolds, examples, and generated output should prefer General Augment
|
|
13
|
+
branding and omit runtime-selection fields.
|
|
14
|
+
- If CLI behavior changes, update `packages/cli/README.md`, docs under `docs/public/`,
|
|
15
|
+
docs-site CLI pages, and CLI tests in the same change.
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: general-augment-cli
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Standalone CLI for General Augment.
|
|
5
|
+
Author: General Augment
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Requires-Python: >=3.12
|
|
8
|
+
Requires-Dist: httpx>=0.27.0
|
|
9
|
+
Requires-Dist: pydantic>=2.7.0
|
|
10
|
+
Requires-Dist: pyyaml>=6.0.0
|
|
11
|
+
Requires-Dist: rich>=13.7.0
|
|
12
|
+
Requires-Dist: typer[all]>=0.12.0
|
|
13
|
+
Provides-Extra: dev
|
|
14
|
+
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
|
|
15
|
+
Requires-Dist: pytest>=8.0.0; extra == 'dev'
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
|
|
18
|
+
# General Augment CLI
|
|
19
|
+
|
|
20
|
+
Standalone developer CLI for General Augment.
|
|
21
|
+
|
|
22
|
+
During private beta, use the repo-local command prefix unless the published package is
|
|
23
|
+
available in your Python package index:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
uv run --project packages/cli genaug --version
|
|
27
|
+
uv run --project packages/cli genaug --help
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
When the package is available, the same commands work through the installed `genaug`
|
|
31
|
+
entrypoint:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
pip install general-augment-cli
|
|
35
|
+
genaug --version
|
|
36
|
+
genaug auth login --api-key gaadmlive...
|
|
37
|
+
genaug doctor
|
|
38
|
+
genaug projects list
|
|
39
|
+
genaug init dayplan-agent --tool web_search
|
|
40
|
+
genaug integrate https://petstore3.swagger.io/api/v3/openapi.json
|
|
41
|
+
genaug validate ./petstore-agent/genaug-agent.yaml
|
|
42
|
+
genaug deploy ./petstore-agent/genaug-agent.yaml
|
|
43
|
+
genaug keys create --project petstore-agent --name "Production backend"
|
|
44
|
+
genaug mock --host 127.0.0.1 --port 8787 --quiet
|
|
45
|
+
genaug smoke --idempotency-key smoke-replay-1 --metadata feature=spark
|
|
46
|
+
genaug smoke --project petstore-agent
|
|
47
|
+
genaug verify --project petstore-agent
|
|
48
|
+
genaug onboarding verify --project petstore-agent --json
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
If the package install fails during private beta, keep using
|
|
52
|
+
`uv run --project packages/cli genaug ...` from the General Augment repository instead
|
|
53
|
+
of assuming the package has shipped to your package index.
|
|
54
|
+
|
|
55
|
+
`genaug auth login` verifies the key against `/api/v1/admin/me` before writing local
|
|
56
|
+
config. The CLI stores auth at `~/.genaug/config.yaml` by default with owner-only file
|
|
57
|
+
permissions. Set
|
|
58
|
+
`GENAUG_CLI_CONFIG` to use a custom path.
|
|
59
|
+
|
|
60
|
+
Preferred environment overrides:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
export GENAUG_ADMIN_API_KEY=gaadmlive...
|
|
64
|
+
export GENAUG_ADMIN_BASE_URL=https://api.generalaugment.com
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
`GENAUG_API_KEY` and `GENAUG_API_BASE_URL` are also accepted, which keeps local
|
|
68
|
+
mock and SDK test scripts easy to share.
|
|
69
|
+
|
|
70
|
+
The generated manifest is `genaug-agent.yaml`. Use `genaug init <name>` when you want
|
|
71
|
+
a starter agent before an OpenAPI spec exists. Use
|
|
72
|
+
`genaug integrate <openapi-spec> --auto-deploy` when you want the CLI to create or
|
|
73
|
+
update the project and register the generated OpenAPI tools in one pass. Without
|
|
74
|
+
`--auto-deploy`, review the scaffold first, then run
|
|
75
|
+
`genaug validate ./<agent>/genaug-agent.yaml` and
|
|
76
|
+
`genaug deploy ./<agent>/genaug-agent.yaml`. `deploy` runs the same local validation
|
|
77
|
+
before calling the hosted API. Both scaffolds include
|
|
78
|
+
`CODING_AGENT_PROMPT.md`, which is the paste-ready backend handoff for a coding agent.
|
|
79
|
+
|
|
80
|
+
## Common workflows
|
|
81
|
+
|
|
82
|
+
- Auth: `genaug auth login`, `genaug auth whoami`, `genaug auth logout`
|
|
83
|
+
- Starter scaffold: `genaug init <name> --tool web_search`
|
|
84
|
+
- Local config validation: `genaug validate ./genaug-agent.yaml --json`
|
|
85
|
+
- Projects: `genaug projects list`, `genaug projects create`, `genaug projects usage`,
|
|
86
|
+
`genaug projects runtime-policy`, `genaug projects export`, `genaug projects archive`
|
|
87
|
+
- API keys: `genaug keys create`, `genaug keys list`, `genaug keys update`,
|
|
88
|
+
`genaug keys revoke`
|
|
89
|
+
- Skills, tools, and channels: `genaug skills list`, `genaug skills view`,
|
|
90
|
+
`genaug skills apply`, `genaug skills delete`, `genaug tools list`, `genaug tools toggle`,
|
|
91
|
+
`genaug tools discovery`, `genaug channels status`, `genaug channels connect`,
|
|
92
|
+
`genaug channels test`, `genaug channels disconnect`. Telegram supports connect,
|
|
93
|
+
test, and disconnect; WhatsApp/SMS support sender configuration and clearing.
|
|
94
|
+
- MCP servers: `genaug mcp list`, `genaug mcp add`, `genaug mcp test`,
|
|
95
|
+
`genaug mcp delete`. Use exactly one transport per server: `--url` for HTTP
|
|
96
|
+
endpoints or `--command` for stdio servers.
|
|
97
|
+
- Model providers: `genaug model-providers list`, `genaug model-providers set`,
|
|
98
|
+
`genaug model-providers health`, `genaug model-providers revoke`
|
|
99
|
+
- Billing: `genaug billing checkout`, `genaug billing portal`,
|
|
100
|
+
`genaug billing events`
|
|
101
|
+
- Memory: `genaug memory store`, `genaug memory search`, `genaug memory profile`,
|
|
102
|
+
`genaug memory delete`, `genaug memory purge-user`
|
|
103
|
+
- Users and identity: `genaug users list`, `genaug users detail`,
|
|
104
|
+
`genaug users delete`, `genaug identity list`, `genaug identity create-test`,
|
|
105
|
+
`genaug identity link-user`, `genaug identity verification-code`,
|
|
106
|
+
`genaug identity magic-link`, `genaug identity verify`,
|
|
107
|
+
`genaug identity resolve`, `genaug identity unlink`
|
|
108
|
+
- Observability: `genaug observability trace`, `genaug observability support-bundle`
|
|
109
|
+
- Approvals: `genaug approvals list`, `genaug approvals approve`, `genaug approvals deny`
|
|
110
|
+
- Operations: `genaug doctor`, `genaug status`, `genaug logs`
|
|
111
|
+
- App smoke checks: `genaug smoke --message "Reply exactly with: ok"`,
|
|
112
|
+
`genaug smoke --structured`, `genaug smoke --json`
|
|
113
|
+
- Project acceptance checks: `genaug verify --project <project-slug>`, which checks
|
|
114
|
+
project keys, hosted agent test, tools, logs, usage, usage limits, observability,
|
|
115
|
+
runtime policy model routing, memory lifecycle, and tool-call audit before printing
|
|
116
|
+
dashboard URLs for the same tenant.
|
|
117
|
+
- One-command onboarding gate: `genaug onboarding verify --project <project-slug> --json`,
|
|
118
|
+
which wraps the same project checks with CLI/API version metadata and a coding-agent
|
|
119
|
+
friendly ready/blocked payload.
|
|
120
|
+
- Local development: `genaug dev ./genaug-agent.yaml --message "Hello"`
|
|
121
|
+
- Local mock testing: `genaug mock --host 127.0.0.1 --port 8787 --quiet`
|
|
122
|
+
|
|
123
|
+
## Billing
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
genaug billing checkout --project dayplan-agent --tier pro
|
|
127
|
+
genaug billing portal --project dayplan-agent
|
|
128
|
+
genaug billing events --project dayplan-agent --json
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Use these commands for hosted billing actions when Stripe is configured for the
|
|
132
|
+
project. `checkout` returns a hosted Stripe Checkout URL for Pro or Team, `portal`
|
|
133
|
+
returns a hosted Stripe Customer Portal URL for linked customers, and `events` lists
|
|
134
|
+
stored Stripe webhook events such as checkout completion, invoice payment, and payment
|
|
135
|
+
failure. These commands do not create Stripe products, prices, or webhooks directly;
|
|
136
|
+
those stay in the server-side billing setup and readiness flow.
|
|
137
|
+
|
|
138
|
+
For a full CLI-to-dashboard onboarding proof from this repository, run:
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
make app-developer-onboarding-smoke
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
That harness creates a fresh dummy tenant from a richer OpenAPI fixture, proves
|
|
145
|
+
generated tool governance, deploys SOUL.md and skills, sends real `/v1/responses`
|
|
146
|
+
smokes for multiple app users, runs `genaug verify --json`, starts an owned dashboard
|
|
147
|
+
dev server, and writes JSON evidence plus screenshots for the project overview, skills,
|
|
148
|
+
tools, integrate, and analytics pages. Add `GENAUG_DASHBOARD_SMOKE_ARCHIVE_PROJECT=1`
|
|
149
|
+
when CI should archive the created smoke project after the artifact is captured.
|
|
150
|
+
|
|
151
|
+
`genaug smoke` checks `/health/ready` and sends one project-keyed `/v1/responses`
|
|
152
|
+
request using bearer auth. Use `--idempotency-key`, `--request-id`, `--traceparent`,
|
|
153
|
+
and repeated `--metadata key=value` flags when you need replayable support/debug
|
|
154
|
+
evidence from hosted API or the local mock. Use `--project <project-slug>` when the
|
|
155
|
+
configured key is a management key and the app-facing request needs `X-Project-ID`.
|
|
156
|
+
Use `--structured` to request the default `json_schema` smoke response, or
|
|
157
|
+
`--schema-file ./schema.json` to verify an app-specific structured-output contract.
|
|
158
|
+
With `--json`, smoke output includes the `/health/ready` payload, the full
|
|
159
|
+
`/v1/responses` object, `response_id`, `request_id`, and `trace_id` so automation can
|
|
160
|
+
prove health and tracing from one command.
|
|
161
|
+
|
|
162
|
+
When the API returns a rate-limit `429`, the CLI prints the stable reason and
|
|
163
|
+
`Retry-After` timing when the platform includes them.
|
|
164
|
+
|
|
165
|
+
`genaug doctor` checks the resolved config path, base URL, API key presence,
|
|
166
|
+
`/health/ready`, and `/api/v1/admin/me` without printing secret values. Run it before
|
|
167
|
+
`integrate` when a new developer is unsure whether local auth or network setup is the
|
|
168
|
+
problem.
|
|
169
|
+
|
|
170
|
+
`genaug mock` runs the deterministic local HTTP mock. Use it for offline app contract tests against
|
|
171
|
+
`/v1/responses`, memory routes, project setup, OpenAPI tool registration, key
|
|
172
|
+
management, logs, usage, observability, health checks, idempotency replays, trace
|
|
173
|
+
metadata, structured-output fixtures, and semantic SSE fixtures.
|
|
174
|
+
|
|
175
|
+
The console commands are defined in `pyproject.toml`:
|
|
176
|
+
|
|
177
|
+
```toml
|
|
178
|
+
[project.scripts]
|
|
179
|
+
genaug = "platform_cli.main:app"
|
|
180
|
+
```
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# General Augment CLI
|
|
2
|
+
|
|
3
|
+
Standalone developer CLI for General Augment.
|
|
4
|
+
|
|
5
|
+
During private beta, use the repo-local command prefix unless the published package is
|
|
6
|
+
available in your Python package index:
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
uv run --project packages/cli genaug --version
|
|
10
|
+
uv run --project packages/cli genaug --help
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
When the package is available, the same commands work through the installed `genaug`
|
|
14
|
+
entrypoint:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pip install general-augment-cli
|
|
18
|
+
genaug --version
|
|
19
|
+
genaug auth login --api-key gaadmlive...
|
|
20
|
+
genaug doctor
|
|
21
|
+
genaug projects list
|
|
22
|
+
genaug init dayplan-agent --tool web_search
|
|
23
|
+
genaug integrate https://petstore3.swagger.io/api/v3/openapi.json
|
|
24
|
+
genaug validate ./petstore-agent/genaug-agent.yaml
|
|
25
|
+
genaug deploy ./petstore-agent/genaug-agent.yaml
|
|
26
|
+
genaug keys create --project petstore-agent --name "Production backend"
|
|
27
|
+
genaug mock --host 127.0.0.1 --port 8787 --quiet
|
|
28
|
+
genaug smoke --idempotency-key smoke-replay-1 --metadata feature=spark
|
|
29
|
+
genaug smoke --project petstore-agent
|
|
30
|
+
genaug verify --project petstore-agent
|
|
31
|
+
genaug onboarding verify --project petstore-agent --json
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
If the package install fails during private beta, keep using
|
|
35
|
+
`uv run --project packages/cli genaug ...` from the General Augment repository instead
|
|
36
|
+
of assuming the package has shipped to your package index.
|
|
37
|
+
|
|
38
|
+
`genaug auth login` verifies the key against `/api/v1/admin/me` before writing local
|
|
39
|
+
config. The CLI stores auth at `~/.genaug/config.yaml` by default with owner-only file
|
|
40
|
+
permissions. Set
|
|
41
|
+
`GENAUG_CLI_CONFIG` to use a custom path.
|
|
42
|
+
|
|
43
|
+
Preferred environment overrides:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
export GENAUG_ADMIN_API_KEY=gaadmlive...
|
|
47
|
+
export GENAUG_ADMIN_BASE_URL=https://api.generalaugment.com
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
`GENAUG_API_KEY` and `GENAUG_API_BASE_URL` are also accepted, which keeps local
|
|
51
|
+
mock and SDK test scripts easy to share.
|
|
52
|
+
|
|
53
|
+
The generated manifest is `genaug-agent.yaml`. Use `genaug init <name>` when you want
|
|
54
|
+
a starter agent before an OpenAPI spec exists. Use
|
|
55
|
+
`genaug integrate <openapi-spec> --auto-deploy` when you want the CLI to create or
|
|
56
|
+
update the project and register the generated OpenAPI tools in one pass. Without
|
|
57
|
+
`--auto-deploy`, review the scaffold first, then run
|
|
58
|
+
`genaug validate ./<agent>/genaug-agent.yaml` and
|
|
59
|
+
`genaug deploy ./<agent>/genaug-agent.yaml`. `deploy` runs the same local validation
|
|
60
|
+
before calling the hosted API. Both scaffolds include
|
|
61
|
+
`CODING_AGENT_PROMPT.md`, which is the paste-ready backend handoff for a coding agent.
|
|
62
|
+
|
|
63
|
+
## Common workflows
|
|
64
|
+
|
|
65
|
+
- Auth: `genaug auth login`, `genaug auth whoami`, `genaug auth logout`
|
|
66
|
+
- Starter scaffold: `genaug init <name> --tool web_search`
|
|
67
|
+
- Local config validation: `genaug validate ./genaug-agent.yaml --json`
|
|
68
|
+
- Projects: `genaug projects list`, `genaug projects create`, `genaug projects usage`,
|
|
69
|
+
`genaug projects runtime-policy`, `genaug projects export`, `genaug projects archive`
|
|
70
|
+
- API keys: `genaug keys create`, `genaug keys list`, `genaug keys update`,
|
|
71
|
+
`genaug keys revoke`
|
|
72
|
+
- Skills, tools, and channels: `genaug skills list`, `genaug skills view`,
|
|
73
|
+
`genaug skills apply`, `genaug skills delete`, `genaug tools list`, `genaug tools toggle`,
|
|
74
|
+
`genaug tools discovery`, `genaug channels status`, `genaug channels connect`,
|
|
75
|
+
`genaug channels test`, `genaug channels disconnect`. Telegram supports connect,
|
|
76
|
+
test, and disconnect; WhatsApp/SMS support sender configuration and clearing.
|
|
77
|
+
- MCP servers: `genaug mcp list`, `genaug mcp add`, `genaug mcp test`,
|
|
78
|
+
`genaug mcp delete`. Use exactly one transport per server: `--url` for HTTP
|
|
79
|
+
endpoints or `--command` for stdio servers.
|
|
80
|
+
- Model providers: `genaug model-providers list`, `genaug model-providers set`,
|
|
81
|
+
`genaug model-providers health`, `genaug model-providers revoke`
|
|
82
|
+
- Billing: `genaug billing checkout`, `genaug billing portal`,
|
|
83
|
+
`genaug billing events`
|
|
84
|
+
- Memory: `genaug memory store`, `genaug memory search`, `genaug memory profile`,
|
|
85
|
+
`genaug memory delete`, `genaug memory purge-user`
|
|
86
|
+
- Users and identity: `genaug users list`, `genaug users detail`,
|
|
87
|
+
`genaug users delete`, `genaug identity list`, `genaug identity create-test`,
|
|
88
|
+
`genaug identity link-user`, `genaug identity verification-code`,
|
|
89
|
+
`genaug identity magic-link`, `genaug identity verify`,
|
|
90
|
+
`genaug identity resolve`, `genaug identity unlink`
|
|
91
|
+
- Observability: `genaug observability trace`, `genaug observability support-bundle`
|
|
92
|
+
- Approvals: `genaug approvals list`, `genaug approvals approve`, `genaug approvals deny`
|
|
93
|
+
- Operations: `genaug doctor`, `genaug status`, `genaug logs`
|
|
94
|
+
- App smoke checks: `genaug smoke --message "Reply exactly with: ok"`,
|
|
95
|
+
`genaug smoke --structured`, `genaug smoke --json`
|
|
96
|
+
- Project acceptance checks: `genaug verify --project <project-slug>`, which checks
|
|
97
|
+
project keys, hosted agent test, tools, logs, usage, usage limits, observability,
|
|
98
|
+
runtime policy model routing, memory lifecycle, and tool-call audit before printing
|
|
99
|
+
dashboard URLs for the same tenant.
|
|
100
|
+
- One-command onboarding gate: `genaug onboarding verify --project <project-slug> --json`,
|
|
101
|
+
which wraps the same project checks with CLI/API version metadata and a coding-agent
|
|
102
|
+
friendly ready/blocked payload.
|
|
103
|
+
- Local development: `genaug dev ./genaug-agent.yaml --message "Hello"`
|
|
104
|
+
- Local mock testing: `genaug mock --host 127.0.0.1 --port 8787 --quiet`
|
|
105
|
+
|
|
106
|
+
## Billing
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
genaug billing checkout --project dayplan-agent --tier pro
|
|
110
|
+
genaug billing portal --project dayplan-agent
|
|
111
|
+
genaug billing events --project dayplan-agent --json
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Use these commands for hosted billing actions when Stripe is configured for the
|
|
115
|
+
project. `checkout` returns a hosted Stripe Checkout URL for Pro or Team, `portal`
|
|
116
|
+
returns a hosted Stripe Customer Portal URL for linked customers, and `events` lists
|
|
117
|
+
stored Stripe webhook events such as checkout completion, invoice payment, and payment
|
|
118
|
+
failure. These commands do not create Stripe products, prices, or webhooks directly;
|
|
119
|
+
those stay in the server-side billing setup and readiness flow.
|
|
120
|
+
|
|
121
|
+
For a full CLI-to-dashboard onboarding proof from this repository, run:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
make app-developer-onboarding-smoke
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
That harness creates a fresh dummy tenant from a richer OpenAPI fixture, proves
|
|
128
|
+
generated tool governance, deploys SOUL.md and skills, sends real `/v1/responses`
|
|
129
|
+
smokes for multiple app users, runs `genaug verify --json`, starts an owned dashboard
|
|
130
|
+
dev server, and writes JSON evidence plus screenshots for the project overview, skills,
|
|
131
|
+
tools, integrate, and analytics pages. Add `GENAUG_DASHBOARD_SMOKE_ARCHIVE_PROJECT=1`
|
|
132
|
+
when CI should archive the created smoke project after the artifact is captured.
|
|
133
|
+
|
|
134
|
+
`genaug smoke` checks `/health/ready` and sends one project-keyed `/v1/responses`
|
|
135
|
+
request using bearer auth. Use `--idempotency-key`, `--request-id`, `--traceparent`,
|
|
136
|
+
and repeated `--metadata key=value` flags when you need replayable support/debug
|
|
137
|
+
evidence from hosted API or the local mock. Use `--project <project-slug>` when the
|
|
138
|
+
configured key is a management key and the app-facing request needs `X-Project-ID`.
|
|
139
|
+
Use `--structured` to request the default `json_schema` smoke response, or
|
|
140
|
+
`--schema-file ./schema.json` to verify an app-specific structured-output contract.
|
|
141
|
+
With `--json`, smoke output includes the `/health/ready` payload, the full
|
|
142
|
+
`/v1/responses` object, `response_id`, `request_id`, and `trace_id` so automation can
|
|
143
|
+
prove health and tracing from one command.
|
|
144
|
+
|
|
145
|
+
When the API returns a rate-limit `429`, the CLI prints the stable reason and
|
|
146
|
+
`Retry-After` timing when the platform includes them.
|
|
147
|
+
|
|
148
|
+
`genaug doctor` checks the resolved config path, base URL, API key presence,
|
|
149
|
+
`/health/ready`, and `/api/v1/admin/me` without printing secret values. Run it before
|
|
150
|
+
`integrate` when a new developer is unsure whether local auth or network setup is the
|
|
151
|
+
problem.
|
|
152
|
+
|
|
153
|
+
`genaug mock` runs the deterministic local HTTP mock. Use it for offline app contract tests against
|
|
154
|
+
`/v1/responses`, memory routes, project setup, OpenAPI tool registration, key
|
|
155
|
+
management, logs, usage, observability, health checks, idempotency replays, trace
|
|
156
|
+
metadata, structured-output fixtures, and semantic SSE fixtures.
|
|
157
|
+
|
|
158
|
+
The console commands are defined in `pyproject.toml`:
|
|
159
|
+
|
|
160
|
+
```toml
|
|
161
|
+
[project.scripts]
|
|
162
|
+
genaug = "platform_cli.main:app"
|
|
163
|
+
```
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling>=1.24.0"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "general-augment-cli"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Standalone CLI for General Augment."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.12"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
authors = [{ name = "General Augment" }]
|
|
13
|
+
dependencies = [
|
|
14
|
+
"typer[all]>=0.12.0",
|
|
15
|
+
"httpx>=0.27.0",
|
|
16
|
+
"rich>=13.7.0",
|
|
17
|
+
"pyyaml>=6.0.0",
|
|
18
|
+
"pydantic>=2.7.0",
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
[project.optional-dependencies]
|
|
22
|
+
dev = [
|
|
23
|
+
"pytest>=8.0.0",
|
|
24
|
+
"pytest-asyncio>=0.23.0",
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
[project.scripts]
|
|
28
|
+
genaug = "platform_cli.main:app"
|
|
29
|
+
|
|
30
|
+
[tool.hatch.build.targets.wheel]
|
|
31
|
+
packages = ["src/platform_cli"]
|
|
32
|
+
|
|
33
|
+
[tool.ruff]
|
|
34
|
+
target-version = "py312"
|
|
35
|
+
line-length = 100
|
|
36
|
+
|
|
37
|
+
[tool.ruff.lint]
|
|
38
|
+
select = ["E", "F", "I", "N", "UP", "ASYNC", "B", "C4", "G", "RUF"]
|
|
39
|
+
|
|
40
|
+
[tool.mypy]
|
|
41
|
+
python_version = "3.12"
|
|
42
|
+
strict = true
|
|
43
|
+
warn_return_any = true
|
|
44
|
+
warn_unused_ignores = true
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""Small branding model for standalone CLI copy."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
|
|
7
|
+
from pydantic import BaseModel, Field
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class Branding(BaseModel):
|
|
11
|
+
"""User-facing CLI branding loaded from environment variables."""
|
|
12
|
+
|
|
13
|
+
product_name: str = Field(
|
|
14
|
+
default_factory=lambda: os.getenv("BRAND_PRODUCT_NAME", "General Augment"),
|
|
15
|
+
)
|
|
16
|
+
product_slug: str = Field(
|
|
17
|
+
default_factory=lambda: os.getenv("BRAND_PRODUCT_SLUG", "general-augment"),
|
|
18
|
+
)
|
|
19
|
+
docs_url: str = Field(
|
|
20
|
+
default_factory=lambda: os.getenv("BRAND_DOCS_URL", "https://docs.generalaugment.com"),
|
|
21
|
+
)
|
|
22
|
+
api_key_prefix: str = Field(default_factory=lambda: os.getenv("BRAND_API_KEY_PREFIX", "gaadm"))
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def get_branding() -> Branding:
|
|
26
|
+
"""Return current process branding."""
|
|
27
|
+
return Branding()
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
"""Thin HTTP client for the standalone CLI."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from collections.abc import Mapping
|
|
6
|
+
from typing import Any
|
|
7
|
+
from urllib.parse import quote
|
|
8
|
+
|
|
9
|
+
import httpx
|
|
10
|
+
|
|
11
|
+
from platform_cli.config import CLIConfig
|
|
12
|
+
from platform_cli.errors import APIError, CLIError
|
|
13
|
+
|
|
14
|
+
ADMIN_PREFIX = "/api/v1/admin"
|
|
15
|
+
INTEGRATIONS_PREFIX = "/api/v1/integrations"
|
|
16
|
+
REQUEST_TIMEOUT_SECONDS = 30.0
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class PlatformClient:
|
|
20
|
+
"""Synchronous HTTP client for platform admin and public endpoints."""
|
|
21
|
+
|
|
22
|
+
def __init__(self, config: CLIConfig, *, timeout: float = REQUEST_TIMEOUT_SECONDS) -> None:
|
|
23
|
+
"""Initialize the client from CLI config."""
|
|
24
|
+
self.config = config
|
|
25
|
+
self.base_url = config.base_url.rstrip("/")
|
|
26
|
+
self.timeout = timeout
|
|
27
|
+
self._client = httpx.Client(timeout=timeout)
|
|
28
|
+
|
|
29
|
+
def close(self) -> None:
|
|
30
|
+
"""Close the underlying HTTP client."""
|
|
31
|
+
self._client.close()
|
|
32
|
+
|
|
33
|
+
def __enter__(self) -> PlatformClient:
|
|
34
|
+
"""Return this client in context managers."""
|
|
35
|
+
return self
|
|
36
|
+
|
|
37
|
+
def __exit__(self, *_: object) -> None:
|
|
38
|
+
"""Close this client."""
|
|
39
|
+
self.close()
|
|
40
|
+
|
|
41
|
+
def admin(
|
|
42
|
+
self,
|
|
43
|
+
method: str,
|
|
44
|
+
path: str,
|
|
45
|
+
*,
|
|
46
|
+
json: Mapping[str, Any] | None = None,
|
|
47
|
+
params: Mapping[str, Any] | None = None,
|
|
48
|
+
) -> Any:
|
|
49
|
+
"""Call an admin API endpoint."""
|
|
50
|
+
if not self.config.api_key:
|
|
51
|
+
raise CLIError("No API key configured. Run genaug auth login first.")
|
|
52
|
+
return self._request(
|
|
53
|
+
method,
|
|
54
|
+
f"{ADMIN_PREFIX}{path}",
|
|
55
|
+
json=json,
|
|
56
|
+
params=params,
|
|
57
|
+
authenticated=True,
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
def public(
|
|
61
|
+
self,
|
|
62
|
+
method: str,
|
|
63
|
+
path: str,
|
|
64
|
+
*,
|
|
65
|
+
params: Mapping[str, Any] | None = None,
|
|
66
|
+
) -> Any:
|
|
67
|
+
"""Call a public API endpoint."""
|
|
68
|
+
return self._request(method, path, params=params, authenticated=False)
|
|
69
|
+
|
|
70
|
+
def integrations(
|
|
71
|
+
self,
|
|
72
|
+
method: str,
|
|
73
|
+
path: str,
|
|
74
|
+
*,
|
|
75
|
+
json: Mapping[str, Any] | None = None,
|
|
76
|
+
params: Mapping[str, Any] | None = None,
|
|
77
|
+
) -> Any:
|
|
78
|
+
"""Call an app-integration endpoint with admin API-key auth."""
|
|
79
|
+
if not self.config.api_key:
|
|
80
|
+
raise CLIError("No API key configured. Run genaug auth login first.")
|
|
81
|
+
return self._request(
|
|
82
|
+
method,
|
|
83
|
+
f"{INTEGRATIONS_PREFIX}{path}",
|
|
84
|
+
json=json,
|
|
85
|
+
params=params,
|
|
86
|
+
authenticated=True,
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
def app(
|
|
90
|
+
self,
|
|
91
|
+
method: str,
|
|
92
|
+
path: str,
|
|
93
|
+
*,
|
|
94
|
+
json: Mapping[str, Any] | None = None,
|
|
95
|
+
params: Mapping[str, Any] | None = None,
|
|
96
|
+
headers: Mapping[str, str] | None = None,
|
|
97
|
+
) -> Any:
|
|
98
|
+
"""Call an app-facing endpoint using bearer auth."""
|
|
99
|
+
if not self.config.api_key:
|
|
100
|
+
raise CLIError("No API key configured. Run genaug auth login first.")
|
|
101
|
+
return self._request(
|
|
102
|
+
method,
|
|
103
|
+
path,
|
|
104
|
+
json=json,
|
|
105
|
+
params=params,
|
|
106
|
+
extra_headers=headers,
|
|
107
|
+
authenticated=True,
|
|
108
|
+
auth_mode="bearer",
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
def _request(
|
|
112
|
+
self,
|
|
113
|
+
method: str,
|
|
114
|
+
path: str,
|
|
115
|
+
*,
|
|
116
|
+
json: Mapping[str, Any] | None = None,
|
|
117
|
+
params: Mapping[str, Any] | None = None,
|
|
118
|
+
extra_headers: Mapping[str, str] | None = None,
|
|
119
|
+
authenticated: bool,
|
|
120
|
+
auth_mode: str = "admin",
|
|
121
|
+
) -> Any:
|
|
122
|
+
"""Send one request and decode the response."""
|
|
123
|
+
headers: dict[str, str] = {}
|
|
124
|
+
if authenticated and self.config.api_key:
|
|
125
|
+
if auth_mode == "bearer":
|
|
126
|
+
headers["Authorization"] = f"Bearer {self.config.api_key}"
|
|
127
|
+
else:
|
|
128
|
+
headers["X-Admin-Key"] = self.config.api_key
|
|
129
|
+
headers.update(dict(extra_headers or {}))
|
|
130
|
+
try:
|
|
131
|
+
response = self._client.request(
|
|
132
|
+
method,
|
|
133
|
+
f"{self.base_url}{path}",
|
|
134
|
+
headers=headers,
|
|
135
|
+
json=dict(json) if json is not None else None,
|
|
136
|
+
params=dict(params) if params is not None else None,
|
|
137
|
+
)
|
|
138
|
+
except (httpx.ConnectError, httpx.TimeoutException, httpx.RequestError) as exc:
|
|
139
|
+
raise CLIError(f"Could not reach the platform API at {self.base_url}: {exc}") from exc
|
|
140
|
+
if response.status_code >= 400:
|
|
141
|
+
raise APIError(response.status_code, _error_detail(response), response.headers)
|
|
142
|
+
if not response.content:
|
|
143
|
+
return None
|
|
144
|
+
try:
|
|
145
|
+
return response.json()
|
|
146
|
+
except ValueError as exc:
|
|
147
|
+
if authenticated:
|
|
148
|
+
raise CLIError(
|
|
149
|
+
"Platform API returned malformed JSON for an authenticated request."
|
|
150
|
+
) from exc
|
|
151
|
+
return response.text
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def resolve_project(client: PlatformClient, project_ref: str) -> dict[str, Any]:
|
|
155
|
+
"""Resolve a project by id, slug, or name."""
|
|
156
|
+
payload = client.admin("GET", "/projects")
|
|
157
|
+
items = payload.get("items", []) if isinstance(payload, dict) else []
|
|
158
|
+
for item in items:
|
|
159
|
+
if not isinstance(item, dict):
|
|
160
|
+
continue
|
|
161
|
+
if project_ref in {str(item.get("id")), str(item.get("slug")), str(item.get("name"))}:
|
|
162
|
+
return item
|
|
163
|
+
raise CLIError(f"Project not found: {project_ref}")
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def encode_path_segment(value: str) -> str:
|
|
167
|
+
"""Encode one path segment for safe URL interpolation."""
|
|
168
|
+
return quote(value, safe="")
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
def _error_detail(response: httpx.Response) -> Any:
|
|
172
|
+
"""Extract one error detail from an HTTP response."""
|
|
173
|
+
try:
|
|
174
|
+
payload = response.json()
|
|
175
|
+
except ValueError:
|
|
176
|
+
return response.text
|
|
177
|
+
if isinstance(payload, dict):
|
|
178
|
+
return payload.get("detail") or payload
|
|
179
|
+
return payload
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Typer command modules for the standalone CLI."""
|