@focusedobjective/deliverytower-cli
v0.1.2
Published
DeliveryTower external assessment API command-line client.
Readme
@focusedobjective/deliverytower-cli
Command-line client for starting and reading DeliveryTower external assessment runs.
The CLI talks to the DeliveryTower Assessment API using a DeliveryTower API key. It sends source references only, such as a GitHub issue, GitHub pull request, Jira issue, or DeliveryTower work item id. DeliveryTower resolves connected source context server-side.
Requirements
- Node.js 20 or newer
- A DeliveryTower Convex site URL
- A DeliveryTower API key with
assessment:runandassessment:read - Optional:
assessment:publishwhen using--publish-github-pr-comment
Set credentials in the environment:
export DELIVERYTOWER_API_URL="https://YOUR_CONVEX_SITE_URL"
export DELIVERYTOWER_API_KEY="dt_live_..."PowerShell:
$env:DELIVERYTOWER_API_URL = "https://YOUR_CONVEX_SITE_URL"
$env:DELIVERYTOWER_API_KEY = "dt_live_..."Verify that the CLI can see the required environment:
npx @focusedobjective/deliverytower-cli auth checkUsage
Run without installing:
npx @focusedobjective/deliverytower-cli assess \
--source github-pr \
--owner acme \
--repo web \
--pr 42 \
--format both \
--waitInstall globally:
npm install -g @focusedobjective/deliverytower-cli
deliverytower auth checkLocal repository checkout:
npm run deliverytower -- assess \
--source github-issue \
--owner acme \
--repo web \
--issue 42Commands
deliverytower auth check
deliverytower assess --source <github-issue|github-pr|jira-issue|work-item> [flags]
deliverytower batch --file <requests.json> [flags]
deliverytower get --run-id <runId>
deliverytower wait --run-id <runId> [flags]Start An Assessment
GitHub pull request:
deliverytower assess \
--source github-pr \
--owner acme \
--repo web \
--pr 42 \
--format markdown \
--idempotency-key "ci-acme-web-pr-42" \
--waitGitHub issue:
deliverytower assess \
--source github-issue \
--owner acme \
--repo web \
--issue 123 \
--format jsonJira issue by key:
deliverytower assess \
--source jira-issue \
--issue PLAT-123 \
--project PLAT \
--format both \
--waitJira issue by URL:
deliverytower assess \
--source jira-issue \
--issue-url "https://example.atlassian.net/browse/PLAT-123"Existing DeliveryTower work item:
deliverytower assess \
--source work-item \
--work-item-id wi_123 \
--format jsonassess starts a run and prints the accepted run JSON. Add --wait to poll until
the run reaches succeeded or failed.
Request Formats
Use --format to request output formats:
json: machine-readable response only. This is the default.markdown: human-readable markdown summary.both: request both JSON and markdown.
When a result includes markdown, --format markdown prints the markdown body.
--format both prints markdown first, followed by the JSON response.
JSON Input
For advanced options, pass the API request body as JSON on stdin or with
--file.
request.json:
{
"source": {
"type": "github_pull_request",
"owner": "acme",
"repo": "web",
"pullRequestNumber": 42
},
"outputFormats": ["json", "markdown"]
}Run it:
deliverytower assess --file request.json --idempotency-key "manual-acme-web-pr-42" --waitThe same request can be piped through stdin:
cat request.json | deliverytower assess --waitPublish A GitHub PR Comment
For GitHub pull request assessments, DeliveryTower can publish or update one PR summary comment:
deliverytower assess \
--source github-pr \
--owner acme \
--repo web \
--pr 42 \
--format markdown \
--publish-github-pr-comment \
--idempotency-key "ci-acme-web-pr-42" \
--waitThe API key must include assessment:publish. DeliveryTower writes the comment
through its connected GitHub App, not through the CLI process.
Retrieve Or Wait For A Run
Retrieve the latest known state:
deliverytower get --run-id arun_... --format jsonPoll until the run is terminal:
deliverytower wait \
--run-id arun_... \
--timeout-seconds 600 \
--poll-interval-seconds 10 \
--format markdownTerminal statuses are succeeded and failed.
Batch Runs
batch reads a non-empty array, or an object with a requests array. Each entry
can be a source reference or a full request body.
requests.json:
[
{
"type": "github_issue",
"owner": "acme",
"repo": "web",
"issueNumber": 1
},
{
"source": {
"type": "jira_issue",
"issueKey": "PLAT-123"
},
"outputFormats": ["json", "markdown"],
"idempotencyKey": "manual-plat-123"
}
]Run the batch:
deliverytower batch \
--file requests.json \
--format markdown \
--idempotency-key-prefix "nightly-2026-06-17" \
--waitWhen --idempotency-key-prefix is provided, entries without their own
idempotencyKey use <prefix>-1, <prefix>-2, and so on.
GitHub Actions Example
name: DeliveryTower Assessment
on:
pull_request:
types: [opened, synchronize, reopened]
permissions:
contents: read
pull-requests: read
jobs:
assess:
runs-on: ubuntu-latest
steps:
- name: Run DeliveryTower assessment
env:
DELIVERYTOWER_API_URL: ${{ secrets.DELIVERYTOWER_API_URL }}
DELIVERYTOWER_API_KEY: ${{ secrets.DELIVERYTOWER_API_KEY }}
PR_NUMBER: ${{ github.event.pull_request.number }}
run: |
npx @focusedobjective/deliverytower-cli assess \
--source github-pr \
--owner "${{ github.repository_owner }}" \
--repo "${{ github.event.repository.name }}" \
--pr "$PR_NUMBER" \
--format both \
--idempotency-key "${{ github.run_id }}-${{ github.repository }}-pr-$PR_NUMBER" \
--waitStore DELIVERYTOWER_API_URL and DELIVERYTOWER_API_KEY as repository or
organization secrets.
Exit Codes
0: command succeeded, or the assessment reachedsucceeded1: invalid input, missing environment, HTTP/API error, or unknown command2: assessment completed with statusfailed3:waitorassess --waittimed out
Notes
- Use an idempotency key for CI and agent workflows so retries reuse the same run.
- The API accepts one source reference per request. Use
batchwhen you need to create multiple runs from one file. - Assessment output is advisory context. It does not grant permission to merge code, edit files, create tickets, or publish comments unless your surrounding workflow explicitly allows that action.
