@oozou/velocity 0.1.3 → 0.1.4

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.
Files changed (4) hide show
  1. package/AGENT.md +210 -0
  2. package/SKILL.md +17 -0
  3. package/dist/index.js +26 -83
  4. package/package.json +3 -1
package/AGENT.md ADDED
@@ -0,0 +1,210 @@
1
+ # Velocity CLI — Agent Reference
2
+
3
+ You are operating the `velocity` CLI. This file is the contract — every
4
+ flag, output shape, and failure mode you need is here. If a behavior
5
+ isn't documented below, run `velocity <subcommand> --help` first; don't
6
+ guess.
7
+
8
+ ## Output contract
9
+
10
+ - Mode is **autodetected from TTY**: a non-TTY stdout (i.e. anything
11
+ an agent captures — pipes, subprocess stdout, redirects) gets JSON
12
+ by default. You usually don't need `--json` explicitly.
13
+ - **Pass `--json` anyway** if you want to be defensive against agent
14
+ runtimes that allocate a pty for the subprocess. Cheap insurance.
15
+ - Under JSON mode stdout is exactly one JSON value per command, schema
16
+ stable. Errors print `{"error":"<message>"}` on stderr and exit
17
+ non-zero. Always check the exit code.
18
+ - Don't parse the human view — it's tables and prose, not stable.
19
+
20
+ ## Authentication
21
+
22
+ The CLI must be authenticated before any non-`auth` command. Three ways:
23
+
24
+ 1. `velocity auth login` — opens a browser. Interactive only.
25
+ 2. `VELOCITY_TOKEN=<vel_…>` env var — for headless/CI/agent-runner
26
+ environments. Token is a regular Velocity API token (Settings →
27
+ API Tokens in the web app).
28
+ 3. A previously written credentials file from a prior `auth login`
29
+ (lives at `~/.config/velocity/credentials.json`, mode `0600`).
30
+
31
+ To check: `velocity auth status` returns
32
+ `{"authenticated": true|false, ...}`. If `false`, ask the user to run
33
+ `velocity auth login` — never try to prompt for credentials yourself.
34
+
35
+ `velocity whoami` is the lighter probe: `{authenticated, user}`.
36
+
37
+ ## Project context
38
+
39
+ Most commands operate on a single project. Resolution order:
40
+
41
+ 1. `--project <slug-or-id>` flag on the command.
42
+ 2. `VELOCITY_PROJECT` env var.
43
+ 3. The persisted active project (set by `velocity projects use <slug>`).
44
+
45
+ Projects accept either a slug (`acme-website`) or a Convex `_id`. Slugs
46
+ are returned by `velocity projects list` and are the preferred form.
47
+
48
+ If no project is resolvable the command exits non-zero with
49
+ `{"error":"No project selected..."}`. List options with
50
+ `velocity projects list` and either pass `--project <slug>` or set
51
+ the active project once with `velocity projects use <slug>`.
52
+
53
+ ## Commands
54
+
55
+ All commands send/receive JSON. Examples below assume an authenticated
56
+ session and an active project where relevant.
57
+
58
+ ### Discovery
59
+
60
+ ```
61
+ velocity whoami # → { authenticated, user }
62
+ velocity projects list # → [{_id, slug, name, isActive, client}]
63
+ velocity projects get <slug-or-id> # → full project record
64
+ velocity projects current # → {env, projectId}
65
+ velocity members # → [{_id, name, email, role}]
66
+ velocity stats # → {totals, statusBreakdown, ...}
67
+ velocity activity --limit 20 # → [{type, actor, target, at}]
68
+ ```
69
+
70
+ ### Stories
71
+
72
+ Stories are identified by their globally-unique `number` (an integer like
73
+ `10634`). Use that, not the Convex `_id`.
74
+
75
+ ```
76
+ velocity stories list # → [{_id, number, title, status, priority, type}]
77
+ velocity stories get <number> # → full story (includes assignee, sprint, parent, children)
78
+ velocity stories create \
79
+ --title "Title" \
80
+ --type feature|bug|chore \
81
+ --status <stage> \
82
+ --priority urgent|high|medium|low \
83
+ [--description "..." | --description-file <path> | --description-stdin] \
84
+ [--assignee <userId>] [--sprint <sprintId>] [--release <releaseId>] \
85
+ [--parent <storyId>] [--points <num>] \
86
+ [--complexity none|low|medium|high]
87
+ # → { _id, number, projectId, ... }
88
+
89
+ velocity stories update <number> [same flags as create, all optional;
90
+ pass "null" to clear a relation]
91
+ velocity stories delete <number> # → { status: "ok" }
92
+ ```
93
+
94
+ Valid `--status` values come from the project's configured stages
95
+ (typically `backlog`, `in_progress`, `done`, etc.). On invalid status
96
+ the server returns 400 — read the `error` field for the allowed list.
97
+
98
+ ### Sprints
99
+
100
+ ```
101
+ velocity sprints list # → [{_id, name, startDate, endDate, status}]
102
+ velocity sprints active # → {sprint, stories, totalPoints, donePoints}
103
+ velocity sprints get <sprintId> # → full sprint record + stories
104
+ velocity sprints stories <sprintId> # → [stories assigned to this sprint]
105
+ ```
106
+
107
+ ### Releases
108
+
109
+ ```
110
+ velocity releases list [--include-archived] # → [{_id, name, version, status, targetDate}]
111
+ velocity releases get <releaseId> # → full release + grouped changelog
112
+ velocity releases create \
113
+ --name "v1.2 Launch" \
114
+ --target-date 2026-06-30 \
115
+ [--version 1.2.0] \
116
+ [--description "..." | --description-file <path> | --description-stdin]
117
+ # → { _id, ... }
118
+
119
+ velocity releases update <releaseId> [same flags, all optional]
120
+ velocity releases status <releaseId> planned|in_progress|released|archived
121
+ velocity releases assign <storyNumber> <releaseId>
122
+ velocity releases unassign <storyNumber>
123
+ ```
124
+
125
+ Setting status to `released` or `archived` locks the release — further
126
+ edits are rejected.
127
+
128
+ ### Comments
129
+
130
+ Comments attach to a story (by story number).
131
+
132
+ ```
133
+ velocity comments list <storyNumber> # → [{_id, body, user, _creationTime}]
134
+ velocity comments add <storyNumber> "body"
135
+ velocity comments add <storyNumber> --file ./comment.md
136
+ velocity comments add <storyNumber> --stdin < comment.md
137
+ ```
138
+
139
+ ### Notes
140
+
141
+ ```
142
+ velocity notes list # → [{_id, title, updatedAt}]
143
+ velocity notes get <noteId> # → full note + content (markdown)
144
+ velocity notes create \
145
+ --title "Title" \
146
+ [--content "..." | --file <path> | --stdin]
147
+ velocity notes update <noteId> [--title "..."] \
148
+ [--content "..." | --file <path> | --stdin]
149
+ velocity notes delete <noteId> # → { status: "ok" }
150
+ ```
151
+
152
+ ### Todos
153
+
154
+ ```
155
+ velocity todos list # → [{_id, title, priority, dueDate, done}]
156
+ velocity todos create \
157
+ --title "Title" \
158
+ [--priority urgent|high|medium|low] \
159
+ [--due-date 2026-06-15] [--assignee <userId>]
160
+ velocity todos update <todoId> [--title "..."] \
161
+ [--priority ...] [--due-date <yyyy-mm-dd> | --due-date null] \
162
+ [--assignee <userId> | --assignee null] \
163
+ [--done]
164
+ velocity todos delete <todoId> # → { status: "ok" }
165
+ ```
166
+
167
+ ## Failure modes
168
+
169
+ | Exit code / error fragment | Meaning | What to do |
170
+ | --- | --- | --- |
171
+ | stdout has JSON, exit 0 | Success | Continue. |
172
+ | `"Not authenticated"` | Token missing or revoked | Ask user to run `velocity auth login`. |
173
+ | `"No project selected"` | No active project resolvable | Tell user to run `velocity projects use <slug>` or pass `--project <slug>`. |
174
+ | `"Project not found"` | Bad slug or id | List options via `velocity projects list`. |
175
+ | `"Story not found"` / `"Note not found"` etc. | Bad numeric id / id | Confirm the value via the relevant `list` command. |
176
+ | `"Cannot assign story to a locked release"` | Release is `released`/`archived` | Either pick an unlocked release or unlock it (web UI only). |
177
+ | Any 500 / unexpected error | Server-side issue | Retry once; if persistent, surface to user verbatim. |
178
+
179
+ Always check the exit code before parsing stdout.
180
+
181
+ ## Conventions
182
+
183
+ - Pass long-text inputs (descriptions, note bodies, comment bodies) via
184
+ `--file <path>` or `--stdin` when the content is more than a line —
185
+ it avoids quoting headaches and surfaces shell injection less often.
186
+ - For mutations, prefer named flags over positional arguments. The
187
+ flag names match the field names in the JSON response, so reading
188
+ back what you just wrote is straightforward.
189
+ - To clear an optional relation (assignee, sprint, release, parent,
190
+ due-date), pass `null` as the value: `--assignee null`.
191
+ - Web URLs for stories, notes, and releases are not returned by these
192
+ commands; they're constructed as
193
+ `https://velocity.oozou.com/projects/<projectId>/stories/<number>`
194
+ etc. when you need to link from agent output to the web app.
195
+
196
+ ## Environment variables
197
+
198
+ | Variable | Purpose |
199
+ | --- | --- |
200
+ | `VELOCITY_TOKEN` | Bearer token; bypasses the credentials file. |
201
+ | `VELOCITY_API_BASE` | Override the API base URL. |
202
+ | `VELOCITY_PROJECT` | Override the active project slug or id. |
203
+ | `VELOCITY_OUTPUT` | `json` or `human`; forces output mode. |
204
+ | `VELOCITY_NO_UPDATE_NOTIFIER` | Set to `1` to silence the update prompt. |
205
+
206
+ ## When in doubt
207
+
208
+ Run `velocity <cmd> --help` for the live flag list — it always matches
209
+ the binary you're invoking, even if this file drifts. Then come back
210
+ to this contract for shape and failure-mode details.
package/SKILL.md ADDED
@@ -0,0 +1,17 @@
1
+ ---
2
+ name: velocity
3
+ description: Operate the Velocity CLI to read and manage projects, stories, sprints, releases, notes, todos, and comments. Use whenever the user asks to look at Velocity data or to create/update/delete anything in their Velocity workspace.
4
+ ---
5
+
6
+ # velocity
7
+
8
+ You have access to the `velocity` CLI. It is the sanctioned way to read
9
+ or write Velocity content from a terminal or agent runtime.
10
+
11
+ **Always read [AGENT.md](./AGENT.md) before issuing your first command in
12
+ a session.** It contains the full command surface, the JSON output
13
+ contract, project resolution rules, and the failure modes you will
14
+ hit. Do not guess command names or flag shapes.
15
+
16
+ If `AGENT.md` is not on disk (sandboxed environments), run
17
+ `velocity agent-help` to print the same content to stdout.
package/dist/index.js CHANGED
@@ -1316,90 +1316,33 @@ var registerUpdateCommand = (program2) => {
1316
1316
  };
