@alphalawyer/alpha-classic-cli 0.1.2 → 0.1.4

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/index.js CHANGED
@@ -19,7 +19,7 @@ function normalizeBaseUrl(value) {
19
19
  }
20
20
 
21
21
  // src/config/environments.ts
22
- var DEFAULT_ENVIRONMENT_NAME = "dev";
22
+ var DEFAULT_ENVIRONMENT_NAME = "prod";
23
23
  var PRESETS = {
24
24
  local: {
25
25
  label: "Local development",
@@ -68,6 +68,16 @@ function getEnvironmentPresetOrThrow(name) {
68
68
  function getDefaultEnvironmentPreset() {
69
69
  return getEnvironmentPresetOrThrow(BUILD_ENVIRONMENT_NAME);
70
70
  }
71
+ async function getCurrentEnvironmentPreset(configReader) {
72
+ const config = await configReader.getConfig();
73
+ const configuredEnvironment = getEnvironmentPreset(config.environment);
74
+ const fallbackEnvironment = getDefaultEnvironmentPreset();
75
+ const environment = configuredEnvironment ?? fallbackEnvironment;
76
+ return {
77
+ ...environment,
78
+ source: configuredEnvironment ? "config" : "default"
79
+ };
80
+ }
71
81
  function normalizePreset(name, preset) {
72
82
  return {
73
83
  name,
@@ -368,6 +378,7 @@ async function createLoginDeviceAuthorization(options, sessionStore) {
368
378
  client: CLIENT_NAME,
369
379
  deviceName: buildDeviceName()
370
380
  });
381
+ const normalizedAuth = normalizeDeviceAuthorizationUrls(auth, context.baseUrl);
371
382
  await sessionStore.saveConfig({
372
383
  environment: context.environment.name,
373
384
  baseUrl: context.baseUrl,
@@ -378,7 +389,7 @@ async function createLoginDeviceAuthorization(options, sessionStore) {
378
389
  baseUrl: context.baseUrl,
379
390
  apiBaseUrl: context.apiBaseUrl,
380
391
  timeoutMs: context.timeoutMs,
381
- auth
392
+ auth: normalizedAuth
382
393
  };
383
394
  }
384
395
  async function pollLoginDeviceAuthorization(options, sessionStore, deviceCode) {
@@ -439,7 +450,7 @@ async function runTokenLogin(options, sessionStore) {
439
450
  if (!options.token) {
440
451
  throw new Error("Missing token.");
441
452
  }
442
- const environment = getDefaultEnvironmentPreset();
453
+ const environment = await getCurrentEnvironmentPreset(sessionStore);
443
454
  const currentUser = await verifyToken(environment.apiBaseUrl, options.token);
444
455
  const currentUserData = getCurrentUserData(currentUser);
445
456
  const userId = options.userId ?? currentUserData?.accid ?? currentUserData?.id ?? currentUserData?.user_id;
@@ -468,9 +479,9 @@ async function runTokenLogin(options, sessionStore) {
468
479
  }
469
480
  async function resolveLoginContext(options, sessionStore) {
470
481
  const config = await sessionStore.getConfig();
471
- const environment = getDefaultEnvironmentPreset();
472
- const baseUrl = normalizeBaseUrl(config.baseUrl ?? environment.baseUrl);
473
- const apiBaseUrl = normalizeBaseUrl(config.apiBaseUrl ?? environment.apiBaseUrl);
482
+ const environment = await getCurrentEnvironmentPreset(sessionStore);
483
+ const baseUrl = normalizeBaseUrl(environment.baseUrl);
484
+ const apiBaseUrl = normalizeBaseUrl(environment.apiBaseUrl);
474
485
  const timeoutMs = options.timeoutMs ?? config.timeoutMs ?? DEFAULT_LOGIN_TIMEOUT_MS;
475
486
  const apiClient = options.apiClient ?? new ApiClient({
476
487
  sessionStore,
@@ -573,6 +584,27 @@ ${qrcode}
573
584
  }
574
585
  emitProgress(reporter, `login: open ${auth.verificationUriComplete}`);
575
586
  }
587
+ function normalizeDeviceAuthorizationUrls(auth, baseUrl) {
588
+ return {
589
+ ...auth,
590
+ ...auth.verificationUri ? { verificationUri: replaceUrlOrigin(auth.verificationUri, baseUrl) } : {},
591
+ verificationUriComplete: replaceUrlOrigin(auth.verificationUriComplete, baseUrl)
592
+ };
593
+ }
594
+ function replaceUrlOrigin(value, baseUrl) {
595
+ if (!value.trim()) {
596
+ return value;
597
+ }
598
+ try {
599
+ const currentUrl = new URL(value);
600
+ const targetUrl = new URL(baseUrl);
601
+ currentUrl.protocol = targetUrl.protocol;
602
+ currentUrl.host = targetUrl.host;
603
+ return currentUrl.toString();
604
+ } catch {
605
+ return new URL(value.startsWith("/") ? value : `/${value}`, baseUrl).toString();
606
+ }
607
+ }
576
608
  function emitProgress(reporter, message) {
577
609
  reporter?.(`[${(/* @__PURE__ */ new Date()).toLocaleTimeString("zh-CN", { hour12: false })}] ${message}`);
578
610
  }
@@ -643,7 +675,7 @@ function printError(type, message, options) {
643
675
  // src/commands/api.ts
644
676
  async function runApiCommand(method, apiPath, options, sessionStore) {
645
677
  const config = await sessionStore.getConfig();
646
- const environment = getDefaultEnvironmentPreset();
678
+ const environment = await getCurrentEnvironmentPreset(sessionStore);
647
679
  const client = new ApiClient({
648
680
  sessionStore,
649
681
  apiBaseUrl: environment.apiBaseUrl,
@@ -694,7 +726,7 @@ async function runApproList(options, sessionStore) {
694
726
  const approTypes = parseNumberList(options.approType);
695
727
  const status = parseApproStatus(options.status);
696
728
  const config = await sessionStore.getConfig();
697
- const environment = getDefaultEnvironmentPreset();
729
+ const environment = await getCurrentEnvironmentPreset(sessionStore);
698
730
  const client = new ApiClient({
699
731
  sessionStore,
700
732
  apiBaseUrl: environment.apiBaseUrl,
@@ -747,7 +779,7 @@ async function runApproList(options, sessionStore) {
747
779
  async function runApproInitiators(options, sessionStore) {
748
780
  const limit = clampLimit(options.limit ?? 50);
749
781
  const config = await sessionStore.getConfig();
750
- const environment = getDefaultEnvironmentPreset();
782
+ const environment = await getCurrentEnvironmentPreset(sessionStore);
751
783
  const client = new ApiClient({
752
784
  sessionStore,
753
785
  apiBaseUrl: environment.apiBaseUrl,
@@ -775,7 +807,7 @@ async function runApproDetail(options, sessionStore) {
775
807
  throw new Error("Missing appro id. Use: alpha-classic-cli appro detail --id <approId>");
776
808
  }
777
809
  const config = await sessionStore.getConfig();
778
- const environment = getDefaultEnvironmentPreset();
810
+ const environment = await getCurrentEnvironmentPreset(sessionStore);
779
811
  const client = new ApiClient({
780
812
  sessionStore,
781
813
  apiBaseUrl: environment.apiBaseUrl,
@@ -1975,8 +2007,8 @@ function clampCommentLimit(limit) {
1975
2007
  }
1976
2008
 
1977
2009
  // src/commands/capabilities.ts
1978
- function runCapabilities(version) {
1979
- const environment = getDefaultEnvironmentPreset();
2010
+ async function runCapabilities(version, sessionStore) {
2011
+ const environment = await getCurrentEnvironmentPreset(sessionStore);
1980
2012
  printSuccess({
1981
2013
  "\u5DE5\u5177": {
1982
2014
  "\u540D\u79F0": "alpha-classic-cli",
@@ -1988,8 +2020,9 @@ function runCapabilities(version) {
1988
2020
  "\u5F53\u524D\u73AF\u5883": environment.name,
1989
2021
  "baseUrl": environment.baseUrl,
1990
2022
  "apiBaseUrl": environment.apiBaseUrl,
1991
- "\u662F\u5426\u6784\u5EFA\u65F6\u9501\u5B9A": true,
1992
- "\u5207\u6362\u65B9\u5F0F": "\u91CD\u65B0\u6784\u5EFA\u5BF9\u5E94\u73AF\u5883\u7248\u672C\uFF0C\u4F8B\u5982 npm run build:dev"
2023
+ "\u662F\u5426\u53EF\u8FD0\u884C\u65F6\u5207\u6362": true,
2024
+ "\u73AF\u5883\u6765\u6E90": environment.source,
2025
+ "\u5207\u6362\u65B9\u5F0F": "alpha-classic-cli env use <local|dev|test|prod>"
1993
2026
  },
1994
2027
  "\u8BA4\u8BC1": {
1995
2028
  "\u68C0\u67E5\u767B\u5F55": "alpha-classic-cli doctor",
@@ -2016,7 +2049,7 @@ function runCapabilities(version) {
2016
2049
  "\u5378\u8F7D Claude Code": "alpha-classic-cli uninstall --agent claude",
2017
2050
  "\u5378\u8F7D Alpha-claw": "alpha-classic-cli uninstall --agent alphaclaw",
2018
2051
  "\u5378\u8F7D\u5168\u90E8": "alpha-classic-cli uninstall --agent all",
2019
- "\u8BF4\u660E": "\u7528\u6237\u81EA\u884C\u9009\u62E9\u5B89\u88C5\u76EE\u6807\uFF1BAlpha-claw \u4F1A\u6309 CLI \u6784\u5EFA\u73AF\u5883\u5B89\u88C5\u5230\u5BF9\u5E94 .openclaw-<env>alphaclaw \u5DE5\u4F5C\u533A\u3002"
2052
+ "\u8BF4\u660E": "\u7528\u6237\u81EA\u884C\u9009\u62E9\u5B89\u88C5\u76EE\u6807\uFF1BAlpha-claw \u4F1A\u5B89\u88C5\u5230\u6240\u6709\u5DF2\u5B58\u5728\u7684 dev\u3001test\u3001prod AlphaClaw workspace\u3002"
2020
2053
  },
2021
2054
  "\u8F93\u51FA\u534F\u8BAE": {
2022
2055
  "\u6210\u529F": { "ok": true, "data": "\u4E1A\u52A1\u6570\u636E" },
@@ -2300,7 +2333,7 @@ function runCapabilities(version) {
2300
2333
  "\u4E0D\u8981\u8F93\u51FA token\u3002",
2301
2334
  "\u4E0D\u8981\u81EA\u884C\u62FC\u63A5\u540E\u7AEF\u63A5\u53E3\uFF0C\u9664\u975E\u7528\u6237\u660E\u786E\u8981\u6C42\u4F7F\u7528 api \u8C03\u8BD5\u547D\u4EE4\u3002",
2302
2335
  "\u4F18\u5148\u4F7F\u7528 capabilities \u4E2D\u58F0\u660E\u7684\u7A33\u5B9A\u4E1A\u52A1\u547D\u4EE4\u3002",
2303
- "\u73AF\u5883\u8FD0\u884C\u65F6\u4E0D\u53EF\u5207\u6362\uFF0C\u907F\u514D\u8BEF\u8FDE dev/prod\u3002"
2336
+ "\u9700\u8981\u5207\u6362\u73AF\u5883\u65F6\u4F7F\u7528 alpha-classic-cli env use\uFF0C\u5E76\u5728\u5207\u6362\u540E\u91CD\u65B0\u767B\u5F55\u3002"
2304
2337
  ]
2305
2338
  });
2306
2339
  }
@@ -2316,7 +2349,7 @@ import fs from "fs/promises";
2316
2349
  import path from "path";
2317
2350
  import { fileURLToPath } from "url";
2318
2351
  var __dirname = path.dirname(fileURLToPath(import.meta.url));
2319
- var SKILL_NAME = "alpha-classic-cli";
2352
+ var SKILL_NAME = "alpha-classic";
2320
2353
  var SKILL_TEMPLATE_ROOT = resolveAssetPath("alpha-classic-skill");
2321
2354
  var CLAUDE_GUIDE_TEMPLATE = path.join(
2322
2355
  resolveAssetPath("claude"),
@@ -2347,25 +2380,71 @@ async function copyDirectory(source, target) {
2347
2380
  }
2348
2381
 
2349
2382
  // src/install/install.ts
2383
+ var ALPHA_CLAW_SKILL_ROOTS = [
2384
+ ".openclaw-devalphaclaw/workspace/skills",
2385
+ ".openclaw-testalphaclaw/workspace/skills",
2386
+ ".openclaw-alphaclaw/workspace/skills"
2387
+ ];
2388
+ var LEGACY_SKILL_NAMES = ["alpha-classic-cli"];
2350
2389
  function resolveCodexSkillPath(homeDir = os2.homedir()) {
2351
2390
  return path2.join(homeDir, ".codex", "skills", SKILL_NAME);
2352
2391
  }
2392
+ function resolveLegacyCodexSkillPaths(homeDir = os2.homedir()) {
2393
+ return LEGACY_SKILL_NAMES.map(
2394
+ (skillName) => path2.join(homeDir, ".codex", "skills", skillName)
2395
+ );
2396
+ }
2353
2397
  function resolveClaudeGuidePath(homeDir = os2.homedir()) {
2354
2398
  return path2.join(homeDir, ".claude", "alpha-classic-cli.md");
2355
2399
  }
2356
2400
  function resolveClaudeMemoryPath(homeDir = os2.homedir()) {
2357
2401
  return path2.join(homeDir, ".claude", "CLAUDE.md");
2358
2402
  }
2359
- function resolveAlphaClawSkillPath(homeDir = os2.homedir()) {
2360
- const environment = getDefaultEnvironmentPreset();
2403
+ function resolveAlphaClawSkillPath(homeDir = os2.homedir(), environmentName = DEFAULT_ENVIRONMENT_NAME) {
2404
+ const environmentRoots = {
2405
+ dev: ".openclaw-devalphaclaw/workspace/skills",
2406
+ test: ".openclaw-testalphaclaw/workspace/skills",
2407
+ prod: ".openclaw-alphaclaw/workspace/skills"
2408
+ };
2409
+ const skillRoot = environmentName === "local" ? environmentRoots.prod : environmentRoots[environmentName];
2361
2410
  return path2.join(
2362
2411
  homeDir,
2363
- `.openclaw-${environment.name}alphaclaw`,
2364
- "workspace",
2365
- "skills",
2412
+ skillRoot,
2366
2413
  SKILL_NAME
2367
2414
  );
2368
2415
  }
2416
+ function resolveAlphaClawSkillPaths(homeDir = os2.homedir()) {
2417
+ return ALPHA_CLAW_SKILL_ROOTS.map(
2418
+ (skillRoot) => path2.join(homeDir, skillRoot, SKILL_NAME)
2419
+ );
2420
+ }
2421
+ async function resolveExistingAlphaClawSkillRoots(homeDir = os2.homedir()) {
2422
+ const skillRoots = ALPHA_CLAW_SKILL_ROOTS.map(
2423
+ (skillRoot) => path2.join(homeDir, skillRoot)
2424
+ );
2425
+ const existingRoots = [];
2426
+ for (const skillRoot of skillRoots) {
2427
+ try {
2428
+ const stat = await fs2.stat(skillRoot);
2429
+ if (stat.isDirectory()) {
2430
+ existingRoots.push(skillRoot);
2431
+ }
2432
+ } catch (error) {
2433
+ const nodeError = error;
2434
+ if (nodeError.code !== "ENOENT") {
2435
+ throw error;
2436
+ }
2437
+ }
2438
+ }
2439
+ return existingRoots;
2440
+ }
2441
+ async function removeLegacySkillDirs(skillRoot) {
2442
+ await Promise.all(
2443
+ LEGACY_SKILL_NAMES.map(
2444
+ (skillName) => fs2.rm(path2.join(skillRoot, skillName), { recursive: true, force: true })
2445
+ )
2446
+ );
2447
+ }
2369
2448
  async function installAgentGuides(options) {
2370
2449
  const agent = options?.agent ?? "codex";
2371
2450
  const result = {
@@ -2385,7 +2464,8 @@ async function installAgentGuides(options) {
2385
2464
  result.claudeMemoryUpdated = claudeResult.claudeMemoryUpdated;
2386
2465
  }
2387
2466
  if (agent === "alphaclaw" || agent === "all") {
2388
- const alphaClawResult = await installAlphaClawSkill(options);
2467
+ const alphaClawResult = await installAlphaClawSkills(options);
2468
+ result.alphaClawSkillPaths = alphaClawResult.alphaClawSkillPaths;
2389
2469
  result.alphaClawSkillPath = alphaClawResult.alphaClawSkillPath;
2390
2470
  result.alphaClawSkillInstalled = alphaClawResult.alphaClawSkillInstalled;
2391
2471
  }
@@ -2399,6 +2479,11 @@ async function uninstallAgentGuides(options) {
2399
2479
  };
2400
2480
  if (agent === "codex" || agent === "all") {
2401
2481
  await fs2.rm(resolveCodexSkillPath(options?.homeDir), { recursive: true, force: true });
2482
+ await Promise.all(
2483
+ resolveLegacyCodexSkillPaths(options?.homeDir).map(
2484
+ (skillPath) => fs2.rm(skillPath, { recursive: true, force: true })
2485
+ )
2486
+ );
2402
2487
  result.codexSkillInstalled = false;
2403
2488
  }
2404
2489
  if (agent === "claude" || agent === "all") {
@@ -2409,8 +2494,18 @@ async function uninstallAgentGuides(options) {
2409
2494
  result.claudeMemoryUpdated = claudeResult.claudeMemoryUpdated;
2410
2495
  }
2411
2496
  if (agent === "alphaclaw" || agent === "all") {
2412
- await fs2.rm(resolveAlphaClawSkillPath(options?.homeDir), { recursive: true, force: true });
2413
- result.alphaClawSkillPath = resolveAlphaClawSkillPath(options?.homeDir);
2497
+ const alphaClawSkillPaths = resolveAlphaClawSkillPaths(options?.homeDir);
2498
+ await Promise.all(
2499
+ alphaClawSkillPaths.concat(
2500
+ ALPHA_CLAW_SKILL_ROOTS.flatMap(
2501
+ (skillRoot) => LEGACY_SKILL_NAMES.map(
2502
+ (skillName) => path2.join(options?.homeDir ?? os2.homedir(), skillRoot, skillName)
2503
+ )
2504
+ )
2505
+ ).map((skillPath) => fs2.rm(skillPath, { recursive: true, force: true }))
2506
+ );
2507
+ result.alphaClawSkillPaths = alphaClawSkillPaths;
2508
+ result.alphaClawSkillPath = alphaClawSkillPaths[0];
2414
2509
  result.alphaClawSkillInstalled = false;
2415
2510
  }
2416
2511
  return result;
@@ -2418,21 +2513,34 @@ async function uninstallAgentGuides(options) {
2418
2513
  async function installCodexSkill(options) {
2419
2514
  const skillPath = resolveCodexSkillPath(options?.homeDir);
2420
2515
  await fs2.rm(skillPath, { recursive: true, force: true });
2516
+ await Promise.all(
2517
+ resolveLegacyCodexSkillPaths(options?.homeDir).map(
2518
+ (legacySkillPath) => fs2.rm(legacySkillPath, { recursive: true, force: true })
2519
+ )
2520
+ );
2421
2521
  await copyDirectory(SKILL_TEMPLATE_ROOT, skillPath);
2422
2522
  return {
2423
2523
  codexSkillPath: skillPath,
2424
2524
  codexSkillInstalled: true
2425
2525
  };
2426
2526
  }
2427
- async function installAlphaClawSkill(options) {
2428
- const skillPath = resolveAlphaClawSkillPath(options?.homeDir);
2429
- await fs2.rm(skillPath, { recursive: true, force: true });
2430
- await copyDirectory(SKILL_TEMPLATE_ROOT, skillPath);
2527
+ async function installAlphaClawSkills(options) {
2528
+ const homeDir = options?.homeDir ?? os2.homedir();
2529
+ const skillRoots = await resolveExistingAlphaClawSkillRoots(homeDir);
2530
+ const skillPaths = [];
2531
+ for (const skillRoot of skillRoots) {
2532
+ const skillPath = path2.join(skillRoot, SKILL_NAME);
2533
+ await fs2.rm(skillPath, { recursive: true, force: true });
2534
+ await removeLegacySkillDirs(skillRoot);
2535
+ await copyDirectory(SKILL_TEMPLATE_ROOT, skillPath);
2536
+ skillPaths.push(skillPath);
2537
+ }
2431
2538
  return {
2432
2539
  codexSkillPath: resolveCodexSkillPath(options?.homeDir),
2433
2540
  codexSkillInstalled: false,
2434
- alphaClawSkillPath: skillPath,
2435
- alphaClawSkillInstalled: true
2541
+ alphaClawSkillPaths: skillPaths,
2542
+ alphaClawSkillPath: skillPaths[0],
2543
+ alphaClawSkillInstalled: skillPaths.length > 0
2436
2544
  };
2437
2545
  }
2438
2546
  async function installClaudeGuide(options) {
@@ -2482,20 +2590,28 @@ async function inspectInstallState(options) {
2482
2590
  } catch {
2483
2591
  claudeGuideInstalled = false;
2484
2592
  }
2485
- const alphaClawSkillPath = resolveAlphaClawSkillPath(options?.homeDir);
2593
+ const alphaClawSkillPath = resolveAlphaClawSkillPath(
2594
+ options?.homeDir,
2595
+ options?.environmentName
2596
+ );
2597
+ const alphaClawSkillPaths = resolveAlphaClawSkillPaths(options?.homeDir);
2598
+ const installedAlphaClawSkillPaths = [];
2486
2599
  let alphaClawSkillInstalled = false;
2487
- try {
2488
- await fs2.access(path2.join(alphaClawSkillPath, "SKILL.md"));
2489
- alphaClawSkillInstalled = true;
2490
- } catch {
2491
- alphaClawSkillInstalled = false;
2600
+ for (const skillPath2 of alphaClawSkillPaths) {
2601
+ try {
2602
+ await fs2.access(path2.join(skillPath2, "SKILL.md"));
2603
+ installedAlphaClawSkillPaths.push(skillPath2);
2604
+ } catch {
2605
+ }
2492
2606
  }
2607
+ alphaClawSkillInstalled = installedAlphaClawSkillPaths.length > 0;
2493
2608
  return {
2494
2609
  codexSkillPath: skillPath,
2495
2610
  codexSkillInstalled: installed,
2496
2611
  claudeGuidePath,
2497
2612
  claudeGuideInstalled,
2498
2613
  claudeMemoryPath: resolveClaudeMemoryPath(options?.homeDir),
2614
+ alphaClawSkillPaths: installedAlphaClawSkillPaths,
2499
2615
  alphaClawSkillPath,
2500
2616
  alphaClawSkillInstalled
2501
2617
  };
@@ -2549,8 +2665,10 @@ async function removeClaudeImport(memoryPath) {
2549
2665
  async function runDoctor(sessionStore) {
2550
2666
  const config = await sessionStore.getConfig();
2551
2667
  let session = await sessionStore.getSession();
2552
- const environment = getDefaultEnvironmentPreset();
2553
- const installState = await inspectInstallState();
2668
+ const environment = await getCurrentEnvironmentPreset(sessionStore);
2669
+ const installState = await inspectInstallState({
2670
+ environmentName: environment.name
2671
+ });
2554
2672
  let apiCheck = {
2555
2673
  ok: false,
2556
2674
  message: "\u672A\u767B\u5F55\u3002\u8BF7\u6267\u884C\uFF1Aalpha-classic-cli login"
@@ -2584,8 +2702,8 @@ async function runDoctor(sessionStore) {
2584
2702
  environment: environment.name,
2585
2703
  baseUrl: environment.baseUrl,
2586
2704
  apiBaseUrl: environment.apiBaseUrl,
2587
- locked: true,
2588
- source: "build",
2705
+ locked: false,
2706
+ source: environment.source,
2589
2707
  configPath: sessionStore.configPath
2590
2708
  },
2591
2709
  session: session ? {
@@ -2633,30 +2751,52 @@ function getCurrentUserData2(response) {
2633
2751
  }
2634
2752
 
2635
2753
  // src/commands/env.ts
2636
- async function runEnvCommand(action, _name, _sessionStore) {
2754
+ async function runEnvCommand(action, name, sessionStore) {
2637
2755
  const normalizedAction = action?.trim().toLowerCase() ?? "current";
2638
2756
  if (normalizedAction === "list") {
2757
+ const currentEnvironment = await getCurrentEnvironmentPreset(sessionStore);
2639
2758
  printSuccess(listEnvironmentPresets(), {
2640
- count: listEnvironmentPresets().length
2759
+ count: listEnvironmentPresets().length,
2760
+ current: currentEnvironment.name
2641
2761
  });
2642
2762
  return;
2643
2763
  }
2644
2764
  if (normalizedAction === "current") {
2645
- const fallback = getDefaultEnvironmentPreset();
2765
+ const currentEnvironment = await getCurrentEnvironmentPreset(sessionStore);
2646
2766
  printSuccess({
2647
- environment: fallback.name,
2648
- label: fallback.label,
2649
- baseUrl: fallback.baseUrl,
2650
- apiBaseUrl: fallback.apiBaseUrl,
2651
- locked: true,
2652
- source: "build"
2767
+ environment: currentEnvironment.name,
2768
+ label: currentEnvironment.label,
2769
+ baseUrl: currentEnvironment.baseUrl,
2770
+ apiBaseUrl: currentEnvironment.apiBaseUrl,
2771
+ locked: false,
2772
+ source: currentEnvironment.source,
2773
+ configPath: sessionStore.configPath
2653
2774
  });
2654
2775
  return;
2655
2776
  }
2656
2777
  if (normalizedAction === "use") {
2657
- throw new Error(
2658
- "env use has been removed. This CLI only exposes env list and env current."
2659
- );
2778
+ if (!name?.trim()) {
2779
+ throw new Error("Missing environment name. Use: alpha-classic-cli env use <local|dev|test|prod>");
2780
+ }
2781
+ const nextEnvironment = getEnvironmentPresetOrThrow(name);
2782
+ await sessionStore.saveConfig({
2783
+ environment: nextEnvironment.name,
2784
+ baseUrl: nextEnvironment.baseUrl,
2785
+ apiBaseUrl: nextEnvironment.apiBaseUrl
2786
+ });
2787
+ await sessionStore.clearAuthState();
2788
+ printSuccess({
2789
+ environment: nextEnvironment.name,
2790
+ label: nextEnvironment.label,
2791
+ baseUrl: nextEnvironment.baseUrl,
2792
+ apiBaseUrl: nextEnvironment.apiBaseUrl,
2793
+ locked: false,
2794
+ source: "config",
2795
+ session: "cleared",
2796
+ hint: "\u73AF\u5883\u5DF2\u5207\u6362\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C alpha-classic-cli login\u3002",
2797
+ configPath: sessionStore.configPath
2798
+ });
2799
+ return;
2660
2800
  }
2661
2801
  throw new Error(`Unknown env action: ${normalizedAction}`);
2662
2802
  }
@@ -2664,7 +2804,7 @@ async function runEnvCommand(action, _name, _sessionStore) {
2664
2804
  // src/commands/matter.ts
2665
2805
  async function runMatterSearch(options, sessionStore) {
2666
2806
  const config = await sessionStore.getConfig();
2667
- const environment = getDefaultEnvironmentPreset();
2807
+ const environment = await getCurrentEnvironmentPreset(sessionStore);
2668
2808
  const client = new ApiClient({
2669
2809
  sessionStore,
2670
2810
  apiBaseUrl: environment.apiBaseUrl,
@@ -2715,7 +2855,7 @@ async function runMatterDetail(options, sessionStore) {
2715
2855
  throw new Error("Missing matter id. Use: alpha-classic-cli matter detail --id <matterId>");
2716
2856
  }
2717
2857
  const config = await sessionStore.getConfig();
2718
- const environment = getDefaultEnvironmentPreset();
2858
+ const environment = await getCurrentEnvironmentPreset(sessionStore);
2719
2859
  const client = new ApiClient({
2720
2860
  sessionStore,
2721
2861
  apiBaseUrl: environment.apiBaseUrl,
@@ -2746,7 +2886,7 @@ async function runMatterTaskList(options, sessionStore) {
2746
2886
  throw new Error("Missing matter id. Use: alpha-classic-cli matter task --id <matterId>");
2747
2887
  }
2748
2888
  const config = await sessionStore.getConfig();
2749
- const environment = getDefaultEnvironmentPreset();
2889
+ const environment = await getCurrentEnvironmentPreset(sessionStore);
2750
2890
  const client = new ApiClient({
2751
2891
  sessionStore,
2752
2892
  apiBaseUrl: environment.apiBaseUrl,
@@ -2798,7 +2938,7 @@ async function runMatterTaskDetail(options, sessionStore) {
2798
2938
  throw new Error("Missing task id. Use: alpha-classic-cli matter task-detail --id <taskId>");
2799
2939
  }
2800
2940
  const config = await sessionStore.getConfig();
2801
- const environment = getDefaultEnvironmentPreset();
2941
+ const environment = await getCurrentEnvironmentPreset(sessionStore);
2802
2942
  const client = new ApiClient({
2803
2943
  sessionStore,
2804
2944
  apiBaseUrl: environment.apiBaseUrl,
@@ -3820,8 +3960,8 @@ function dateFromTimestamp2(timestamp) {
3820
3960
  }
3821
3961
 
3822
3962
  // src/commands/version.ts
3823
- function runVersion(info) {
3824
- const environment = getDefaultEnvironmentPreset();
3963
+ async function runVersion(info, sessionStore) {
3964
+ const environment = await getCurrentEnvironmentPreset(sessionStore);
3825
3965
  printSuccess({
3826
3966
  "\u540D\u79F0": info.name,
3827
3967
  "\u7248\u672C": info.version,
@@ -3829,7 +3969,8 @@ function runVersion(info) {
3829
3969
  "\u73AF\u5883": environment.name,
3830
3970
  "baseUrl": environment.baseUrl,
3831
3971
  "apiBaseUrl": environment.apiBaseUrl,
3832
- "\u73AF\u5883\u662F\u5426\u6784\u5EFA\u65F6\u9501\u5B9A": true
3972
+ "\u73AF\u5883\u662F\u5426\u53EF\u8FD0\u884C\u65F6\u5207\u6362": true,
3973
+ "\u73AF\u5883\u6765\u6E90": environment.source
3833
3974
  });
3834
3975
  }
3835
3976
 
@@ -3914,22 +4055,33 @@ async function main() {
3914
4055
  program.name("alpha-classic-cli").description("Alpha Classic AI-friendly CLI for Alpha web app").version(packageJson.version ?? "0.0.0");
3915
4056
  program.command("install").description("Install agent guides for Codex, Claude Code, Alpha-claw, or all supported agents").option("--agent <agent>", "Agent target: codex, claude, alphaclaw, all", "codex").action(async (options) => {
3916
4057
  const agent = parseAgentInstallTarget(options.agent);
3917
- const result = await installAgentGuides({ agent });
4058
+ const environment = await getCurrentEnvironmentPreset(sessionStore);
4059
+ const result = await installAgentGuides({
4060
+ agent,
4061
+ environmentName: environment.name
4062
+ });
3918
4063
  printSuccess(result);
3919
4064
  });
3920
4065
  program.command("uninstall").description("Uninstall agent guides for Codex, Claude Code, Alpha-claw, or all supported agents").option("--agent <agent>", "Agent target: codex, claude, alphaclaw, all", "codex").action(async (options) => {
3921
4066
  const agent = parseAgentInstallTarget(options.agent);
3922
- const result = await uninstallAgentGuides({ agent });
4067
+ const environment = await getCurrentEnvironmentPreset(sessionStore);
4068
+ const result = await uninstallAgentGuides({
4069
+ agent,
4070
+ environmentName: environment.name
4071
+ });
3923
4072
  printSuccess(result);
3924
4073
  });
3925
- program.command("capabilities").description("Print machine-readable CLI capabilities for agents").action(() => {
3926
- runCapabilities(packageJson.version ?? "0.0.0");
4074
+ program.command("capabilities").description("Print machine-readable CLI capabilities for agents").action(async () => {
4075
+ await runCapabilities(packageJson.version ?? "0.0.0", sessionStore);
3927
4076
  });
3928
- program.command("version").description("Print machine-readable CLI version").action(() => {
3929
- runVersion({
3930
- name: packageJson.name ?? "alpha-classic-cli",
3931
- version: packageJson.version ?? "0.0.0"
3932
- });
4077
+ program.command("version").description("Print machine-readable CLI version").action(async () => {
4078
+ await runVersion(
4079
+ {
4080
+ name: packageJson.name ?? "alpha-classic-cli",
4081
+ version: packageJson.version ?? "0.0.0"
4082
+ },
4083
+ sessionStore
4084
+ );
3933
4085
  });
3934
4086
  program.command("login").description("Start Alpha CLI device authorization login").option("--token <token>", "Debug fallback token").option("--user-id <id>", "Current user id").option("--office-id <id>", "Current office id").option("--name <name>", "Current user name").option("--no-wait", "Create device authorization and print JSON only").option("--json", "Print final result as JSON envelope").option("--device-code <deviceCode>", "Poll an existing device code").option("--timeout-ms <ms>", "Device authorization wait timeout", parseInteger).option("--no-open-browser", "Do not open browser when token is missing").action(
3935
4087
  async (options) => {
@@ -3992,7 +4144,7 @@ async function main() {
3992
4144
  program.command("doctor").description("Inspect config, session, skill install, and API health").action(async () => {
3993
4145
  await runDoctor(sessionStore);
3994
4146
  });
3995
- program.command("env").description("Inspect the build-time environment").argument("[action]", "Action: list, current").argument("[name]", "Environment name for list/current only").action(async (action, name) => {
4147
+ program.command("env").description("Inspect or switch the current environment").argument("[action]", "Action: list, current, use").argument("[name]", "Environment name for env use: local, dev, test, prod").action(async (action, name) => {
3996
4148
  await runEnvCommand(action, name, sessionStore);
3997
4149
  });
3998
4150
  program.command("api").description("Call a raw API endpoint").argument("<method>", "HTTP method").argument("<path>", "API path").option("--params <json>", "Query params JSON object").option("--data <json>", "Request body JSON").action(
@@ -4053,10 +4205,13 @@ async function main() {
4053
4205
  }
4054
4206
  function parseAgentInstallTarget(value) {
4055
4207
  const target = (value ?? "codex").trim().toLowerCase();
4208
+ if (target === "alpha-claw") {
4209
+ return "alphaclaw";
4210
+ }
4056
4211
  if (target === "codex" || target === "claude" || target === "alphaclaw" || target === "all") {
4057
4212
  return target;
4058
4213
  }
4059
- throw new Error(`Invalid agent target: ${value}. Supported: codex, claude, alphaclaw, all`);
4214
+ throw new Error(`Invalid agent target: ${value}. Supported: codex, claude, alphaclaw, alpha-claw, all`);
4060
4215
  }
4061
4216
  main().catch((error) => {
4062
4217
  printError("runtime", error instanceof Error ? error.message : String(error));