expedait-cli 0.2.2__tar.gz → 0.4.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.
- expedait_cli-0.4.0/CHANGELOG.md +92 -0
- expedait_cli-0.4.0/PKG-INFO +301 -0
- expedait_cli-0.4.0/README.md +290 -0
- expedait_cli-0.4.0/expedait_cli/client.py +411 -0
- expedait_cli-0.4.0/expedait_cli/commands/comments.py +146 -0
- expedait_cli-0.4.0/expedait_cli/commands/context_cmd.py +160 -0
- expedait_cli-0.4.0/expedait_cli/commands/deliverables.py +524 -0
- expedait_cli-0.4.0/expedait_cli/commands/objectives.py +62 -0
- expedait_cli-0.4.0/expedait_cli/commands/processes.py +603 -0
- {expedait_cli-0.2.2 → expedait_cli-0.4.0}/expedait_cli/commands/projects.py +25 -4
- expedait_cli-0.4.0/expedait_cli/commands/review.py +81 -0
- expedait_cli-0.4.0/expedait_cli/commands/roles.py +196 -0
- {expedait_cli-0.2.2 → expedait_cli-0.4.0}/expedait_cli/main.py +14 -2
- expedait_cli-0.4.0/expedait_cli/ops.py +203 -0
- {expedait_cli-0.2.2 → expedait_cli-0.4.0}/pyproject.toml +4 -2
- {expedait_cli-0.2.2 → expedait_cli-0.4.0}/tests/test_client.py +60 -2
- expedait_cli-0.4.0/tests/test_commands/test_comments.py +122 -0
- expedait_cli-0.4.0/tests/test_commands/test_context.py +32 -0
- expedait_cli-0.4.0/tests/test_commands/test_context_files.py +140 -0
- expedait_cli-0.4.0/tests/test_commands/test_deliverables.py +141 -0
- expedait_cli-0.4.0/tests/test_commands/test_deliverables_write.py +203 -0
- expedait_cli-0.4.0/tests/test_commands/test_objectives.py +49 -0
- expedait_cli-0.4.0/tests/test_commands/test_processes.py +174 -0
- {expedait_cli-0.2.2 → expedait_cli-0.4.0}/tests/test_commands/test_projects.py +37 -16
- expedait_cli-0.4.0/tests/test_commands/test_review.py +62 -0
- expedait_cli-0.4.0/tests/test_commands/test_roles.py +90 -0
- {expedait_cli-0.2.2 → expedait_cli-0.4.0}/uv.lock +1 -1
- expedait_cli-0.2.2/PKG-INFO +0 -153
- expedait_cli-0.2.2/README.md +0 -142
- expedait_cli-0.2.2/expedait_cli/client.py +0 -134
- expedait_cli-0.2.2/expedait_cli/commands/comments.py +0 -102
- expedait_cli-0.2.2/expedait_cli/commands/pages.py +0 -110
- expedait_cli-0.2.2/tests/test_commands/test_comments.py +0 -138
- expedait_cli-0.2.2/tests/test_commands/test_pages.py +0 -153
- {expedait_cli-0.2.2 → expedait_cli-0.4.0}/.github/workflows/ci.yml +0 -0
- {expedait_cli-0.2.2 → expedait_cli-0.4.0}/.github/workflows/publish.yml +0 -0
- {expedait_cli-0.2.2 → expedait_cli-0.4.0}/.gitignore +0 -0
- {expedait_cli-0.2.2 → expedait_cli-0.4.0}/CLAUDE.md +0 -0
- {expedait_cli-0.2.2 → expedait_cli-0.4.0}/LICENSE +0 -0
- {expedait_cli-0.2.2 → expedait_cli-0.4.0}/expedait_cli/__init__.py +0 -0
- {expedait_cli-0.2.2 → expedait_cli-0.4.0}/expedait_cli/auth.py +0 -0
- {expedait_cli-0.2.2 → expedait_cli-0.4.0}/expedait_cli/commands/__init__.py +0 -0
- {expedait_cli-0.2.2 → expedait_cli-0.4.0}/expedait_cli/commands/auth_cmd.py +0 -0
- {expedait_cli-0.2.2 → expedait_cli-0.4.0}/expedait_cli/commands/init_cmd.py +0 -0
- {expedait_cli-0.2.2 → expedait_cli-0.4.0}/expedait_cli/config.py +0 -0
- {expedait_cli-0.2.2 → expedait_cli-0.4.0}/expedait_cli/formatters.py +0 -0
- {expedait_cli-0.2.2 → expedait_cli-0.4.0}/expedait_cli/settings.py +0 -0
- {expedait_cli-0.2.2 → expedait_cli-0.4.0}/tests/__init__.py +0 -0
- {expedait_cli-0.2.2 → expedait_cli-0.4.0}/tests/conftest.py +0 -0
- {expedait_cli-0.2.2 → expedait_cli-0.4.0}/tests/test_auth.py +0 -0
- {expedait_cli-0.2.2 → expedait_cli-0.4.0}/tests/test_commands/__init__.py +0 -0
- {expedait_cli-0.2.2 → expedait_cli-0.4.0}/tests/test_commands/test_auth_cmd.py +0 -0
- {expedait_cli-0.2.2 → expedait_cli-0.4.0}/tests/test_commands/test_init_cmd.py +0 -0
- {expedait_cli-0.2.2 → expedait_cli-0.4.0}/tests/test_config.py +0 -0
- {expedait_cli-0.2.2 → expedait_cli-0.4.0}/tests/test_settings.py +0 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.4.0
|
|
4
|
+
|
|
5
|
+
Bring the CLI to parity with the hosted MCP server's write surface — agents can
|
|
6
|
+
now create and adapt content, processes, and roles, not just read them. Every
|
|
7
|
+
new command supports `--format json` and reports a per-op summary.
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
- **Deliverable writes** (mirror MCP `write_deliverable`):
|
|
11
|
+
- `deliverables write --ops @file.json` — ordered batch of `create` / `edit` /
|
|
12
|
+
`rename` / `save_version` / `set_state` ops, chainable with `id="$last"` or
|
|
13
|
+
named refs (`ref="x"` on create, `id="@x"` later). Pre-flight validates op
|
|
14
|
+
shape and reference ordering; ops stop on first failure (rest `skipped`) and
|
|
15
|
+
the command exits non-zero on partial failure.
|
|
16
|
+
- Ergonomic subcommands on top: `deliverables create`, `edit`, `rename`,
|
|
17
|
+
`save-version`, `set-state` (states: Not Started, In Progress, Review,
|
|
18
|
+
Approved, Completed, Final). `--content` / `--instructions` accept `@file`,
|
|
19
|
+
`-` (stdin), or a literal.
|
|
20
|
+
- **`processes` command group** (mirror MCP `list_processes` / `get_process` /
|
|
21
|
+
`write_process`): `processes list`, `processes get PROCESS_ID` (full template
|
|
22
|
+
tree — phases, rows, deliverable-type cards, owner roles, objective
|
|
23
|
+
subprocesses), and `processes write --ops` (create/update/delete process,
|
|
24
|
+
phases, rows, deliverable types; `set_dependencies`; `set_owner_roles`). Named
|
|
25
|
+
refs, optional card layout with auto-placement (`after_type_id` / append),
|
|
26
|
+
role-name resolution, and an in-use delete guard (`confirm_in_use`).
|
|
27
|
+
- **`roles` command group** (mirror MCP `list_roles` / `write_role`):
|
|
28
|
+
`roles list`, `roles create`, `roles update`, `roles delete`, and
|
|
29
|
+
`roles write --ops`.
|
|
30
|
+
- **Context-file management** under the `context` group — manage the uploaded
|
|
31
|
+
files that feed a deliverable's (or objective's) LLM context: `context files`
|
|
32
|
+
(list), `context add` (upload; re-upload by name replaces), `context
|
|
33
|
+
file-content` (parsed text), `context download-file`, `context remove-file`,
|
|
34
|
+
and `context set-file --exclude/--include` (toggle a file in/out of the LLM
|
|
35
|
+
context). External source links remain web-app integration flows.
|
|
36
|
+
- `expedait_cli/ops.py` — shared multi-op engine (`RefResolver`, `run_ops`,
|
|
37
|
+
`render_ops`) behind all three write surfaces, mirroring the MCP server's
|
|
38
|
+
`_common.py` run-ops scaffold.
|
|
39
|
+
- `client.BackendError` + an op-safe request path so per-op failures are
|
|
40
|
+
captured and reported instead of aborting the whole command.
|
|
41
|
+
- `deliverables types` — list deliverable types so you can find the `--type` id
|
|
42
|
+
that `deliverables create` needs.
|
|
43
|
+
- `projects workspace [PROJECT_ID]` — deliverables grouped by phase (mirrors the
|
|
44
|
+
MCP `get_project_workspace` tool); the structure-aware view the flat
|
|
45
|
+
`deliverables list` can't give.
|
|
46
|
+
|
|
47
|
+
### Fixed
|
|
48
|
+
- `processes write` no longer crashes with an uncaught `KeyError` when an
|
|
49
|
+
`update_phase_row` op omits `position`; it now reports a clean per-op
|
|
50
|
+
`missing_field` error.
|
|
51
|
+
- `--content` / `--instructions` / `--ops` with a missing or unreadable `@file`
|
|
52
|
+
now raise a clear usage error instead of leaking an `OSError` traceback. The
|
|
53
|
+
three duplicate readers were consolidated into one helper (`ops.read_value_arg`).
|
|
54
|
+
- `projects download` no longer crashes. It passed a `fmt=` argument that the
|
|
55
|
+
client method never accepted (a `TypeError` on every run, hidden by a loosely
|
|
56
|
+
mocked test). The backend `/download` endpoint has no format parameter, so the
|
|
57
|
+
dead `--download-format` option was removed; the command always extracts the
|
|
58
|
+
markdown + images ZIP.
|
|
59
|
+
|
|
60
|
+
## 0.3.0
|
|
61
|
+
|
|
62
|
+
Adapt the CLI to the product's four-primitive domain model (objectives,
|
|
63
|
+
deliverables, context, review).
|
|
64
|
+
|
|
65
|
+
### Added
|
|
66
|
+
- `deliverables` command group (`list`, `get`, `inspect`, `download`) — the
|
|
67
|
+
rename of `pages`, pointed at `/api/v1/deliverables/...`.
|
|
68
|
+
- `deliverables get --include` — comma-separated section reads (`meta`,
|
|
69
|
+
`content`, `template`, `requirements`, `writer_instructions`, `dependencies`,
|
|
70
|
+
`external_context`, `score`, `comments`, `versions`), defaulting to `content`.
|
|
71
|
+
`meta` surfaces `parent_deliverable_id`.
|
|
72
|
+
- `objectives overview DELIVERABLE_ID` — objective metadata plus its full
|
|
73
|
+
descendant tree.
|
|
74
|
+
- `context get DELIVERABLE_ID` — read-only LLM context snapshot for a
|
|
75
|
+
deliverable.
|
|
76
|
+
- `review` command group: `review issues DELIVERABLE_ID [--state open|muted|all]`
|
|
77
|
+
and `review mute ISSUE_ID [--note TEXT] [--unmute]`.
|
|
78
|
+
- `comments create --agent-run-id` to link a comment to a build run.
|
|
79
|
+
- `expedait-cli` console-script alias so `uvx expedait-cli …` keeps working.
|
|
80
|
+
|
|
81
|
+
### Changed
|
|
82
|
+
- `comments create` now resolves anchor offsets from the deliverable content;
|
|
83
|
+
only `--text` and `--selected-text` are required. `--start-offset` /
|
|
84
|
+
`--end-offset` remain available as explicit overrides.
|
|
85
|
+
- Renamed `comments create --source-page-id` → `--source-deliverable-id`
|
|
86
|
+
(payload field `source_page_id` → `source_deliverable_id`).
|
|
87
|
+
- `comments resolve` / `comments delete` now use the deliverable-scoped routes
|
|
88
|
+
`/api/v1/deliverables/{id}/comments/{comment_id}`.
|
|
89
|
+
|
|
90
|
+
### Deprecated
|
|
91
|
+
- The `pages` command group. `expedait pages …` still works for one release
|
|
92
|
+
(warns and forwards to `deliverables`) and will then be removed.
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: expedait-cli
|
|
3
|
+
Version: 0.4.0
|
|
4
|
+
Summary: CLI for Expedait project management — read and write deliverables, processes, roles, and comments
|
|
5
|
+
License-Expression: Apache-2.0
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Requires-Python: >=3.11
|
|
8
|
+
Requires-Dist: click>=8.1
|
|
9
|
+
Requires-Dist: httpx>=0.27
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
|
|
12
|
+
# Expedait CLI
|
|
13
|
+
|
|
14
|
+
[](https://pypi.org/project/expedait-cli/)
|
|
15
|
+
[](https://opensource.org/licenses/Apache-2.0)
|
|
16
|
+
[](https://www.python.org/downloads/)
|
|
17
|
+
|
|
18
|
+
CLI for [Expedait](https://expedait.org) — lets AI coding agents download project specs and post comments via the Expedait API.
|
|
19
|
+
|
|
20
|
+
## The model
|
|
21
|
+
|
|
22
|
+
Expedait organizes specs around four primitives:
|
|
23
|
+
|
|
24
|
+
- **Objectives** — top-level goals. An objective is itself a deliverable that nests child deliverables beneath it (`parent_deliverable_id`).
|
|
25
|
+
- **Deliverables** — the individual spec documents (formerly "pages").
|
|
26
|
+
- **Context** — the assembled LLM context for one deliverable: dependency deliverables, linked external sources, uploaded files, and aggregate sizes.
|
|
27
|
+
- **Review** — scoring findings raised on a deliverable: severity, description, the criteria that flagged them, and anchor offsets.
|
|
28
|
+
|
|
29
|
+
## Usage
|
|
30
|
+
|
|
31
|
+
### Run with `uvx` (recommended)
|
|
32
|
+
|
|
33
|
+
No installation needed — run directly:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
uvx expedait-cli auth login
|
|
37
|
+
uvx expedait-cli projects list
|
|
38
|
+
uvx expedait-cli projects download 1
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Add as a dev dependency
|
|
42
|
+
|
|
43
|
+
If your AI agent needs it available in the project environment:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
uv add --group dev expedait-cli
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Then reference it in your agent configuration (e.g. `CLAUDE.md`, `.cursor/rules`, etc.).
|
|
50
|
+
|
|
51
|
+
## Project Setup
|
|
52
|
+
|
|
53
|
+
After authenticating, run `init` inside your project directory to store your tenant and project settings locally:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
uvx expedait-cli init
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
This creates `.expedait/settings.json` with your `tenant_id` and `project_id`. Add `.expedait/` to your `.gitignore`.
|
|
60
|
+
|
|
61
|
+
Once initialized, commands that need a project ID will resolve it automatically. Downloads default to `.expedait/context/`:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
expedait projects download # downloads to .expedait/context/
|
|
65
|
+
expedait deliverables list # no --project-id needed
|
|
66
|
+
expedait deliverables download 42 # downloads to .expedait/context/
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
**Resolution order for tenant/project:** CLI flag > env var > `.expedait/settings.json` > `~/.expedait/config.json`.
|
|
70
|
+
|
|
71
|
+
## Authentication
|
|
72
|
+
|
|
73
|
+
### Interactive login
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
uvx expedait-cli auth login
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Prompts for login method (SSO or email/password). Stores credentials in `~/.expedait/config.json`.
|
|
80
|
+
|
|
81
|
+
### Environment variables (CI / agents)
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
export EXPEDAIT_TOKEN="your-jwt-token"
|
|
85
|
+
export EXPEDAIT_API_URL="https://your-instance.expedait.org"
|
|
86
|
+
export EXPEDAIT_TENANT_ID=1
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
**Token resolution order:** `EXPEDAIT_TOKEN` env var > `~/.expedait/config.json` > error.
|
|
90
|
+
|
|
91
|
+
## Commands
|
|
92
|
+
|
|
93
|
+
### Auth
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
expedait auth login # Interactive login
|
|
97
|
+
expedait auth status # Show current user and tenant
|
|
98
|
+
expedait auth logout # Clear stored credentials
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Projects
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
expedait projects list # List all projects
|
|
105
|
+
expedait projects get PROJECT_ID # Get project details
|
|
106
|
+
expedait projects workspace PROJECT_ID # Deliverables grouped by phase (structure-aware view)
|
|
107
|
+
expedait projects download PROJECT_ID # Extract all deliverables to .expedait/context/
|
|
108
|
+
expedait projects download PROJECT_ID --output-dir ./specs # Extract to a custom directory
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Deliverables
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
expedait deliverables list --project-id PROJECT_ID # List deliverables in a project
|
|
115
|
+
expedait deliverables types # List deliverable types (find the --type ID for create)
|
|
116
|
+
expedait deliverables get DELIVERABLE_ID # Print deliverable markdown content
|
|
117
|
+
expedait deliverables get DELIVERABLE_ID --include meta,content,dependencies,score
|
|
118
|
+
expedait deliverables inspect DELIVERABLE_ID # Full context (content + comments + deps + lock)
|
|
119
|
+
expedait deliverables download DELIVERABLE_ID # Extract to .expedait/context/
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
`--include` accepts a comma-separated subset of: `meta`, `content`, `template`,
|
|
123
|
+
`requirements`, `writer_instructions`, `dependencies`, `external_context`,
|
|
124
|
+
`score`, `comments`, `versions`. It defaults to `content`. `meta` surfaces
|
|
125
|
+
`parent_deliverable_id` (non-null ⇒ this deliverable is a child nested under an
|
|
126
|
+
objective).
|
|
127
|
+
|
|
128
|
+
#### Writing deliverables
|
|
129
|
+
|
|
130
|
+
Mirrors the MCP `write_deliverable` tool. Ergonomic subcommands cover the common
|
|
131
|
+
cases; `write --ops` applies an ordered batch in one call.
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
expedait deliverables create --project P --type TYPE_ID --title "Vision" \
|
|
135
|
+
[--content @vision.md] [--parent-deliverable-id ID] # create (content: @file, - for stdin, or literal)
|
|
136
|
+
expedait deliverables edit DELIVERABLE_ID --content @body.md # replace content (autosave, no version bump)
|
|
137
|
+
expedait deliverables rename DELIVERABLE_ID --title "New title" # rename without touching content
|
|
138
|
+
expedait deliverables save-version DELIVERABLE_ID --reason "checkpoint" # explicit snapshot
|
|
139
|
+
expedait deliverables set-state DELIVERABLE_ID --state "Review" # transition workflow state
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Valid states: `Not Started`, `In Progress`, `Review`, `Approved`, `Completed`,
|
|
143
|
+
`Final`.
|
|
144
|
+
|
|
145
|
+
For multi-step writes, `write --ops` takes a JSON ops array (`@file.json`, `-`
|
|
146
|
+
for stdin, or inline). Each op is one of `create`, `edit`, `rename`,
|
|
147
|
+
`save_version`, `set_state`. Chain ops on a freshly-created deliverable with
|
|
148
|
+
`"id": "$last"` (the previous op's deliverable) or bind a name on create
|
|
149
|
+
(`"ref": "x"`) and reference it later as `"id": "@x"`:
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
expedait deliverables write --ops @ops.json
|
|
153
|
+
# ops.json:
|
|
154
|
+
# [
|
|
155
|
+
# {"op": "create", "ref": "v", "project_id": 1, "deliverable_type_id": 3, "title": "Vision"},
|
|
156
|
+
# {"op": "edit", "id": "@v", "content": "# Product Vision\n..."},
|
|
157
|
+
# {"op": "set_state", "id": "@v", "state": "Review"}
|
|
158
|
+
# ]
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Ops run in order and stop on the first failure (the rest report `skipped`); the
|
|
162
|
+
output reports per-op `{status: ok | error | skipped}`, and the command exits
|
|
163
|
+
non-zero if any op failed.
|
|
164
|
+
|
|
165
|
+
### Objectives
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
expedait objectives overview DELIVERABLE_ID # Objective metadata + full descendant tree
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Context
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
expedait context get DELIVERABLE_ID # The LLM context snapshot for one deliverable
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
A deliverable's (or objective's) context is built from dependency deliverables,
|
|
178
|
+
linked external sources, and **uploaded context files**. The CLI manages the
|
|
179
|
+
file half of that surface — attach reference docs an agent should write against,
|
|
180
|
+
and toggle whether each one feeds the LLM context:
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
expedait context files DELIVERABLE_ID # List attached context files
|
|
184
|
+
expedait context add DELIVERABLE_ID ./reference.md # Upload a context file (re-upload by name replaces)
|
|
185
|
+
expedait context file-content FILE_ID # Parsed text the file contributes to context
|
|
186
|
+
expedait context download-file FILE_ID -o ./out.md # Download a file's raw bytes
|
|
187
|
+
expedait context set-file FILE_ID --exclude # Exclude from LLM context (or --include)
|
|
188
|
+
expedait context remove-file FILE_ID # Delete a context file
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
External source links (Notion, GitHub, etc.) are created through the web app's
|
|
192
|
+
integration flows, not the CLI.
|
|
193
|
+
|
|
194
|
+
### Review
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
expedait review issues DELIVERABLE_ID # List scoring findings (default: all)
|
|
198
|
+
expedait review issues DELIVERABLE_ID --state open # Only open findings
|
|
199
|
+
expedait review mute ISSUE_ID --note "by design" # Mute a finding
|
|
200
|
+
expedait review mute ISSUE_ID --unmute # Unmute a finding
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### Comments
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
expedait comments list DELIVERABLE_ID # List comments on a deliverable
|
|
207
|
+
expedait comments create DELIVERABLE_ID \ # Create a comment (offsets resolved automatically)
|
|
208
|
+
--text "Comment content" \
|
|
209
|
+
--selected-text "text from the deliverable" \
|
|
210
|
+
--source-deliverable-id 5 # Optional: agent's source deliverable
|
|
211
|
+
expedait comments resolve DELIVERABLE_ID COMMENT_ID # Mark as resolved
|
|
212
|
+
expedait comments delete DELIVERABLE_ID COMMENT_ID # Delete a comment
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
Only `--text` and `--selected-text` are required; the CLI locates the selected
|
|
216
|
+
text in the deliverable to compute anchor offsets. Pass `--start-offset` and
|
|
217
|
+
`--end-offset` to anchor explicitly (e.g. when the selected text appears more
|
|
218
|
+
than once).
|
|
219
|
+
|
|
220
|
+
### Processes (Process Designer)
|
|
221
|
+
|
|
222
|
+
A *process* is a project type plus the template tree it owns: phases → rows →
|
|
223
|
+
deliverable-type cards, dependency edges, owner roles, and objective
|
|
224
|
+
subprocesses. Editing it reshapes **every** project instantiated from it.
|
|
225
|
+
Mirrors the MCP `list_processes` / `get_process` / `write_process` tools.
|
|
226
|
+
|
|
227
|
+
```bash
|
|
228
|
+
expedait processes list # List processes (project types)
|
|
229
|
+
expedait processes get PROCESS_ID # Full template tree (phases, rows, cards, roles)
|
|
230
|
+
expedait processes write --ops @ops.json # Build or adapt a process in one call
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
`write --ops` ops: `create_process`, `update_process`, `duplicate_process`,
|
|
234
|
+
`delete_process`, `create_phase`, `update_phase`, `delete_phase`,
|
|
235
|
+
`create_phase_row`, `update_phase_row`, `delete_phase_row`,
|
|
236
|
+
`create_deliverable_type`, `update_deliverable_type`, `delete_deliverable_type`,
|
|
237
|
+
`set_dependencies`, `set_owner_roles`. Ops chain via named refs (`"ref": "x"` on
|
|
238
|
+
a create op, `"@x"` later). Card layout is optional — omit `col_position` and
|
|
239
|
+
cards auto-place (append, or just after `after_type_id`). `set_owner_roles`
|
|
240
|
+
accepts role names or ids. Delete ops refuse an in-use template unless the op
|
|
241
|
+
carries `"confirm_in_use": true`.
|
|
242
|
+
|
|
243
|
+
```jsonc
|
|
244
|
+
// ops.json — build a process end to end in one call
|
|
245
|
+
[
|
|
246
|
+
{"op": "create_process", "ref": "p", "name": "Product Dev"},
|
|
247
|
+
{"op": "create_phase", "ref": "ph", "process_id": "@p", "name": "Discovery"},
|
|
248
|
+
{"op": "create_deliverable_type", "ref": "vision", "phase_id": "@ph", "name": "Vision"},
|
|
249
|
+
{"op": "create_deliverable_type", "ref": "prd", "phase_id": "@ph", "name": "PRD", "after_type_id": "@vision"},
|
|
250
|
+
{"op": "set_dependencies", "type_id": "@prd", "dependency_ids": ["@vision"]},
|
|
251
|
+
{"op": "set_owner_roles", "type_id": "@prd", "role_names": ["Product Manager"]}
|
|
252
|
+
]
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
### Roles
|
|
256
|
+
|
|
257
|
+
A *role* is a workspace project role — the owner-role pool assigned to
|
|
258
|
+
deliverable types. A role's `instructions` is its LLM coaching persona. Mirrors
|
|
259
|
+
the MCP `list_roles` / `write_role` tools.
|
|
260
|
+
|
|
261
|
+
```bash
|
|
262
|
+
expedait roles list # List project roles
|
|
263
|
+
expedait roles create --name "Product Manager" \ # Create (instructions: @file, -, or literal)
|
|
264
|
+
[--description "owns the roadmap"] [--instructions @pm.md]
|
|
265
|
+
expedait roles update ROLE_ID --name "Lead PM" # Update name/description/instructions
|
|
266
|
+
expedait roles delete ROLE_ID # Delete a role
|
|
267
|
+
expedait roles write --ops @ops.json # Batch (create_role/update_role/delete_role)
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### Global Options
|
|
271
|
+
|
|
272
|
+
```bash
|
|
273
|
+
expedait --api-url https://host:8000 ... # Override API URL
|
|
274
|
+
expedait --tenant-id 2 ... # Override tenant
|
|
275
|
+
expedait --format json ... # Force JSON output
|
|
276
|
+
expedait --format text ... # Force human-readable output
|
|
277
|
+
expedait --version # Show version
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
Output format defaults to `text` when connected to a terminal, `json` when piped.
|
|
281
|
+
|
|
282
|
+
> **Migration note:** the `pages` command group has been renamed to
|
|
283
|
+
> `deliverables`. `expedait pages …` still works for one release (it warns and
|
|
284
|
+
> forwards) but will be removed.
|
|
285
|
+
|
|
286
|
+
## Agent Skills
|
|
287
|
+
|
|
288
|
+
For step-by-step guides on using the CLI from AI coding agents, see [expedait-skills](https://github.com/Expedait/expedait-skills).
|
|
289
|
+
|
|
290
|
+
## Development
|
|
291
|
+
|
|
292
|
+
```bash
|
|
293
|
+
git clone https://github.com/Expedait/expedait-cli.git
|
|
294
|
+
cd expedait-cli
|
|
295
|
+
uv sync --group dev
|
|
296
|
+
uv run python -m pytest
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
## License
|
|
300
|
+
|
|
301
|
+
[Apache License 2.0](LICENSE)
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
# Expedait CLI
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/expedait-cli/)
|
|
4
|
+
[](https://opensource.org/licenses/Apache-2.0)
|
|
5
|
+
[](https://www.python.org/downloads/)
|
|
6
|
+
|
|
7
|
+
CLI for [Expedait](https://expedait.org) — lets AI coding agents download project specs and post comments via the Expedait API.
|
|
8
|
+
|
|
9
|
+
## The model
|
|
10
|
+
|
|
11
|
+
Expedait organizes specs around four primitives:
|
|
12
|
+
|
|
13
|
+
- **Objectives** — top-level goals. An objective is itself a deliverable that nests child deliverables beneath it (`parent_deliverable_id`).
|
|
14
|
+
- **Deliverables** — the individual spec documents (formerly "pages").
|
|
15
|
+
- **Context** — the assembled LLM context for one deliverable: dependency deliverables, linked external sources, uploaded files, and aggregate sizes.
|
|
16
|
+
- **Review** — scoring findings raised on a deliverable: severity, description, the criteria that flagged them, and anchor offsets.
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
|
|
20
|
+
### Run with `uvx` (recommended)
|
|
21
|
+
|
|
22
|
+
No installation needed — run directly:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
uvx expedait-cli auth login
|
|
26
|
+
uvx expedait-cli projects list
|
|
27
|
+
uvx expedait-cli projects download 1
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Add as a dev dependency
|
|
31
|
+
|
|
32
|
+
If your AI agent needs it available in the project environment:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
uv add --group dev expedait-cli
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Then reference it in your agent configuration (e.g. `CLAUDE.md`, `.cursor/rules`, etc.).
|
|
39
|
+
|
|
40
|
+
## Project Setup
|
|
41
|
+
|
|
42
|
+
After authenticating, run `init` inside your project directory to store your tenant and project settings locally:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
uvx expedait-cli init
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
This creates `.expedait/settings.json` with your `tenant_id` and `project_id`. Add `.expedait/` to your `.gitignore`.
|
|
49
|
+
|
|
50
|
+
Once initialized, commands that need a project ID will resolve it automatically. Downloads default to `.expedait/context/`:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
expedait projects download # downloads to .expedait/context/
|
|
54
|
+
expedait deliverables list # no --project-id needed
|
|
55
|
+
expedait deliverables download 42 # downloads to .expedait/context/
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
**Resolution order for tenant/project:** CLI flag > env var > `.expedait/settings.json` > `~/.expedait/config.json`.
|
|
59
|
+
|
|
60
|
+
## Authentication
|
|
61
|
+
|
|
62
|
+
### Interactive login
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
uvx expedait-cli auth login
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Prompts for login method (SSO or email/password). Stores credentials in `~/.expedait/config.json`.
|
|
69
|
+
|
|
70
|
+
### Environment variables (CI / agents)
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
export EXPEDAIT_TOKEN="your-jwt-token"
|
|
74
|
+
export EXPEDAIT_API_URL="https://your-instance.expedait.org"
|
|
75
|
+
export EXPEDAIT_TENANT_ID=1
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
**Token resolution order:** `EXPEDAIT_TOKEN` env var > `~/.expedait/config.json` > error.
|
|
79
|
+
|
|
80
|
+
## Commands
|
|
81
|
+
|
|
82
|
+
### Auth
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
expedait auth login # Interactive login
|
|
86
|
+
expedait auth status # Show current user and tenant
|
|
87
|
+
expedait auth logout # Clear stored credentials
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Projects
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
expedait projects list # List all projects
|
|
94
|
+
expedait projects get PROJECT_ID # Get project details
|
|
95
|
+
expedait projects workspace PROJECT_ID # Deliverables grouped by phase (structure-aware view)
|
|
96
|
+
expedait projects download PROJECT_ID # Extract all deliverables to .expedait/context/
|
|
97
|
+
expedait projects download PROJECT_ID --output-dir ./specs # Extract to a custom directory
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Deliverables
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
expedait deliverables list --project-id PROJECT_ID # List deliverables in a project
|
|
104
|
+
expedait deliverables types # List deliverable types (find the --type ID for create)
|
|
105
|
+
expedait deliverables get DELIVERABLE_ID # Print deliverable markdown content
|
|
106
|
+
expedait deliverables get DELIVERABLE_ID --include meta,content,dependencies,score
|
|
107
|
+
expedait deliverables inspect DELIVERABLE_ID # Full context (content + comments + deps + lock)
|
|
108
|
+
expedait deliverables download DELIVERABLE_ID # Extract to .expedait/context/
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
`--include` accepts a comma-separated subset of: `meta`, `content`, `template`,
|
|
112
|
+
`requirements`, `writer_instructions`, `dependencies`, `external_context`,
|
|
113
|
+
`score`, `comments`, `versions`. It defaults to `content`. `meta` surfaces
|
|
114
|
+
`parent_deliverable_id` (non-null ⇒ this deliverable is a child nested under an
|
|
115
|
+
objective).
|
|
116
|
+
|
|
117
|
+
#### Writing deliverables
|
|
118
|
+
|
|
119
|
+
Mirrors the MCP `write_deliverable` tool. Ergonomic subcommands cover the common
|
|
120
|
+
cases; `write --ops` applies an ordered batch in one call.
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
expedait deliverables create --project P --type TYPE_ID --title "Vision" \
|
|
124
|
+
[--content @vision.md] [--parent-deliverable-id ID] # create (content: @file, - for stdin, or literal)
|
|
125
|
+
expedait deliverables edit DELIVERABLE_ID --content @body.md # replace content (autosave, no version bump)
|
|
126
|
+
expedait deliverables rename DELIVERABLE_ID --title "New title" # rename without touching content
|
|
127
|
+
expedait deliverables save-version DELIVERABLE_ID --reason "checkpoint" # explicit snapshot
|
|
128
|
+
expedait deliverables set-state DELIVERABLE_ID --state "Review" # transition workflow state
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Valid states: `Not Started`, `In Progress`, `Review`, `Approved`, `Completed`,
|
|
132
|
+
`Final`.
|
|
133
|
+
|
|
134
|
+
For multi-step writes, `write --ops` takes a JSON ops array (`@file.json`, `-`
|
|
135
|
+
for stdin, or inline). Each op is one of `create`, `edit`, `rename`,
|
|
136
|
+
`save_version`, `set_state`. Chain ops on a freshly-created deliverable with
|
|
137
|
+
`"id": "$last"` (the previous op's deliverable) or bind a name on create
|
|
138
|
+
(`"ref": "x"`) and reference it later as `"id": "@x"`:
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
expedait deliverables write --ops @ops.json
|
|
142
|
+
# ops.json:
|
|
143
|
+
# [
|
|
144
|
+
# {"op": "create", "ref": "v", "project_id": 1, "deliverable_type_id": 3, "title": "Vision"},
|
|
145
|
+
# {"op": "edit", "id": "@v", "content": "# Product Vision\n..."},
|
|
146
|
+
# {"op": "set_state", "id": "@v", "state": "Review"}
|
|
147
|
+
# ]
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Ops run in order and stop on the first failure (the rest report `skipped`); the
|
|
151
|
+
output reports per-op `{status: ok | error | skipped}`, and the command exits
|
|
152
|
+
non-zero if any op failed.
|
|
153
|
+
|
|
154
|
+
### Objectives
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
expedait objectives overview DELIVERABLE_ID # Objective metadata + full descendant tree
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Context
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
expedait context get DELIVERABLE_ID # The LLM context snapshot for one deliverable
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
A deliverable's (or objective's) context is built from dependency deliverables,
|
|
167
|
+
linked external sources, and **uploaded context files**. The CLI manages the
|
|
168
|
+
file half of that surface — attach reference docs an agent should write against,
|
|
169
|
+
and toggle whether each one feeds the LLM context:
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
expedait context files DELIVERABLE_ID # List attached context files
|
|
173
|
+
expedait context add DELIVERABLE_ID ./reference.md # Upload a context file (re-upload by name replaces)
|
|
174
|
+
expedait context file-content FILE_ID # Parsed text the file contributes to context
|
|
175
|
+
expedait context download-file FILE_ID -o ./out.md # Download a file's raw bytes
|
|
176
|
+
expedait context set-file FILE_ID --exclude # Exclude from LLM context (or --include)
|
|
177
|
+
expedait context remove-file FILE_ID # Delete a context file
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
External source links (Notion, GitHub, etc.) are created through the web app's
|
|
181
|
+
integration flows, not the CLI.
|
|
182
|
+
|
|
183
|
+
### Review
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
expedait review issues DELIVERABLE_ID # List scoring findings (default: all)
|
|
187
|
+
expedait review issues DELIVERABLE_ID --state open # Only open findings
|
|
188
|
+
expedait review mute ISSUE_ID --note "by design" # Mute a finding
|
|
189
|
+
expedait review mute ISSUE_ID --unmute # Unmute a finding
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### Comments
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
expedait comments list DELIVERABLE_ID # List comments on a deliverable
|
|
196
|
+
expedait comments create DELIVERABLE_ID \ # Create a comment (offsets resolved automatically)
|
|
197
|
+
--text "Comment content" \
|
|
198
|
+
--selected-text "text from the deliverable" \
|
|
199
|
+
--source-deliverable-id 5 # Optional: agent's source deliverable
|
|
200
|
+
expedait comments resolve DELIVERABLE_ID COMMENT_ID # Mark as resolved
|
|
201
|
+
expedait comments delete DELIVERABLE_ID COMMENT_ID # Delete a comment
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
Only `--text` and `--selected-text` are required; the CLI locates the selected
|
|
205
|
+
text in the deliverable to compute anchor offsets. Pass `--start-offset` and
|
|
206
|
+
`--end-offset` to anchor explicitly (e.g. when the selected text appears more
|
|
207
|
+
than once).
|
|
208
|
+
|
|
209
|
+
### Processes (Process Designer)
|
|
210
|
+
|
|
211
|
+
A *process* is a project type plus the template tree it owns: phases → rows →
|
|
212
|
+
deliverable-type cards, dependency edges, owner roles, and objective
|
|
213
|
+
subprocesses. Editing it reshapes **every** project instantiated from it.
|
|
214
|
+
Mirrors the MCP `list_processes` / `get_process` / `write_process` tools.
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
expedait processes list # List processes (project types)
|
|
218
|
+
expedait processes get PROCESS_ID # Full template tree (phases, rows, cards, roles)
|
|
219
|
+
expedait processes write --ops @ops.json # Build or adapt a process in one call
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
`write --ops` ops: `create_process`, `update_process`, `duplicate_process`,
|
|
223
|
+
`delete_process`, `create_phase`, `update_phase`, `delete_phase`,
|
|
224
|
+
`create_phase_row`, `update_phase_row`, `delete_phase_row`,
|
|
225
|
+
`create_deliverable_type`, `update_deliverable_type`, `delete_deliverable_type`,
|
|
226
|
+
`set_dependencies`, `set_owner_roles`. Ops chain via named refs (`"ref": "x"` on
|
|
227
|
+
a create op, `"@x"` later). Card layout is optional — omit `col_position` and
|
|
228
|
+
cards auto-place (append, or just after `after_type_id`). `set_owner_roles`
|
|
229
|
+
accepts role names or ids. Delete ops refuse an in-use template unless the op
|
|
230
|
+
carries `"confirm_in_use": true`.
|
|
231
|
+
|
|
232
|
+
```jsonc
|
|
233
|
+
// ops.json — build a process end to end in one call
|
|
234
|
+
[
|
|
235
|
+
{"op": "create_process", "ref": "p", "name": "Product Dev"},
|
|
236
|
+
{"op": "create_phase", "ref": "ph", "process_id": "@p", "name": "Discovery"},
|
|
237
|
+
{"op": "create_deliverable_type", "ref": "vision", "phase_id": "@ph", "name": "Vision"},
|
|
238
|
+
{"op": "create_deliverable_type", "ref": "prd", "phase_id": "@ph", "name": "PRD", "after_type_id": "@vision"},
|
|
239
|
+
{"op": "set_dependencies", "type_id": "@prd", "dependency_ids": ["@vision"]},
|
|
240
|
+
{"op": "set_owner_roles", "type_id": "@prd", "role_names": ["Product Manager"]}
|
|
241
|
+
]
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### Roles
|
|
245
|
+
|
|
246
|
+
A *role* is a workspace project role — the owner-role pool assigned to
|
|
247
|
+
deliverable types. A role's `instructions` is its LLM coaching persona. Mirrors
|
|
248
|
+
the MCP `list_roles` / `write_role` tools.
|
|
249
|
+
|
|
250
|
+
```bash
|
|
251
|
+
expedait roles list # List project roles
|
|
252
|
+
expedait roles create --name "Product Manager" \ # Create (instructions: @file, -, or literal)
|
|
253
|
+
[--description "owns the roadmap"] [--instructions @pm.md]
|
|
254
|
+
expedait roles update ROLE_ID --name "Lead PM" # Update name/description/instructions
|
|
255
|
+
expedait roles delete ROLE_ID # Delete a role
|
|
256
|
+
expedait roles write --ops @ops.json # Batch (create_role/update_role/delete_role)
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### Global Options
|
|
260
|
+
|
|
261
|
+
```bash
|
|
262
|
+
expedait --api-url https://host:8000 ... # Override API URL
|
|
263
|
+
expedait --tenant-id 2 ... # Override tenant
|
|
264
|
+
expedait --format json ... # Force JSON output
|
|
265
|
+
expedait --format text ... # Force human-readable output
|
|
266
|
+
expedait --version # Show version
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
Output format defaults to `text` when connected to a terminal, `json` when piped.
|
|
270
|
+
|
|
271
|
+
> **Migration note:** the `pages` command group has been renamed to
|
|
272
|
+
> `deliverables`. `expedait pages …` still works for one release (it warns and
|
|
273
|
+
> forwards) but will be removed.
|
|
274
|
+
|
|
275
|
+
## Agent Skills
|
|
276
|
+
|
|
277
|
+
For step-by-step guides on using the CLI from AI coding agents, see [expedait-skills](https://github.com/Expedait/expedait-skills).
|
|
278
|
+
|
|
279
|
+
## Development
|
|
280
|
+
|
|
281
|
+
```bash
|
|
282
|
+
git clone https://github.com/Expedait/expedait-cli.git
|
|
283
|
+
cd expedait-cli
|
|
284
|
+
uv sync --group dev
|
|
285
|
+
uv run python -m pytest
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
## License
|
|
289
|
+
|
|
290
|
+
[Apache License 2.0](LICENSE)
|