@oozou/velocity 0.1.0 → 0.1.2

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 (2) hide show
  1. package/dist/index.js +94 -25
  2. package/package.json +5 -4
package/dist/index.js CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  // src/index.ts
4
4
  import { Command } from "commander";
5
+ import updateNotifier from "update-notifier";
5
6
 
6
7
  // src/commands/auth.ts
7
8
  import open from "open";
@@ -177,7 +178,7 @@ var requireProjectId = async (cmd, env) => {
177
178
  const projectId = await resolveProjectId(cmd, env);
178
179
  if (!projectId) {
179
180
  throw new Error(
180
- "No project selected. Pass --project <id> or run `velocity project use <id>`."
181
+ "No project selected. Pass --project <slug-or-id> or run `velocity projects use <slug>`."
181
182
  );
182
183
  }
183
184
  return projectId;
@@ -570,19 +571,19 @@ var registerWhoamiCommand = (program2) => {
570
571
  });
571
572
  };
572
573
 
573
- // src/commands/project.ts
574
+ // src/commands/projects.ts
574
575
  var formatProjectList = (rows) => {
575
576
  if (rows.length === 0) return "No projects.\n";
576
577
  const widths = {
577
- id: Math.max(2, ...rows.map((r) => r._id.length)),
578
+ slug: Math.max(4, ...rows.map((r) => (r.slug ?? "\u2014").length)),
578
579
  name: Math.max(4, ...rows.map((r) => r.name.length))
579
580
  };
580
581
  const lines = [
581
- `${"id".padEnd(widths.id)} ${"name".padEnd(widths.name)} client`
582
+ `${"slug".padEnd(widths.slug)} ${"name".padEnd(widths.name)} client`
582
583
  ];
583
584
  for (const r of rows) {
584
585
  lines.push(
585
- `${r._id.padEnd(widths.id)} ${r.name.padEnd(widths.name)} ${r.client?.name ?? ""}`
586
+ `${(r.slug ?? "\u2014").padEnd(widths.slug)} ${r.name.padEnd(widths.name)} ${r.client?.name ?? ""}`
586
587
  );
587
588
  }
588
589
  return lines.join("\n") + "\n";
@@ -599,21 +600,28 @@ var runGet = async (cmd, id) => {
599
600
  const projectId = id ?? await readActiveProject(envName);
600
601
  if (!projectId) {
601
602
  throw new Error(
602
- "No project id. Pass `velocity project get <id>` or run `velocity project use <id>`."
603
+ "No project id. Pass `velocity projects get <id>` or run `velocity projects use <id>`."
603
604
  );
604
605
  }
605
606
  const project = await fromAuth(auth).get(`/api/v1/projects/${projectId}`);
606
607
  writeResult(cmd, project);
607
608
  };
608
- var runUse2 = async (cmd, id) => {
609
+ var runUse2 = async (cmd, slugOrId) => {
609
610
  const auth = await requireAuth(cmd);
610
- await fromAuth(auth).get(`/api/v1/projects/${id}`);
611
+ const project = await fromAuth(auth).get(
612
+ `/api/v1/projects/${slugOrId}`
613
+ );
611
614
  const envName = await resolveEnvName(cmd);
612
- await writeActiveProject(envName, id);
615
+ await writeActiveProject(envName, project._id);
613
616
  writeResult(
614
617
  cmd,
615
- { projectId: id, env: envName },
616
- (v) => `Active project set to ${v.projectId} (env: ${v.env}).
618
+ {
619
+ projectId: project._id,
620
+ slug: project.slug,
621
+ name: project.name,
622
+ env: envName
623
+ },
624
+ (v) => `Active project set to "${v.name}" (${v.slug ?? v.projectId}) for env ${v.env}.
617
625
  `
618
626
  );
619
627
  };
@@ -624,7 +632,7 @@ var runCurrent2 = async (cmd) => {
624
632
  cmd,
625
633
  { env: envName, projectId },
626
634
  (v) => v.projectId ? `Active project: ${v.projectId} (env: ${v.env})
627
- ` : `No active project for env "${v.env}". Run \`velocity project use <id>\`.
635
+ ` : `No active project for env "${v.env}". Run \`velocity projects use <id>\`.
628
636
  `
629
637
  );
630
638
  };
@@ -638,37 +646,37 @@ var runReset2 = async (cmd) => {
638
646
  `
639
647
  );
640
648
  };
641
- var registerProjectCommands = (program2) => {
642
- const project = program2.command("project").description("Project listing and active-project selection");
643
- project.command("list").description("List accessible projects").action(async function() {
649
+ var registerProjectsCommands = (program2) => {
650
+ const projects = program2.command("projects").description("Project listing and active-project selection");
651
+ projects.command("list").description("List accessible projects").action(async function() {
644
652
  try {
645
653
  await runList2(this);
646
654
  } catch (err) {
647
655
  exitWithError(err, this);
648
656
  }
649
657
  });
650
- project.command("get [id]").description("Show project details (defaults to the active project)").action(async function(id) {
658
+ projects.command("get [id]").description("Show project details (defaults to the active project)").action(async function(id) {
651
659
  try {
652
660
  await runGet(this, id);
653
661
  } catch (err) {
654
662
  exitWithError(err, this);
655
663
  }
656
664
  });
657
- project.command("use <id>").description("Set the active project for the current env").action(async function(id) {
665
+ projects.command("use <slugOrId>").description("Set the active project for the current env (slug or id)").action(async function(id) {
658
666
  try {
659
667
  await runUse2(this, id);
660
668
  } catch (err) {
661
669
  exitWithError(err, this);
662
670
  }
663
671
  });
664
- project.command("current").description("Show the active project for the current env").action(async function() {
672
+ projects.command("current").description("Show the active project for the current env").action(async function() {
665
673
  try {
666
674
  await runCurrent2(this);
667
675
  } catch (err) {
668
676
  exitWithError(err, this);
669
677
  }
670
678
  });
671
- project.command("reset").description("Clear the active project for the current env").action(async function() {
679
+ projects.command("reset").description("Clear the active project for the current env").action(async function() {
672
680
  try {
673
681
  await runReset2(this);
674
682
  } catch (err) {
@@ -1261,6 +1269,52 @@ var registerProjectMetaCommands = (program2) => {
1261
1269
  });
1262
1270
  };
1263
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
+
1264
1318
  // src/commands/agent-help.ts
1265
1319
  var HELP_TEXT = `# Velocity CLI agent guide
1266
1320
 
@@ -1287,7 +1341,7 @@ The Velocity CLI is a REST client over /api/v1/* with two output modes:
1287
1341
  Most commands need a projectId. Resolution:
1288
1342
  1. \`--project <id>\` flag
1289
1343
  2. \`VELOCITY_PROJECT\` env var
1290
- 3. The active-project file (\`velocity project use <id>\`)
1344
+ 3. The active-project file (\`velocity projects use <slug>\`)
1291
1345
 
1292
1346
  ## Command tree
1293
1347
 
@@ -1296,9 +1350,11 @@ auth login | logout | status
1296
1350
  env list | current | use <name> | reset
1297
1351
  whoami
1298
1352
 
1299
- project list
1300
- project get [id]
1301
- project use <id> | current | reset
1353
+ projects list
1354
+ projects get [slug-or-id]
1355
+ projects use <slug-or-id> | current | reset
1356
+
1357
+ update # upgrade the CLI to the latest version on npm
1302
1358
 
1303
1359
  stories list
1304
1360
  stories get <number>
@@ -1359,13 +1415,25 @@ var registerAgentHelpCommand = (program2) => {
1359
1415
  };
1360
1416
 
1361
1417
  // src/index.ts
1362
- var VERSION = "0.1.0";
1418
+ var VERSION = "0.1.2";
1419
+ if (process.stdout.isTTY && process.env.VELOCITY_NO_UPDATE_NOTIFIER !== "1") {
1420
+ try {
1421
+ updateNotifier({
1422
+ pkg: { name: "@oozou/velocity", version: VERSION },
1423
+ updateCheckInterval: 1e3 * 60 * 60 * 24
1424
+ }).notify({
1425
+ defer: false,
1426
+ message: "Update available {currentVersion} \u2192 {latestVersion}\nRun `velocity update` or `npm i -g {packageName}@latest`"
1427
+ });
1428
+ } catch {
1429
+ }
1430
+ }
1363
1431
  var program = new Command();
1364
1432
  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).option("--env <name>", "Target a named env (production, local)").option("--api-base <url>", "Override the Velocity API base URL").option("--project <id>", "Target a specific project for this invocation");
1365
1433
  registerAuthCommands(program);
1366
1434
  registerEnvCommands(program);
1367
1435
  registerWhoamiCommand(program);
1368
- registerProjectCommands(program);
1436
+ registerProjectsCommands(program);
1369
1437
  registerStoriesCommands(program);
1370
1438
  registerSprintsCommands(program);
1371
1439
  registerReleasesCommands(program);
@@ -1373,6 +1441,7 @@ registerCommentsCommands(program);
1373
1441
  registerNotesCommands(program);
1374
1442
  registerTodosCommands(program);
1375
1443
  registerProjectMetaCommands(program);
1444
+ registerUpdateCommand(program);
1376
1445
  registerAgentHelpCommand(program);
1377
1446
  program.parseAsync(process.argv).catch((err) => {
1378
1447
  writeError(err, program);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oozou/velocity",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
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",
@@ -29,8 +29,7 @@
29
29
  "LICENSE"
30
30
  ],
31
31
  "publishConfig": {
32
- "access": "public",
33
- "provenance": true
32
+ "access": "public"
34
33
  },
35
34
  "scripts": {
36
35
  "dev": "tsup --watch",
@@ -42,10 +41,12 @@
42
41
  "dependencies": {
43
42
  "commander": "^12.1.0",
44
43
  "env-paths": "^3.0.0",
45
- "open": "^10.1.0"
44
+ "open": "^10.1.0",
45
+ "update-notifier": "^7.3.1"
46
46
  },
47
47
  "devDependencies": {
48
48
  "@types/node": "^20",
49
+ "@types/update-notifier": "^6.0.8",
49
50
  "@velocity/shared": "workspace:*",
50
51
  "tsup": "^8.3.5",
51
52
  "typescript": "^5.9.3"