1317
1317
 
1318
1318
  // src/commands/agent-help.ts
1319
- var HELP_TEXT = `# Velocity CLI agent guide
1320
-
1321
- The Velocity CLI is a REST client over /api/v1/* with two output modes:
1322
- - Human (default on a TTY): tabular plain text.
1323
- - JSON (default when stdout is piped, or pass --json): a single JSON value per command.
1324
-
1325
- ## Auth
1326
- - \`velocity auth login\` \u2014 opens a browser, polls for approval. Stores creds at
1327
- ~/.config/velocity/credentials.json (mode 0600).
1328
- - \`velocity auth logout\` \u2014 deletes the local credentials file.
1329
- - \`velocity auth status\` \u2014 show session details. \`velocity whoami\` \u2014 short form.
1330
- - Headless escape hatch: set \`VELOCITY_TOKEN=vel_\u2026\`. \`VELOCITY_API_BASE\`
1331
- overrides the URL.
1332
-
1333
- ## Active project
1334
- Most commands need a projectId. Resolution:
1335
- 1. \`--project <id>\` flag
1336
- 2. \`VELOCITY_PROJECT\` env var
1337
- 3. The active-project file (\`velocity projects use <slug>\`)
1338
-
1339
- ## Command tree
1340
-
1341
- \`\`\`
1342
- auth login | logout | status
1343
- whoami
1344
-
1345
- projects list
1346
- projects get [slug-or-id]
1347
- projects use <slug-or-id> | current | reset
1348
-
1349
- update # upgrade the CLI to the latest version on npm
1350
-
1351
- stories list
1352
- stories get <number>
1353
- stories create --title --type --status --priority [--description --assignee --sprint --release --parent --points --complexity]
1354
- stories update <number> [--title --description --type --status --priority --assignee --sprint --release --parent --points --complexity]
1355
- stories delete <number>
1356
-
1357
- sprints list
1358
- sprints active
1359
- sprints get <sprintId>
1360
- sprints stories <sprintId>
1361
-
1362
- releases list [--include-archived]
1363
- releases get <releaseId>
1364
- releases create --name --target-date [--version --description]
1365
- releases update <releaseId> [--name --target-date --version --description]
1366
- releases status <releaseId> <planned|in_progress|released|archived>
1367
- releases assign <storyNumber> <releaseId>
1368
- releases unassign <storyNumber>
1369
-
1370
- comments list <storyNumber>
1371
- comments add <storyNumber> <body> | --body | --file | --stdin
1372
-
1373
- notes list
1374
- notes get <noteId>
1375
- notes create --title [--content | --file | --stdin]
1376
- notes update <noteId> [--title --content | --file | --stdin]
1377
- notes delete <noteId>
1378
-
1379
- todos list
1380
- todos create --title [--priority --due-date --assignee]
1381
- todos update <todoId> [--title --priority --due-date --assignee --done]
1382
- todos delete <todoId>
1383
-
1384
- stats
1385
- activity [--limit N]
1386
- members
1387
- \`\`\`
1388
-
1389
- ## Output rules for scripts
1390
- - Stdout: success result (human or JSON depending on TTY / flags / VELOCITY_OUTPUT).
1391
- - Stderr: prompts, errors, browser hints. Never JSON success data.
1392
- - Exit code: 0 on success, non-zero on failure.
1393
- - 401 from any command \u2192 token rotted or revoked. Re-run \`velocity auth login\`.
1394
-
1395
- ## Errors
1396
- JSON mode errors come back as \`{"error":"..."}\` on stderr with a non-zero exit
1397
- code. Human mode prints \`Error: ...\` on stderr.
1398
- `;
1319
+ import { readFile as readFile4 } from "fs/promises";
1320
+ import { fileURLToPath } from "url";
1321
+ import { dirname as dirname3, join as join2 } from "path";
1322
+ var findAgentDoc = async () => {
1323
+ const here = dirname3(fileURLToPath(import.meta.url));
1324
+ const candidates = [
1325
+ join2(here, "..", "AGENT.md"),
1326
+ // dist/index.js ../AGENT.md
1327
+ join2(here, "..", "..", "AGENT.md")
1328
+ // dev: src/commands ../../AGENT.md
1329
+ ];
1330
+ for (const path of candidates) {
1331
+ try {
1332
+ return await readFile4(path, "utf8");
1333
+ } catch {
1334
+ }
1335
+ }
1336
+ throw new Error(
1337
+ "AGENT.md not found. Reinstall the CLI with `npm i -g @oozou/velocity@latest`."
1338
+ );
1339
+ };
1399
1340
  var registerAgentHelpCommand = (program2) => {
1400
- program2.command("agent-help").description("Print a markdown guide for AI agents using the CLI").action(async function() {
1341
+ program2.command("agent-help").description("Print the agent contract (AGENT.md) to stdout").action(async function() {
1401
1342
  try {
1402
- writeResult(this, { markdown: HELP_TEXT }, () => HELP_TEXT);
1343
+ const doc = await findAgentDoc();
1344
+ process.stdout.write(doc);
1345
+ if (!doc.endsWith("\n")) process.stdout.write("\n");
1403
1346
  } catch (err) {
1404
1347
  exitWithError(err, this);
1405
1348
  }
@@ -1407,7 +1350,7 @@ var registerAgentHelpCommand = (program2) => {
1407
1350
  };
1408
1351
 
1409
1352
  // src/index.ts
1410
- var VERSION = "0.1.3";
1353
+ var VERSION = "0.1.4";
1411
1354
  if (process.stdout.isTTY && process.env.VELOCITY_NO_UPDATE_NOTIFIER !== "1") {
1412
1355
  try {
1413
1356
  updateNotifier({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oozou/velocity",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
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",
@@ -25,6 +25,8 @@
25
25
  },
26
26
  "files": [
27
27
  "dist",
28
+ "AGENT.md",
29
+ "SKILL.md",
28
30
  "README.md",
29
31
  "LICENSE"
30
32
  ],