@oozou/velocity 0.1.1 → 0.1.3
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.
- package/README.md +204 -20
- package/dist/index.js +72 -15
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -1,56 +1,240 @@
|
|
|
1
1
|
# @oozou/velocity
|
|
2
2
|
|
|
3
|
-
Command-line
|
|
3
|
+
Command-line client for [Velocity](https://velocity.oozou.com). Built for humans
|
|
4
|
+
at a terminal and for AI agents driving it programmatically. Output is plain
|
|
5
|
+
tabular text on a TTY, JSON when piped.
|
|
4
6
|
|
|
5
7
|
## Install
|
|
6
8
|
|
|
7
9
|
```sh
|
|
8
10
|
npm i -g @oozou/velocity
|
|
9
|
-
# or
|
|
10
|
-
pnpm add -g @oozou/velocity
|
|
11
11
|
# or run without installing
|
|
12
12
|
npx -y @oozou/velocity auth login
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
+
Update later with `velocity update` (it shells out to `npm i -g @latest`).
|
|
16
|
+
|
|
15
17
|
## Quick start
|
|
16
18
|
|
|
17
19
|
```sh
|
|
18
|
-
velocity
|
|
19
|
-
velocity auth login # opens a browser to authorize
|
|
20
|
+
velocity auth login # browser-based sign-in
|
|
20
21
|
velocity whoami
|
|
21
|
-
velocity
|
|
22
|
+
velocity projects list
|
|
23
|
+
velocity projects use <slug>
|
|
22
24
|
velocity stories list
|
|
23
|
-
velocity stories create --title "
|
|
25
|
+
velocity stories create --title "Fix nav crash" --type bug --status backlog --priority high
|
|
24
26
|
```
|
|
25
27
|
|
|
26
28
|
## Output modes
|
|
27
29
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
| Mode | When |
|
|
31
|
+
| --- | --- |
|
|
32
|
+
| Human | stdout is a TTY |
|
|
33
|
+
| JSON | stdout is piped / non-TTY |
|
|
34
|
+
|
|
35
|
+
Override per-invocation with `--json` / `--human`, or set
|
|
36
|
+
`VELOCITY_OUTPUT=json|human`.
|
|
37
|
+
|
|
38
|
+
Errors land on stderr. Under `--json`, errors are a single
|
|
39
|
+
`{"error":"..."}` line. Exit code is non-zero on any failure.
|
|
31
40
|
|
|
32
41
|
## Headless / CI
|
|
33
42
|
|
|
34
|
-
Skip the browser flow with an existing API token
|
|
43
|
+
Skip the browser flow with an existing API token (Settings → API Tokens):
|
|
35
44
|
|
|
36
45
|
```sh
|
|
37
46
|
export VELOCITY_TOKEN=vel_…
|
|
38
|
-
|
|
39
|
-
velocity stories list --project <id>
|
|
47
|
+
velocity stories list --project <slug>
|
|
40
48
|
```
|
|
41
49
|
|
|
42
|
-
|
|
50
|
+
`VELOCITY_API_BASE` overrides the default endpoint if you're pointing at a
|
|
51
|
+
non-production stack.
|
|
43
52
|
|
|
44
|
-
|
|
45
|
-
| --- | --- |
|
|
46
|
-
| `production` | `https://velocity.oozou.com` |
|
|
47
|
-
| `local` | `http://localhost:3000` |
|
|
53
|
+
## Project context
|
|
48
54
|
|
|
49
|
-
|
|
55
|
+
Most commands operate on a single project. Resolution precedence:
|
|
56
|
+
|
|
57
|
+
1. `--project <slug-or-id>` flag on the command
|
|
58
|
+
2. `VELOCITY_PROJECT` env var
|
|
59
|
+
3. The persisted active project (set by `velocity projects use <slug>`)
|
|
60
|
+
|
|
61
|
+
Projects are addressable by slug (`acme-website`) or by Convex id. Slugs are
|
|
62
|
+
the friendly identifier shown by `velocity projects list`.
|
|
50
63
|
|
|
51
64
|
## Commands
|
|
52
65
|
|
|
53
|
-
`velocity
|
|
66
|
+
### `velocity auth`
|
|
67
|
+
|
|
68
|
+
Browser-based auth via OAuth 2.0 device-code flow.
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
velocity auth login # opens browser, polls for approval
|
|
72
|
+
velocity auth logout # delete locally stored credentials
|
|
73
|
+
velocity auth status # show session details
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Credentials live at `~/.config/velocity/credentials.json` (mode `0600`). The
|
|
77
|
+
token issued is a regular Velocity API token — revokable from
|
|
78
|
+
Settings → API Tokens in the web app.
|
|
79
|
+
|
|
80
|
+
### `velocity whoami`
|
|
81
|
+
|
|
82
|
+
Print the currently authenticated user. Unix `whoami` analogue.
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
velocity whoami
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### `velocity update`
|
|
89
|
+
|
|
90
|
+
Upgrade the CLI to the latest version on npm. Shells out to
|
|
91
|
+
`npm i -g @oozou/velocity@latest`.
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
velocity update
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Pass `VELOCITY_NO_UPDATE_NOTIFIER=1` to silence the passive
|
|
98
|
+
"update available" prompt the CLI prints on its next run.
|
|
99
|
+
|
|
100
|
+
### `velocity projects`
|
|
101
|
+
|
|
102
|
+
Project listing and the active-project switcher.
|
|
103
|
+
|
|
104
|
+
```
|
|
105
|
+
velocity projects list # all projects you can access
|
|
106
|
+
velocity projects get [slug-or-id] # detail (defaults to active project)
|
|
107
|
+
velocity projects use <slug-or-id> # set the active project
|
|
108
|
+
velocity projects current # show the active project
|
|
109
|
+
velocity projects reset # clear the active project
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### `velocity stories`
|
|
113
|
+
|
|
114
|
+
Stories are addressed by their globally-unique number (`#10634`).
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
velocity stories list
|
|
118
|
+
velocity stories get <number>
|
|
119
|
+
velocity stories create \
|
|
120
|
+
--title "Title" \
|
|
121
|
+
--type feature|bug|chore \
|
|
122
|
+
--status <stage> \
|
|
123
|
+
--priority urgent|high|medium|low \
|
|
124
|
+
[--description "..." | --description-file <path> | --description-stdin] \
|
|
125
|
+
[--assignee <userId>] \
|
|
126
|
+
[--sprint <sprintId>] \
|
|
127
|
+
[--release <releaseId>] \
|
|
128
|
+
[--parent <storyId>] \
|
|
129
|
+
[--points <number>] \
|
|
130
|
+
[--complexity none|low|medium|high]
|
|
131
|
+
velocity stories update <number> [same options as create, all optional;
|
|
132
|
+
pass "null" to clear a relation]
|
|
133
|
+
velocity stories delete <number>
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### `velocity sprints`
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
velocity sprints list # all sprints in active project
|
|
140
|
+
velocity sprints active # current sprint + stories + day totals
|
|
141
|
+
velocity sprints get <sprintId>
|
|
142
|
+
velocity sprints stories <sprintId> # all stories in a sprint
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### `velocity releases`
|
|
146
|
+
|
|
147
|
+
```
|
|
148
|
+
velocity releases list [--include-archived]
|
|
149
|
+
velocity releases get <releaseId>
|
|
150
|
+
velocity releases create \
|
|
151
|
+
--name "v1.2 Launch" \
|
|
152
|
+
--target-date 2026-06-30 \
|
|
153
|
+
[--version 1.2.0] \
|
|
154
|
+
[--description "..." | --description-file <path> | --description-stdin]
|
|
155
|
+
velocity releases update <releaseId> [same options as create, all optional;
|
|
156
|
+
pass "null" to clear]
|
|
157
|
+
velocity releases status <releaseId> planned|in_progress|released|archived
|
|
158
|
+
velocity releases assign <storyNumber> <releaseId>
|
|
159
|
+
velocity releases unassign <storyNumber>
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### `velocity comments`
|
|
163
|
+
|
|
164
|
+
Comments attach to a story (by story number).
|
|
165
|
+
|
|
166
|
+
```
|
|
167
|
+
velocity comments list <storyNumber>
|
|
168
|
+
velocity comments add <storyNumber> "body text"
|
|
169
|
+
velocity comments add <storyNumber> --file ./comment.md
|
|
170
|
+
velocity comments add <storyNumber> --stdin < comment.md
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### `velocity notes`
|
|
174
|
+
|
|
175
|
+
```
|
|
176
|
+
velocity notes list
|
|
177
|
+
velocity notes get <noteId>
|
|
178
|
+
velocity notes create \
|
|
179
|
+
--title "Architecture decisions" \
|
|
180
|
+
[--content "..." | --file <path> | --stdin]
|
|
181
|
+
velocity notes update <noteId> [--title "..."] \
|
|
182
|
+
[--content "..." | --file <path> | --stdin]
|
|
183
|
+
velocity notes delete <noteId>
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### `velocity todos`
|
|
187
|
+
|
|
188
|
+
```
|
|
189
|
+
velocity todos list
|
|
190
|
+
velocity todos create \
|
|
191
|
+
--title "Email Alice" \
|
|
192
|
+
[--priority urgent|high|medium|low] \
|
|
193
|
+
[--due-date 2026-06-15] \
|
|
194
|
+
[--assignee <userId>]
|
|
195
|
+
velocity todos update <todoId> [--title "..."] \
|
|
196
|
+
[--priority ...] [--due-date 2026-06-15 | --due-date null] \
|
|
197
|
+
[--assignee <userId> | --assignee null] \
|
|
198
|
+
[--done]
|
|
199
|
+
velocity todos delete <todoId>
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Project meta
|
|
203
|
+
|
|
204
|
+
Top-level commands that operate on the active project.
|
|
205
|
+
|
|
206
|
+
```
|
|
207
|
+
velocity stats # totals, status breakdown
|
|
208
|
+
velocity activity [--limit N] # recent activity feed
|
|
209
|
+
velocity members # team members
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### `velocity agent-help`
|
|
213
|
+
|
|
214
|
+
Prints a markdown guide intended as model context for AI agents driving the
|
|
215
|
+
CLI. Useful at the top of an agent session:
|
|
216
|
+
|
|
217
|
+
```sh
|
|
218
|
+
velocity agent-help --json
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
## Global flags
|
|
222
|
+
|
|
223
|
+
| Flag | Purpose |
|
|
224
|
+
| --- | --- |
|
|
225
|
+
| `--json` / `--human` | Force output mode regardless of TTY |
|
|
226
|
+
| `--api-base <url>` | Override the API base URL for one invocation |
|
|
227
|
+
| `--project <slug-or-id>` | Override the active project for one invocation |
|
|
228
|
+
|
|
229
|
+
## Environment variables
|
|
230
|
+
|
|
231
|
+
| Variable | Purpose |
|
|
232
|
+
| --- | --- |
|
|
233
|
+
| `VELOCITY_TOKEN` | Bearer token; bypasses the credentials file |
|
|
234
|
+
| `VELOCITY_API_BASE` | Override the API base URL |
|
|
235
|
+
| `VELOCITY_PROJECT` | Override the active project slug or id |
|
|
236
|
+
| `VELOCITY_OUTPUT` | `json` or `human`; forces output mode |
|
|
237
|
+
| `VELOCITY_NO_UPDATE_NOTIFIER` | Set to `1` to silence the update prompt |
|
|
54
238
|
|
|
55
239
|
## License
|
|
56
240
|
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
|
-
import { Command } from "commander";
|
|
4
|
+
import { Command, Option } from "commander";
|
|
5
|
+
import updateNotifier from "update-notifier";
|
|
5
6
|
|
|
6
7
|
// src/commands/auth.ts
|
|
7
8
|
import open from "open";
|
|
@@ -496,7 +497,7 @@ var runReset = async (cmd) => {
|
|
|
496
497
|
);
|
|
497
498
|
};
|
|
498
499
|
var registerEnvCommands = (program2) => {
|
|
499
|
-
const env = program2.command("env").description("Switch between Velocity deployments (production/local)");
|
|
500
|
+
const env = program2.command("env", { hidden: true }).description("Switch between Velocity deployments (production/local)");
|
|
500
501
|
env.command("list").description("List known environments and which one is active").action(async function() {
|
|
501
502
|
try {
|
|
502
503
|
await runList(this);
|
|
@@ -1268,6 +1269,52 @@ var registerProjectMetaCommands = (program2) => {
|
|
|
1268
1269
|
});
|
|
1269
1270
|
};
|
|
1270
1271
|
|
|
1272
|
+
// src/commands/update.ts
|
|
1273
|
+
import { spawn } from "child_process";
|
|
1274
|
+
var PKG = "@oozou/velocity";
|
|
1275
|
+
var runUpdate5 = async (cmd) => {
|
|
1276
|
+
return new Promise((resolve, reject) => {
|
|
1277
|
+
process.stderr.write(
|
|
1278
|
+
`Updating ${PKG} via \`npm i -g ${PKG}@latest\`...
|
|
1279
|
+
`
|
|
1280
|
+
);
|
|
1281
|
+
const proc = spawn(
|
|
1282
|
+
"npm",
|
|
1283
|
+
["i", "-g", `${PKG}@latest`, "--no-update-notifier"],
|
|
1284
|
+
{ stdio: "inherit" }
|
|
1285
|
+
);
|
|
1286
|
+
proc.on("error", (err) => {
|
|
1287
|
+
reject(
|
|
1288
|
+
new Error(
|
|
1289
|
+
`Could not invoke npm: ${err.message}. Run \`npm i -g ${PKG}@latest\` manually.`
|
|
1290
|
+
)
|
|
1291
|
+
);
|
|
1292
|
+
});
|
|
1293
|
+
proc.on("exit", (code) => {
|
|
1294
|
+
if (code === 0) {
|
|
1295
|
+
writeResult(
|
|
1296
|
+
cmd,
|
|
1297
|
+
{ status: "ok", package: PKG },
|
|
1298
|
+
() => `Updated ${PKG} to the latest version on npm.
|
|
1299
|
+
`
|
|
1300
|
+
);
|
|
1301
|
+
resolve();
|
|
1302
|
+
} else {
|
|
1303
|
+
reject(new Error(`npm exited with code ${code}`));
|
|
1304
|
+
}
|
|
1305
|
+
});
|
|
1306
|
+
});
|
|
1307
|
+
};
|
|
1308
|
+
var registerUpdateCommand = (program2) => {
|
|
1309
|
+
program2.command("update").description("Update the Velocity CLI to the latest version on npm").action(async function() {
|
|
1310
|
+
try {
|
|
1311
|
+
await runUpdate5(this);
|
|
1312
|
+
} catch (err) {
|
|
1313
|
+
exitWithError(err, this);
|
|
1314
|
+
}
|
|
1315
|
+
});
|
|
1316
|
+
};
|
|
1317
|
+
|
|
1271
1318
|
// src/commands/agent-help.ts
|
|
1272
1319
|
var HELP_TEXT = `# Velocity CLI agent guide
|
|
1273
1320
|
|
|
@@ -1275,20 +1322,13 @@ The Velocity CLI is a REST client over /api/v1/* with two output modes:
|
|
|
1275
1322
|
- Human (default on a TTY): tabular plain text.
|
|
1276
1323
|
- JSON (default when stdout is piped, or pass --json): a single JSON value per command.
|
|
1277
1324
|
|
|
1278
|
-
## Environments
|
|
1279
|
-
- \`velocity env list\` \u2014 show known envs (production, local) and which is active.
|
|
1280
|
-
- \`velocity env use <name>\` \u2014 set the active env for future invocations.
|
|
1281
|
-
- \`velocity env current\` \u2014 show active env + api base + signed-in state.
|
|
1282
|
-
- \`velocity env reset\` \u2014 clear the active-env file (falls back to production).
|
|
1283
|
-
- \`--env <name>\` flag overrides per-command. \`VELOCITY_ENV\` env var overrides next.
|
|
1284
|
-
|
|
1285
1325
|
## Auth
|
|
1286
1326
|
- \`velocity auth login\` \u2014 opens a browser, polls for approval. Stores creds at
|
|
1287
|
-
~/.config/velocity/credentials
|
|
1327
|
+
~/.config/velocity/credentials.json (mode 0600).
|
|
1288
1328
|
- \`velocity auth logout\` \u2014 deletes the local credentials file.
|
|
1289
1329
|
- \`velocity auth status\` \u2014 show session details. \`velocity whoami\` \u2014 short form.
|
|
1290
|
-
- Headless escape hatch: set \`VELOCITY_TOKEN=vel_\u2026\`.
|
|
1291
|
-
|
|
1330
|
+
- Headless escape hatch: set \`VELOCITY_TOKEN=vel_\u2026\`. \`VELOCITY_API_BASE\`
|
|
1331
|
+
overrides the URL.
|
|
1292
1332
|
|
|
1293
1333
|
## Active project
|
|
1294
1334
|
Most commands need a projectId. Resolution:
|
|
@@ -1300,13 +1340,14 @@ Most commands need a projectId. Resolution:
|
|
|
1300
1340
|
|
|
1301
1341
|
\`\`\`
|
|
1302
1342
|
auth login | logout | status
|
|
1303
|
-
env list | current | use <name> | reset
|
|
1304
1343
|
whoami
|
|
1305
1344
|
|
|
1306
1345
|
projects list
|
|
1307
1346
|
projects get [slug-or-id]
|
|
1308
1347
|
projects use <slug-or-id> | current | reset
|
|
1309
1348
|
|
|
1349
|
+
update # upgrade the CLI to the latest version on npm
|
|
1350
|
+
|
|
1310
1351
|
stories list
|
|
1311
1352
|
stories get <number>
|
|
1312
1353
|
stories create --title --type --status --priority [--description --assignee --sprint --release --parent --points --complexity]
|
|
@@ -1366,9 +1407,24 @@ var registerAgentHelpCommand = (program2) => {
|
|
|
1366
1407
|
};
|
|
1367
1408
|
|
|
1368
1409
|
// src/index.ts
|
|
1369
|
-
var VERSION = "0.1.
|
|
1410
|
+
var VERSION = "0.1.3";
|
|
1411
|
+
if (process.stdout.isTTY && process.env.VELOCITY_NO_UPDATE_NOTIFIER !== "1") {
|
|
1412
|
+
try {
|
|
1413
|
+
updateNotifier({
|
|
1414
|
+
pkg: { name: "@oozou/velocity", version: VERSION },
|
|
1415
|
+
updateCheckInterval: 1e3 * 60 * 60 * 24
|
|
1416
|
+
}).notify({
|
|
1417
|
+
defer: false,
|
|
1418
|
+
message: "Update available {currentVersion} \u2192 {latestVersion}\nRun `velocity update` or `npm i -g {packageName}@latest`"
|
|
1419
|
+
});
|
|
1420
|
+
} catch {
|
|
1421
|
+
}
|
|
1422
|
+
}
|
|
1370
1423
|
var program = new Command();
|
|
1371
|
-
program.name("velocity").description("CLI for Velocity").version(VERSION).option("--json", "force JSON output regardless of TTY", false).option("--human", "force human output regardless of TTY", false).
|
|
1424
|
+
program.name("velocity").description("CLI for Velocity").version(VERSION).option("--json", "force JSON output regardless of TTY", false).option("--human", "force human output regardless of TTY", false).addOption(
|
|
1425
|
+
// Functional but intentionally not surfaced in --help output.
|
|
1426
|
+
new Option("--env <name>", "Target a named env").hideHelp()
|
|
1427
|
+
).option("--api-base <url>", "Override the Velocity API base URL").option("--project <id>", "Target a specific project for this invocation");
|
|
1372
1428
|
registerAuthCommands(program);
|
|
1373
1429
|
registerEnvCommands(program);
|
|
1374
1430
|
registerWhoamiCommand(program);
|
|
@@ -1380,6 +1436,7 @@ registerCommentsCommands(program);
|
|
|
1380
1436
|
registerNotesCommands(program);
|
|
1381
1437
|
registerTodosCommands(program);
|
|
1382
1438
|
registerProjectMetaCommands(program);
|
|
1439
|
+
registerUpdateCommand(program);
|
|
1383
1440
|
registerAgentHelpCommand(program);
|
|
1384
1441
|
program.parseAsync(process.argv).catch((err) => {
|
|
1385
1442
|
writeError(err, program);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oozou/velocity",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Velocity CLI — browser-based auth + REST client for the Velocity project management API.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"homepage": "https://velocity.oozou.com",
|
|
@@ -41,10 +41,12 @@
|
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"commander": "^12.1.0",
|
|
43
43
|
"env-paths": "^3.0.0",
|
|
44
|
-
"open": "^10.1.0"
|
|
44
|
+
"open": "^10.1.0",
|
|
45
|
+
"update-notifier": "^7.3.1"
|
|
45
46
|
},
|
|
46
47
|
"devDependencies": {
|
|
47
48
|
"@types/node": "^20",
|
|
49
|
+
"@types/update-notifier": "^6.0.8",
|
|
48
50
|
"@velocity/shared": "workspace:*",
|
|
49
51
|
"tsup": "^8.3.5",
|
|
50
52
|
"typescript": "^5.9.3"
|