archbyte 0.2.8 → 0.2.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/dist/cli/setup.js +80 -13
  2. package/package.json +1 -1
package/dist/cli/setup.js CHANGED
@@ -11,7 +11,7 @@ const __filename = fileURLToPath(import.meta.url);
11
11
  const __dirname = path.dirname(__filename);
12
12
  const PROVIDERS = [
13
13
  { name: "anthropic", label: "Anthropic", hint: "Claude Sonnet / Opus" },
14
- { name: "openai", label: "OpenAI", hint: "Codex / GPT-5.2" },
14
+ { name: "openai", label: "OpenAI", hint: "GPT-5.2 / o4-mini" },
15
15
  { name: "google", label: "Google", hint: "Gemini Flash / Pro" },
16
16
  ];
17
17
  const PROVIDER_MODELS = {
@@ -22,10 +22,9 @@ const PROVIDER_MODELS = {
22
22
  { id: "claude-opus-4-6", label: "Claude Opus 4.6", hint: "Most capable" },
23
23
  ],
24
24
  openai: [
25
- { id: "", label: "Default (recommended)", hint: "Codex for fast agents, GPT-5.2 for connections" },
26
- { id: "gpt-5.2-codex", label: "GPT-5.2 Codex", hint: "Fast, coding-optimized" },
27
- { id: "gpt-5.2", label: "GPT-5.2", hint: "General purpose, thinking model" },
28
- { id: "o3", label: "o3", hint: "Reasoning model" },
25
+ { id: "", label: "Default (recommended)", hint: "GPT-5.2 for all agents" },
26
+ { id: "gpt-5.2", label: "GPT-5.2", hint: "Latest flagship model" },
27
+ { id: "o4-mini", label: "o4-mini", hint: "Fast reasoning model" },
29
28
  ],
30
29
  google: [
31
30
  { id: "", label: "Default (recommended)", hint: "Flash for fast agents, Pro for connections" },
@@ -93,10 +92,47 @@ function askHidden(prompt) {
93
92
  stdin.on("data", onData);
94
93
  });
95
94
  }
