codiedev 0.7.9 → 0.7.10

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/dist/connect.js CHANGED
@@ -42,11 +42,73 @@ const connectFlow_1 = require("./connectFlow");
42
42
  const version_1 = require("./version");
43
43
  const upgradeNudge_1 = require("./upgradeNudge");
44
44
  const BACKEND_URL = process.env.CODIEDEV_URL || "https://judicious-falcon-861.convex.site";
45
- function prompt(rl, question) {
45
+ /**
46
+ * Reads a line from stdin without echoing the typed/pasted characters —
47
+ * for tokens, passwords, anything that shouldn't end up in terminal
48
+ * scrollback or screenshots. Echoes `*` per character so the user gets
49
+ * visual feedback that input is being received.
50
+ *
51
+ * Falls back to the regular `prompt()` if stdin isn't a TTY (e.g., piped
52
+ * input in CI). Without a TTY there's no echo to suppress anyway, and
53
+ * raw mode would error.
54
+ */
55
+ function promptHidden(question) {
46
56
  return new Promise((resolve) => {
47
- rl.question(question, (answer) => {
48
- resolve(answer.trim());
49
- });
57
+ const stdin = process.stdin;
58
+ const stdout = process.stdout;
59
+ if (!stdin.isTTY) {
60
+ // CI / piped input — no terminal to mute. Fall back to readline.
61
+ const rl = readline.createInterface({ input: stdin, output: stdout });
62
+ rl.question(question, (answer) => {
63
+ rl.close();
64
+ resolve(answer.trim());
65
+ });
66
+ return;
67
+ }
68
+ stdout.write(question);
69
+ let buf = "";
70
+ const cleanup = () => {
71
+ stdin.removeListener("data", onData);
72
+ stdin.setRawMode(false);
73
+ stdin.pause();
74
+ };
75
+ const onData = (chunk) => {
76
+ const key = chunk.toString("utf8");
77
+ // Iterate so a single `chunk` containing a multi-char paste still
78
+ // masks each character individually.
79
+ for (const ch of key) {
80
+ // Ctrl+C — abort like a normal terminal interrupt.
81
+ if (ch === "") {
82
+ cleanup();
83
+ stdout.write("\n");
84
+ process.exit(130);
85
+ }
86
+ // Enter — finalize.
87
+ if (ch === "\r" || ch === "\n") {
88
+ cleanup();
89
+ stdout.write("\n");
90
+ resolve(buf.trim());
91
+ return;
92
+ }
93
+ // Backspace / DEL — erase one masked char.
94
+ if (ch === "" || ch === "\b") {
95
+ if (buf.length > 0) {
96
+ buf = buf.slice(0, -1);
97
+ stdout.write("\b \b");
98
+ }
99
+ continue;
100
+ }
101
+ // Ignore other control bytes (escape sequences from arrow keys, etc.)
102
+ if (ch.charCodeAt(0) < 0x20)
103
+ continue;
104
+ buf += ch;
105
+ stdout.write("*");
106
+ }
107
+ };
108
+ stdin.setRawMode(true);
109
+ stdin.resume();
110
+ stdin.setEncoding("utf8");
111
+ stdin.on("data", onData);
50
112
  });
51
113
  }
52
114
  function postJson(url, body) {
@@ -109,16 +171,9 @@ async function runConnect(args = []) {
109
171
  console.log(`Reusing API token from ~/.codiedev/config.json (run with --force to use a new one).\n`);
110
172
  }
111
173
  else {
112
- const rl = readline.createInterface({
113
- input: process.stdin,
114
- output: process.stdout,
115
- });
116
- try {
117
- token = await prompt(rl, "Enter your CodieDev API token: ");
118
- }
119
- finally {
120
- rl.close();
121
- }
174
+ // Hidden prompt — masks the token with `*` as it's typed/pasted so it
175
+ // doesn't end up in terminal scrollback or screenshots.
176
+ token = await promptHidden("Enter your CodieDev API token: ");
122
177
  if (!token) {
123
178
  console.error("Error: API token is required.");
124
179
  process.exit(1);
@@ -0,0 +1 @@
1
+ export declare function maskToken(token: string | null | undefined): string;
package/dist/secret.js ADDED
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ // Display helpers for credential-shaped strings. Use anywhere a token /
3
+ // secret might end up in user-visible output (logs, success lines, error
4
+ // messages) so a stray `console.log` can't leak the full value.
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.maskToken = maskToken;
7
+ const PREFIX_LEN = 12;
8
+ function maskToken(token) {
9
+ if (typeof token !== "string" || token.length === 0)
10
+ return "";
11
+ if (token.length <= PREFIX_LEN)
12
+ return token;
13
+ return `${token.slice(0, PREFIX_LEN)}...`;
14
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codiedev",
3
- "version": "0.7.9",
3
+ "version": "0.7.10",
4
4
  "description": "Connect Claude Code, Codex, Cursor, or VS Code Copilot to CodieDev for org-wide session capture and artifact collaboration",
5
5
  "bin": {
6
6
  "codiedev": "dist/cli.js",