@stelfield/cli 0.12.1 → 0.12.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stelfield/cli",
3
- "version": "0.12.1",
3
+ "version": "0.12.3",
4
4
  "description": "Stelfield 平台命令行工具——让任何能执行 shell 命令的 Agent 用一条命令接入 Stelfield:登录、发单接单、管理能力。",
5
5
  "type": "module",
6
6
  "bin": {
package/src/api.js CHANGED
@@ -240,7 +240,7 @@ async function authedRequestWithRefresh(baseUrl, credOpts, httpOpts, makeRequest
240
240
 
241
241
  // ── 命中 401:触发 refresh ────────────────────────────────
242
242
  // 用凭证目录作 key 实现 profile 隔离(不同目录各自独立 refresh)
243
- const credDir = credOpts.dir || process.env.STELFIELD_CONFIG_DIR || (await import('node:os')).homedir() + '/' + BRAND.configDirName;
243
+ const credDir = credOpts.dir || (await import('./profile.js')).configRootFromEnv();
244
244
 
245
245
  const newTokens = await refreshWithDedup(credDir, baseUrl, creds.refresh_token, fetchImpl);
246
246
 
@@ -68,3 +68,4 @@ export function loadCredentials(opts = {}) {
68
68
  return null; // 内容损坏 → 当作未登录
69
69
  }
70
70
  }
71
+
package/src/index.js CHANGED
@@ -12,7 +12,7 @@ import { parseArgs } from './cli-parse.js';
12
12
  import { buildAskQuestions, buildAnswers } from './collab-input.js';
13
13
  import { RETIRED_COMMANDS } from './retired-commands.js';
14
14
  import { resolveBaseUrl } from './config.js';
15
- import { defaultRootDir, isValidProfileName, profileDir, resolveCredDir } from './profile.js';
15
+ import { configRootFromEnv, defaultRootDir, isValidProfileName, profileDir, resolveCredDir } from './profile.js';
16
16
  import { loadCredentials } from './credentials.js';
17
17
  import { runAuthLogin } from './oauth.js';
18
18
  import { runConnect } from './connect.js';
@@ -656,7 +656,7 @@ export async function run(argv, deps = {}) {
656
656
  );
657
657
  return 2;
658
658
  }
659
- profileDirPath = profileDir(flags.profile, { rootDir: env.STELFIELD_CONFIG_DIR || defaultRootDir() });
659
+ profileDirPath = profileDir(flags.profile, { rootDir: configRootFromEnv(env) });
660
660
  }
661
661
 
662
662
  if (command === 'auth:login') {
package/src/profile.js CHANGED
@@ -13,11 +13,28 @@
13
13
  // profile 名限 [A-Za-z0-9._-]{1,32},防止拼出目录穿越路径。
14
14
 
15
15
  import os from 'node:os';
16
+ import fs from 'node:fs';
16
17
  import path from 'node:path';
17
18
 
18
19
  /** 默认(不传 --profile)凭证根目录。 */
19
20
  export function defaultRootDir() {
20
- return path.join(os.homedir(), '.stelfield');
21
+ // An Agent that logged in under the old `linger` command keeps its login in ~/.linger. Use that folder in place
22
+ // (never a copy: the server's refresh token is single-use, so two copies of one login would log each other out
23
+ // while the old and new command run side by side). Fresh installs use ~/.stelfield.
24
+ const fresh = path.join(os.homedir(), '.stelfield');
25
+ const legacy = path.join(os.homedir(), '.linger');
26
+ if (hasLogin(fresh)) return fresh;
27
+ if (hasLogin(legacy)) return legacy;
28
+ return fresh;
29
+ }
30
+
31
+ function hasLogin(dir) {
32
+ return fs.existsSync(path.join(dir, 'credentials')) || fs.existsSync(path.join(dir, 'profiles'));
33
+ }
34
+
35
+ /** Config root named by the environment: STELFIELD_CONFIG_DIR, else the old LINGER_CONFIG_DIR, else the default. */
36
+ export function configRootFromEnv(env = process.env) {
37
+ return env.STELFIELD_CONFIG_DIR || env.LINGER_CONFIG_DIR || defaultRootDir();
21
38
  }
22
39
 
23
40
  /** profile 名合法性(目录名安全子集 · 挡住 ../ 之类)。 */
@@ -54,9 +71,8 @@ export function profileDir(name, opts = {}) {
54
71
  export function resolveCredDir({ dir, profile, env = process.env } = {}) {
55
72
  if (dir) return dir;
56
73
  if (profile != null && profile !== '') {
57
- const root = env.STELFIELD_CONFIG_DIR || defaultRootDir();
74
+ const root = configRootFromEnv(env);
58
75
  return profileDir(profile, { rootDir: root });
59
76
  }
60
- if (env.STELFIELD_CONFIG_DIR) return env.STELFIELD_CONFIG_DIR;
61
- return defaultRootDir();
77
+ return configRootFromEnv(env);
62
78
  }