copillm 0.3.0-beta.4 → 0.3.0

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.
@@ -1,13 +1,13 @@
1
1
  import { setTimeout as sleep } from "node:timers/promises";
2
2
  import { clearStoredCredential, loadStoredCredential, loadStoredCredentialForAccount, registerExistingCredentialAsDefault, saveStoredCredential } from "../../auth/credentials.js";
3
- import { readAccountsIndex, findAccount, assertValidAccountId, InvalidAccountIdError, UnknownAccountError } from "../../auth/accounts.js";
3
+ import { readAccountsIndex, assertValidAccountId, InvalidAccountIdError, UnknownAccountError } from "../../auth/accounts.js";
4
4
  import { addAccount, listAccountsDetailed, removeAccountAndCredential, removeAllAccounts, switchDefaultAccount } from "../../auth/accountManager.js";
5
5
  import { loginViaDeviceFlow } from "../../auth/deviceFlow.js";
6
6
  import { inspectGithubIdentity } from "../../auth/githubIdentity.js";
7
7
  import { loadConfig } from "../../config/config.js";
8
8
  import { inspectLock, releaseLock } from "../../server/lock.js";
9
9
  import { stopByPid } from "../daemon/lifecycle.js";
10
- import { describeBackend, formatHumanAuthStatusLine } from "../shared/backends.js";
10
+ import { describeBackend } from "../shared/backends.js";
11
11
  import { writeCommandOutput } from "../shared/output.js";
