@tmturtle/cli 1.0.1 → 1.0.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 (3) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/dist/tt.js +53 -33
  3. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Trademark Turtle CLI Changelog
2
2
 
3
+ ## v1.0.2 - 2026-07-22
4
+
5
+ - API keys entered through `tt auth set` remain hidden in real terminals.
6
+
3
7
  ## v1.0.1 - 2026-07-22
4
8
 
5
9
  - `tt auth set` now opens a hidden interactive prompt, while `--stdin` remains
package/dist/tt.js CHANGED
@@ -1287,7 +1287,7 @@ function createTmturtleClient({ apiKey, baseUrl }) {
1287
1287
  // package.json
1288
1288
  var package_default = {
1289
1289
  name: "@tmturtle/cli",
1290
- version: "1.0.1",
1290
+ version: "1.0.2",
1291
1291
  description: "Command-line access to Trademark Turtle search, reports, and service status",
1292
1292
  repository: {
1293
1293
  type: "git",
@@ -1397,10 +1397,6 @@ function createMacOsKeychain(command = security) {
1397
1397
  };
1398
1398
  }
1399
1399
 
1400
- // src/prompt.ts
1401
- import { createInterface } from "readline/promises";
1402
- import { Writable } from "stream";
1403
-
1404
1400
  // src/cli-error.ts
1405
1401
  class CliError extends Error {
1406
1402
  code;
@@ -1417,35 +1413,59 @@ class BadRequestError extends CliError {
1417
1413
  }
1418
1414
 
1419
1415
  // src/prompt.ts
1420
- async function readHiddenApiKey(input = process.stdin, output = process.stderr) {
1421
- if (!(input.isTTY && output.isTTY)) {
1422
- throw new BadRequestError("Interactive input requires a terminal; use --stdin instead");
1423
- }
1424
- output.write("API key: ");
1425
- const silentOutput = new Writable({
1426
- write(_chunk, _encoding, callback) {
1427
- callback();
1428
- }
1429
- });
1430
- const prompt = createInterface({ input, output: silentOutput, terminal: true });
1431
- const cancellation = new AbortController;
1432
- const cancel = () => cancellation.abort();
1433
- prompt.once("SIGINT", cancel);
1434
- prompt.once("close", cancel);
1435
- try {
1436
- return await prompt.question("", { signal: cancellation.signal });
1437
- } catch (error) {
1438
- if (cancellation.signal.aborted) {
1439
- throw new BadRequestError("API key input cancelled", { cause: error });
1440
- }
1441
- throw error;
1442
- } finally {
1443
- prompt.off("SIGINT", cancel);
1444
- prompt.off("close", cancel);
1445
- prompt.close();
1446
- output.write(`
1416
+ function readHiddenApiKey(input = process.stdin, output = process.stderr) {
1417
+ if (!(input.isTTY && output.isTTY && input.setRawMode)) {
1418
+ return Promise.reject(new BadRequestError("Interactive input requires a terminal; use --stdin instead"));
1419
+ }
1420
+ const wasFlowing = input.readableFlowing === true;
1421
+ const wasRaw = input.isRaw === true;
1422
+ input.setRawMode(true);
1423
+ return new Promise((resolve, reject) => {
1424
+ const bytes = [];
1425
+ const finish = (result) => {
1426
+ input.removeListener("data", onData);
1427
+ input.removeListener("end", onEnd);
1428
+ input.removeListener("error", onError);
1429
+ if (!wasRaw) {
1430
+ input.setRawMode?.(false);
1431
+ }
1432
+ if (!wasFlowing) {
1433
+ input.pause();
1434
+ }
1435
+ output.write(`
1447
1436
  `);
1448
- }
1437
+ if (result.error) {
1438
+ reject(result.error);
1439
+ } else {
1440
+ resolve(result.value ?? "");
1441
+ }
1442
+ };
1443
+ const cancel = () => finish({ error: new BadRequestError("API key input cancelled") });
1444
+ const onData = (chunk) => {
1445
+ for (const byte of Buffer.from(chunk)) {
1446
+ if (byte === 3 || byte === 4) {
1447
+ cancel();
1448
+ return;
1449
+ }
1450
+ if (byte === 10 || byte === 13) {
1451
+ finish({ value: Buffer.from(bytes).toString("utf8") });
1452
+ return;
1453
+ }
1454
+ if (byte === 8 || byte === 127) {
1455
+ bytes.pop();
1456
+ continue;
1457
+ }
1458
+ bytes.push(byte);
1459
+ }
1460
+ };
1461
+ const onEnd = () => cancel();
1462
+ const onError = (error) => finish({ error });
1463
+ input.on("data", onData);
1464
+ input.once("end", onEnd);
1465
+ input.once("error", onError);
1466
+ input.resume();
1467
+ output.write("API key: ");
1468
+ });
1449
1469
  }
1450
1470
 
1451
1471
  // ../../node_modules/.bun/commander@15.0.0/node_modules/commander/lib/error.js
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tmturtle/cli",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "Command-line access to Trademark Turtle search, reports, and service status",
5
5
  "repository": {
6
6
  "type": "git",