qatools-cli 1.1.7 → 1.1.9

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/package.json +6 -2
  2. package/qatools.js +33 -0
package/package.json CHANGED
@@ -1,9 +1,13 @@
1
1
  {
2
2
  "name": "qatools-cli",
3
- "version": "1.1.7",
3
+ "version": "1.1.9",
4
4
  "description": "CLI for QA Tools — requirements, epics, sprints, sessions, App Context sync, project agenda. The companion to qa-tools.com.",
5
+ "scripts": {
6
+ "release": "npm version patch --no-git-tag-version && npm publish",
7
+ "release:minor": "npm version minor --no-git-tag-version && npm publish"
8
+ },
5
9
  "bin": {
6
- "qatools": "./qatools.js"
10
+ "qatools": "qatools.js"
7
11
  },
8
12
  "files": [
9
13
  "qatools.js"
package/qatools.js CHANGED
@@ -465,6 +465,7 @@ program
465
465
  .option("--parent <label>", "Parent item label (e.g. BUG-5)")
466
466
  .option("--requirement-key <key>", "Requirement key (e.g. auth.login)")
467
467
  .option("--tags <tags>", "Tags (comma-separated)")
468
+ .option("--notify", "Enable email notifications on this item (default off)")
468
469
  .option("-e, --email <email>", "Login email")
469
470
  .option("-p, --password <password>", "Login password")
470
471
  .action(async (options) => {
@@ -486,6 +487,7 @@ program
486
487
  parentId: options.parent || "",
487
488
  requirementKey: options.requirementKey || "",
488
489
  tags: options.tags ? options.tags.split(",").map(t => t.trim().toLowerCase()) : [],
490
+ mailNotify: !!options.notify,
489
491
  });
490
492
  console.log(`Created: ${result.data.type.toUpperCase()}-${result.data.bugNumber} (${result.data.id})`);
491
493
  if (options.tags) console.log(` Tags: ${options.tags}`);
@@ -496,6 +498,33 @@ program
496
498
  process.exit(0);
497
499
  });
498
500
 
501
+ program
502
+ .command("notify")
503
+ .description("Send a deliberate notification email to a project member (respects their opt-out)")
504
+ .requiredOption("--to <email>", "Recipient (must be a member of the project)")
505
+ .requiredOption("--subject <text>", "Email subject")
506
+ .requiredOption("--message <text>", "Email body (plain text)")
507
+ .option("--project <id>", "Target project ID (overrides default)")
508
+ .option("-e, --email <email>", "Login email")
509
+ .option("-p, --password <password>", "Login password")
510
+ .action(async (options) => {
511
+ await authenticate(options);
512
+ const creds = getCredentials();
513
+ const projectId = options.project || creds?.projectId;
514
+ if (!projectId) { console.error("No project configured. Run: qatools setup, or pass --project <id>"); process.exit(1); }
515
+
516
+ const notify = httpsCallable(functions, "notifyUser");
517
+ try {
518
+ const result = await notify({ projectId, to: options.to, subject: options.subject, message: options.message });
519
+ if (result.data.skipped) console.log(`Skipped ${options.to}: ${result.data.reason}`);
520
+ else console.log(`Sent to ${result.data.to}`);
521
+ } catch (e) {
522
+ console.error("Failed:", e.message);
523
+ process.exit(1);
524
+ }
525
+ process.exit(0);
526
+ });
527
+
499
528
  program
500
529
  .command("templates")
501
530
  .description("List templates and their review status")
@@ -1290,6 +1319,7 @@ program
1290
1319
  .option("--requirement-key <key>", "Set requirement key")
1291
1320
  .option("--tags <tags>", "Set tags (comma-separated, replaces existing)")
1292
1321
  .option("--description <text>", "Update description")
1322
+ .option("--notify <on|off>", "Turn item email notifications on/off")
1293
1323
  .option("--author <name>", "Author name for comments (default: your email)", "Claude")
1294
1324
  .option("--skip-test-verification", "Allow setting status=resolved without going through ready_for_test (use only when no test applies). Evidence is still required.")
1295
1325
  .option("--project <id>", "Target project ID (overrides default; needed for status pre-check)")
@@ -1317,6 +1347,7 @@ program
1317
1347
  if (options.requirementKey) u.requirementKey = options.requirementKey;
1318
1348
  if (options.tags) u.tags = options.tags.split(",").map(t => t.trim().toLowerCase());
1319
1349
  if (options.description) u.description = options.description;
1350
+ if (options.notify) u.mailNotify = options.notify === 'on';
1320
1351
  updates[options.id] = u;
1321
1352
  } else {
1322
1353
  console.error("Provide --file or --id");
@@ -2028,6 +2059,7 @@ qatools backlog
2028
2059
  qatools backlog-tags # List existing tags (MUST check before tagging)
2029
2060
  qatools backlog-create -d "..." -t bug --requirement-key <key> --assigned <email> --developer <email> --sprint <id> --tags tag1,tag2
2030
2061
  qatools backlog-update -i <id> --status resolved --sprint <id> --priority 1 --requirement-key <key> --developer <email> --tags tag1,tag2
2062
+ qatools notify --to <email> --subject "..." --message "..." # email a project member directly (e.g. "ready to test"); respects their opt-out
2031
2063
  qatools backlog-duplicates --local # Output for local AI analysis (no API key needed)
2032
2064
  qatools backlog-duplicates # AI-powered duplicate detection (requires API key)
2033
2065
 
@@ -2523,6 +2555,7 @@ export QATOOLS_API_KEY=${apiKey || "<din-nyckel>"}
2523
2555
  - \`qatools template-upload -f file.json\` — upload test template
2524
2556
  - \`qatools backlog-create -d "..." -t bug\` — create backlog item
2525
2557
  - \`qatools backlog-update -i <id> --status resolved --evidence "..."\` — mark resolved (evidence required)
2558
+ - \`qatools notify --to <email> --subject "..." --message "..."\` — email a project member directly (respects opt-out)
2526
2559
  - \`qatools access show\` — view access model
2527
2560
 
2528
2561
  ### Skills