@toothfairyai/tfcode 1.0.0-beta.4 → 1.0.0-beta.6
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/bin/tfcode.js +88 -87
- package/package.json +1 -1
package/bin/tfcode.js
CHANGED
|
@@ -42,47 +42,35 @@ function info(msg) {
|
|
|
42
42
|
|
|
43
43
|
function question(rl, prompt, hidden = false) {
|
|
44
44
|
return new Promise((resolve) => {
|
|
45
|
-
if (hidden) {
|
|
45
|
+
if (hidden && process.stdin.isTTY) {
|
|
46
|
+
// Use simpler approach for hidden input
|
|
46
47
|
process.stdout.write(prompt);
|
|
47
48
|
|
|
48
49
|
let input = '';
|
|
49
50
|
const stdin = process.stdin;
|
|
50
51
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
52
|
+
stdin.setRawMode(true);
|
|
53
|
+
stdin.setEncoding('utf8');
|
|
54
54
|
stdin.resume();
|
|
55
55
|
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
break;
|
|
71
|
-
case '\u0003':
|
|
72
|
-
process.stdout.write('\n');
|
|
73
|
-
process.exit();
|
|
74
|
-
break;
|
|
75
|
-
case '\u007F':
|
|
76
|
-
case '\b':
|
|
77
|
-
input = input.slice(0, -1);
|
|
78
|
-
break;
|
|
79
|
-
default:
|
|
80
|
-
input += c;
|
|
81
|
-
break;
|
|
56
|
+
const onKeypress = (str) => {
|
|
57
|
+
if (str === '\n' || str === '\r' || str === '\u0004') {
|
|
58
|
+
stdin.setRawMode(false);
|
|
59
|
+
stdin.pause();
|
|
60
|
+
stdin.removeListener('data', onKeypress);
|
|
61
|
+
process.stdout.write('\n');
|
|
62
|
+
resolve(input);
|
|
63
|
+
} else if (str === '\u0003') {
|
|
64
|
+
process.stdout.write('\n');
|
|
65
|
+
process.exit();
|
|
66
|
+
} else if (str === '\u007F' || str === '\b') {
|
|
67
|
+
input = input.slice(0, -1);
|
|
68
|
+
} else if (str.length === 1 && str.charCodeAt(0) >= 32) {
|
|
69
|
+
input += str;
|
|
82
70
|
}
|
|
83
71
|
};
|
|
84
72
|
|
|
85
|
-
stdin.on('data',
|
|
73
|
+
stdin.on('data', onKeypress);
|
|
86
74
|
} else {
|
|
87
75
|
rl.question(prompt, (answer) => {
|
|
88
76
|
resolve(answer.trim());
|
|
@@ -101,42 +89,17 @@ function select(prompt, options) {
|
|
|
101
89
|
});
|
|
102
90
|
log('');
|
|
103
91
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
if (stdin.isTTY) {
|
|
110
|
-
stdin.setRawMode(true);
|
|
111
|
-
}
|
|
112
|
-
stdin.resume();
|
|
113
|
-
|
|
114
|
-
const onData = (char) => {
|
|
115
|
-
const c = char.toString('utf8');
|
|
116
|
-
|
|
117
|
-
if (c === '\n' || c === '\r' || c === '\u0004') {
|
|
118
|
-
if (stdin.isTTY) {
|
|
119
|
-
stdin.setRawMode(false);
|
|
120
|
-
}
|
|
121
|
-
stdin.pause();
|
|
122
|
-
stdin.removeListener('data', onData);
|
|
123
|
-
process.stdout.write('\n');
|
|
124
|
-
|
|
125
|
-
const idx = parseInt(input) - 1;
|
|
126
|
-
resolve(idx >= 0 && idx < options.length ? idx : 0);
|
|
127
|
-
} else if (c === '\u0003') {
|
|
128
|
-
process.stdout.write('\n');
|
|
129
|
-
process.exit();
|
|
130
|
-
} else if (c >= '1' && c <= '9') {
|
|
131
|
-
input += c;
|
|
132
|
-
process.stdout.write(c);
|
|
133
|
-
} else if (c === '\u007F' || c === '\b') {
|
|
134
|
-
input = input.slice(0, -1);
|
|
135
|
-
process.stdout.write('\b \b');
|
|
136
|
-
}
|
|
137
|
-
};
|
|
92
|
+
// Create a fresh readline for select
|
|
93
|
+
const rlSelect = readline.createInterface({
|
|
94
|
+
input: process.stdin,
|
|
95
|
+
output: process.stdout
|
|
96
|
+
});
|
|
138
97
|
|
|
139
|
-
|
|
98
|
+
rlSelect.question('Select (1-' + options.length + '): ', (answer) => {
|
|
99
|
+
rlSelect.close();
|
|
100
|
+
const idx = parseInt(answer.trim()) - 1;
|
|
101
|
+
resolve(idx >= 0 && idx < options.length ? idx : 0);
|
|
102
|
+
});
|
|
140
103
|
});
|
|
141
104
|
}
|
|
142
105
|
|
|
@@ -287,11 +250,6 @@ function saveToolsCache(tools) {
|
|
|
287
250
|
}
|
|
288
251
|
|
|
289
252
|
async function interactiveSetup() {
|
|
290
|
-
const rl = readline.createInterface({
|
|
291
|
-
input: process.stdin,
|
|
292
|
-
output: process.stdout
|
|
293
|
-
});
|
|
294
|
-
|
|
295
253
|
log('');
|
|
296
254
|
log(`${COLORS.bold}${COLORS.magenta}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${COLORS.reset}`);
|
|
297
255
|
log(`${COLORS.bold}${COLORS.magenta} tfcode Setup${COLORS.reset}`);
|
|
@@ -303,35 +261,56 @@ async function interactiveSetup() {
|
|
|
303
261
|
log(`${COLORS.dim} https://app.toothfairyai.com → Settings → API Keys${COLORS.reset}`);
|
|
304
262
|
log('');
|
|
305
263
|
|
|
306
|
-
// Workspace ID
|
|
264
|
+
// Step 1: Workspace ID
|
|
307
265
|
log(`${COLORS.bold}Step 1: Workspace ID${COLORS.reset}`);
|
|
308
266
|
log(`${COLORS.dim}This is your workspace UUID (e.g., 12345678-1234-1234-1234-123456789012)${COLORS.reset}`);
|
|
309
267
|
log('');
|
|
310
|
-
|
|
268
|
+
|
|
269
|
+
const workspaceId = await new Promise((resolve) => {
|
|
270
|
+
const rl = readline.createInterface({
|
|
271
|
+
input: process.stdin,
|
|
272
|
+
output: process.stdout
|
|
273
|
+
});
|
|
274
|
+
rl.question('Enter your Workspace ID: ', (answer) => {
|
|
275
|
+
rl.close();
|
|
276
|
+
resolve(answer.trim());
|
|
277
|
+
});
|
|
278
|
+
});
|
|
311
279
|
|
|
312
280
|
if (!workspaceId) {
|
|
313
281
|
error('Workspace ID is required');
|
|
314
|
-
rl.close();
|
|
315
282
|
process.exit(1);
|
|
316
283
|
}
|
|
317
284
|
|
|
318
285
|
log('');
|
|
319
286
|
|
|
320
|
-
// API Key
|
|
287
|
+
// Step 2: API Key
|
|
321
288
|
log(`${COLORS.bold}Step 2: API Key${COLORS.reset}`);
|
|
322
|
-
log(`${COLORS.dim}
|
|
289
|
+
log(`${COLORS.dim}Paste or type your API key${COLORS.reset}`);
|
|
323
290
|
log('');
|
|
324
|
-
|
|
291
|
+
|
|
292
|
+
const apiKey = await new Promise((resolve) => {
|
|
293
|
+
const rl = readline.createInterface({
|
|
294
|
+
input: process.stdin,
|
|
295
|
+
output: process.stdout
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
// Simple approach - just show the input (API keys are long anyway)
|
|
299
|
+
// This allows paste and works reliably
|
|
300
|
+
rl.question('Enter your API Key: ', (answer) => {
|
|
301
|
+
rl.close();
|
|
302
|
+
resolve(answer.trim());
|
|
303
|
+
});
|
|
304
|
+
});
|
|
325
305
|
|
|
326
306
|
if (!apiKey) {
|
|
327
307
|
error('API Key is required');
|
|
328
|
-
rl.close();
|
|
329
308
|
process.exit(1);
|
|
330
309
|
}
|
|
331
310
|
|
|
332
311
|
log('');
|
|
333
312
|
|
|
334
|
-
// Region
|
|
313
|
+
// Step 3: Region
|
|
335
314
|
log(`${COLORS.bold}Step 3: Region${COLORS.reset}`);
|
|
336
315
|
const regions = ['dev (Development)', 'au (Australia)', 'eu (Europe)', 'us (United States)'];
|
|
337
316
|
const regionIdx = await select('Select your region:', regions);
|
|
@@ -349,8 +328,16 @@ async function interactiveSetup() {
|
|
|
349
328
|
log(` Region: ${region}`);
|
|
350
329
|
log('');
|
|
351
330
|
|
|
352
|
-
|
|
353
|
-
|
|
331
|
+
const confirm = await new Promise((resolve) => {
|
|
332
|
+
const rl = readline.createInterface({
|
|
333
|
+
input: process.stdin,
|
|
334
|
+
output: process.stdout
|
|
335
|
+
});
|
|
336
|
+
rl.question('Save these credentials? (Y/n): ', (answer) => {
|
|
337
|
+
rl.close();
|
|
338
|
+
resolve(answer.trim());
|
|
339
|
+
});
|
|
340
|
+
});
|
|
354
341
|
|
|
355
342
|
if (confirm.toLowerCase() !== 'n' && confirm.toLowerCase() !== 'no') {
|
|
356
343
|
const config = { workspace_id: workspaceId, api_key: apiKey, region };
|
|
@@ -359,8 +346,16 @@ async function interactiveSetup() {
|
|
|
359
346
|
log('');
|
|
360
347
|
|
|
361
348
|
// Validate
|
|
362
|
-
|
|
363
|
-
|
|
349
|
+
const testNow = await new Promise((resolve) => {
|
|
350
|
+
const rl = readline.createInterface({
|
|
351
|
+
input: process.stdin,
|
|
352
|
+
output: process.stdout
|
|
353
|
+
});
|
|
354
|
+
rl.question('Validate credentials now? (Y/n): ', (answer) => {
|
|
355
|
+
rl.close();
|
|
356
|
+
resolve(answer.trim());
|
|
357
|
+
});
|
|
358
|
+
});
|
|
364
359
|
|
|
365
360
|
if (testNow.toLowerCase() !== 'n' && testNow.toLowerCase() !== 'no') {
|
|
366
361
|
log('');
|
|
@@ -376,8 +371,16 @@ async function interactiveSetup() {
|
|
|
376
371
|
log(` Workspace ID: ${result.workspace_id}`);
|
|
377
372
|
log('');
|
|
378
373
|
|
|
379
|
-
|
|
380
|
-
|
|
374
|
+
const syncNow = await new Promise((resolve) => {
|
|
375
|
+
const rl = readline.createInterface({
|
|
376
|
+
input: process.stdin,
|
|
377
|
+
output: process.stdout
|
|
378
|
+
});
|
|
379
|
+
rl.question('Sync tools now? (Y/n): ', (answer) => {
|
|
380
|
+
rl.close();
|
|
381
|
+
resolve(answer.trim());
|
|
382
|
+
});
|
|
383
|
+
});
|
|
381
384
|
|
|
382
385
|
if (syncNow.toLowerCase() !== 'n' && syncNow.toLowerCase() !== 'no') {
|
|
383
386
|
log('');
|
|
@@ -433,8 +436,6 @@ async function interactiveSetup() {
|
|
|
433
436
|
} else {
|
|
434
437
|
log('Setup cancelled.');
|
|
435
438
|
}
|
|
436
|
-
|
|
437
|
-
rl.close();
|
|
438
439
|
}
|
|
439
440
|
|
|
440
441
|
const cli = yargs(hideBin(process.argv))
|