12
12
  /**
13
13
  * Derive a friendly, path-safe account id from the GitHub login behind a token.
@@ -79,8 +79,8 @@ export async function runAuthLogin(opts, options) {
79
79
  }
80
80
  }
81
81
  }
82
- const result = await addAccount({ id: accountId, accountType, token, mode: saveMode });
83
- emitLoginResult(opts, result, false);
82
+ const result = await addAccount({ id: accountId, accountType, token, mode: saveMode, makeDefault: true });
83
+ emitLoginResult(opts, result);
84
84
  return;
85
85
  }
86
86
  // ---- No name: auto-manage by the token's GitHub login -----------------
@@ -95,8 +95,8 @@ export async function runAuthLogin(opts, options) {
95
95
  if (index) {
96
96
  // An index exists but its default account has no credential — restore it.
97
97
  const targetId = newLogin ?? index.defaultAccount;
98
- const result = await addAccount({ id: targetId, accountType, token, mode: saveMode });
99
- emitLoginResult(opts, result, !result.isDefault);
98
+ const result = await addAccount({ id: targetId, accountType, token, mode: saveMode, makeDefault: true });
99
+ emitLoginResult(opts, result);
100
100
  return;
101
101
  }
102
102
  // Fresh single-account install: store without creating an index.
@@ -118,9 +118,10 @@ export async function runAuthLogin(opts, options) {
118
118
  }
119
119
  if (index) {
120
120
  // Add the new login as its own account, or refresh it in place if known.
121
- const wasKnown = findAccount(newLogin) !== null;
122
- const result = await addAccount({ id: newLogin, accountType, token, mode: saveMode });
123
- emitLoginResult(opts, result, !wasKnown && !result.isDefault);
121
+ // The just-signed-in account becomes the default — that's the account you
122
+ // clearly intend to use right now.
123
+ const result = await addAccount({ id: newLogin, accountType, token, mode: saveMode, makeDefault: true });
124
+ emitLoginResult(opts, result);
124
125
  return;
125
126
  }
126
127
  // No index yet. Compare against the existing single account.
@@ -136,17 +137,15 @@ export async function runAuthLogin(opts, options) {
136
137
  return;
137
138
  }
138
139
  // A different (or unverifiable) prior account → transition to multi-account,
139
- // preserving the prior login as the default and adding the new one.
140
+ // preserving the prior login and making the just-signed-in account the
141
+ // default (the one you clearly intend to use now).
140
142
  registerExistingCredentialAsDefault(existingLogin ?? "default", existing.accountType);
141
- const result = await addAccount({ id: newLogin, accountType, token, mode: saveMode });
142
- emitLoginResult(opts, result, !result.isDefault);
143
+ const result = await addAccount({ id: newLogin, accountType, token, mode: saveMode, makeDefault: true });
144
+ emitLoginResult(opts, result);
143
145
  }
144
- function emitLoginResult(opts, result, hintSwitch) {
145
- const defaultSuffix = result.isDefault ? " (default)" : "";
146
- const switchHint = hintSwitch
147
- ? ` It is not the default — run \`copillm auth switch ${result.id}\` to make it so.`
148
- : "";
149
- writeCommandOutput(opts, `Login succeeded for account "${result.id}"${defaultSuffix}. Credentials stored via ${describeBackend(result.backend)}.${switchHint}`, {
146
+ function emitLoginResult(opts, result) {
147
+ const defaultNote = result.isDefault ? " — now the default account" : "";
148
+ writeCommandOutput(opts, `Logged in as "${result.id}"${defaultNote}.`, {
150
149
  status: "ok",
151
150
  action: "login",
152
151
  account: result.id,
@@ -290,14 +289,30 @@ export async function runAuthStatusList(opts) {
290
289
  }, null, 2) + "\n");
291
290
  return { anyStored };
292
291
  }
293
- process.stdout.write(`copillm ${enriched.length} account(s)\n`);
294
- for (const account of enriched) {
292
+ // Human view: lead with the default account (the one in use right now),
293
+ // then a compact, aligned list. Avoid repeating the same login three times —
294
+ // the account id is the handle; show extra detail only when it adds something.
295
+ const ordered = [...enriched].sort((a, b) => Number(b.isDefault) - Number(a.isDefault));
296
+ const idWidth = Math.min(32, Math.max(...ordered.map((a) => a.id.length)));
297
+ const defaultId = listing.defaultAccount ?? ordered.find((a) => a.isDefault)?.id ?? null;
298
+ const header = defaultId
299
+ ? `copillm — ${enriched.length} account${enriched.length === 1 ? "" : "s"} · default: ${defaultId}`
300
+ : `copillm — ${enriched.length} account${enriched.length === 1 ? "" : "s"}`;
301
+ process.stdout.write(`${header}\n\n`);
302
+ for (const account of ordered) {
295
303
  const marker = account.isDefault ? "*" : " ";
296
- const who = account.login ? ` @${account.login}` : "";
297
- const state = account.stored
298
- ? formatHumanAuthStatusLine(account.backend, account.login ? { login: account.login, name: account.name } : null)
299
- : "no credential";
300
- process.stdout.write(`${marker} ${account.id} [${account.accountType}]${who} — ${state}\n`);
304
+ const notes = [];
305
+ if (account.isDefault)
306
+ notes.push("default");
307
+ if (!account.stored)
308
+ notes.push("no credential");
309
+ // Only surface the GitHub login when it differs from the account id (e.g. a
310
+ // custom --as name); otherwise it's redundant.
311
+ if (account.login && account.login !== account.id)
312
+ notes.push(`@${account.login}`);
313
+ const noteStr = notes.length > 0 ? ` (${notes.join(", ")})` : "";
314
+ process.stdout.write(` ${marker} ${account.id.padEnd(idWidth)}${noteStr}\n`);
301
315
  }
316
+ process.stdout.write(`\nSwitch default: copillm auth switch <account> · per launch: --account <account>\n`);
302
317
  return { anyStored };
303
318
  }
@@ -1,7 +1,7 @@
1
1
  import { createRequire } from "node:module";
2
2
  const FALLBACK_PACKAGE_INFO = {
3
3
  name: "copillm",
4
- version: "0.3.0-beta.4"
4
+ version: "0.3.0"
5
5
  };
6
6
  export function getPackageInfo() {
7
7
  const envName = cleanPackageValue(process.env.COPILLM_PACKAGE_NAME);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "copillm",
3
- "version": "0.3.0-beta.4",
3
+ "version": "0.3.0",
4
4
  "description": "Local Copilot proxy CLI (OpenAI/Anthropic-compatible)",
5
5
  "license": "MIT",
6
6
  "type": "module",