96
- async function validateProviderSilent(providerName, apiKey) {
95
+ function askText(prompt) {
96
+ return new Promise((resolve) => {
97
+ process.stdout.write(prompt);
98
+ const stdin = process.stdin;
99
+ const wasRaw = stdin.isRaw;
100
+ stdin.setRawMode(true);
101
+ stdin.resume();
102
+ stdin.setEncoding("utf8");
103
+ let input = "";
104
+ const onData = (data) => {
105
+ for (const ch of data) {
106
+ if (ch === "\n" || ch === "\r" || ch === "\u0004") {
107
+ stdin.setRawMode(wasRaw ?? false);
108
+ stdin.pause();
109
+ stdin.removeListener("data", onData);
110
+ process.stdout.write("\n");
111
+ resolve(input);
112
+ return;
113
+ }
114
+ else if (ch === "\u0003") {
115
+ process.stdout.write("\n");
116
+ process.exit(0);
117
+ }
118
+ else if (ch === "\u007F" || ch === "\b") {
119
+ if (input.length > 0) {
120
+ input = input.slice(0, -1);
121
+ process.stdout.write("\b \b");
122
+ }
123
+ }
124
+ else {
125
+ input += ch;
126
+ process.stdout.write(ch);
127
+ }
128
+ }
129
+ };
130
+ stdin.on("data", onData);
131
+ });
132
+ }
133
+ async function validateProviderSilent(providerName, apiKey, model) {
97
134
  try {
98
135
  const provider = createProvider({ provider: providerName, apiKey });
99
- const model = resolveModel(providerName, "fast");
100
136
  await provider.chat({
101
137
  model,
102
138
  system: "Reply with 'ok'.",
@@ -105,7 +141,11 @@ async function validateProviderSilent(providerName, apiKey) {
105
141
  });
106
142
  return true;
107
143
  }
108
- catch {
144
+ catch (err) {
145
+ if (process.env.ARCHBYTE_DEBUG) {
146
+ const msg = err instanceof Error ? err.message : String(err);
147
+ console.log(chalk.red(`\n Validation error: ${msg}`));
148
+ }
109
149
  return false;
110
150
  }
111
151
  }
@@ -163,7 +203,8 @@ export async function handleSetup() {
163
203
  for (const p of configured) {
164
204
  const active = p === config.provider ? chalk.green(" (active)") : "";
165
205
  const model = profiles[p].model ? chalk.gray(` model: ${profiles[p].model}`) : "";
166
- console.log(chalk.gray(` ${p}: ${maskKey(profiles[p].apiKey)}${model}${active}`));
206
+ const email = profiles[p].email ? chalk.gray(` (${profiles[p].email})`) : "";
207
+ console.log(chalk.gray(` ${p}: ${maskKey(profiles[p].apiKey)}${email}${model}${active}`));
167
208
  }
168
209
  console.log();
169
210
  }
@@ -213,6 +254,30 @@ export async function handleSetup() {
213
254
  if (!profiles[provider])
214
255
  profiles[provider] = { apiKey: "" };
215
256
  profiles[provider].apiKey = apiKey;
257
+ // Step 2b: Email for this provider account (optional)
258
+ const existingEmail = profiles[provider].email;
259
+ if (existingEmail) {
260
+ console.log(chalk.gray(`\n Account email: ${existingEmail}`));
261
+ const emailIdx = await select(" Update email?", [
262
+ `Keep existing ${chalk.gray("(" + existingEmail + ")")}`,
263
+ "Enter new email",
264
+ "Skip",
265
+ ]);
266
+ if (emailIdx === 1) {
267
+ const newEmail = await askText(chalk.bold(" Email: "));
268
+ if (newEmail) {
269
+ profiles[provider].email = newEmail;
270
+ console.log(chalk.green(` ✓ Email: ${newEmail}`));
271
+ }
272
+ }
273
+ }
274
+ else {
275
+ const email = await askText(chalk.bold(` ${selected.label} account email ${chalk.gray("(optional, Enter to skip)")}: `));
276
+ if (email) {
277
+ profiles[provider].email = email;
278
+ console.log(chalk.green(` ✓ Email: ${email}`));
279
+ }
280
+ }
216
281
  // Step 3: Model selection
217
282
  const models = PROVIDER_MODELS[provider];
218
283
  if (models) {
@@ -232,9 +297,11 @@ export async function handleSetup() {
232
297
  }
233
298
  }
234
299
  config.profiles = profiles;
300
+ // Validate with the model the user actually chose
301
+ const validationModel = profiles[provider].model ?? resolveModel(provider, "fast");
235
302
  // Validate provider with spinner
236
- const s = spinner("Validating credentials");
237
- let isValid = await validateProviderSilent(provider, apiKey);
303
+ const s = spinner(`Validating credentials with ${validationModel}`);
304
+ let isValid = await validateProviderSilent(provider, apiKey, validationModel);
238
305
  s.stop(isValid ? "valid" : "invalid", isValid ? "green" : "red");
239
306
  // Retry loop on failure
240
307
  if (!isValid) {
@@ -248,8 +315,8 @@ export async function handleSetup() {
248
315
  profiles[provider].apiKey = newKey;
249
316
  console.log(chalk.green(` ✓ API key: ${maskKey(newKey)}`));
250
317
  }
251
- const s2 = spinner("Validating credentials");
252
- isValid = await validateProviderSilent(provider, profiles[provider].apiKey);
318
+ const s2 = spinner(`Validating credentials with ${validationModel}`);
319
+ isValid = await validateProviderSilent(provider, profiles[provider].apiKey, validationModel);
253
320
  s2.stop(isValid ? "valid" : "invalid", isValid ? "green" : "red");
254
321
  }
255
322
  if (!isValid) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "archbyte",
3
- "version": "0.2.8",
3
+ "version": "0.2.9",
4
4
  "description": "ArchByte - See what agents build. As they build it.",
5
5
  "type": "module",
6
6
  "bin": {