@alphalawyer/alpha-classic-cli 0.1.1 → 0.1.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/README.md
CHANGED
|
@@ -5,7 +5,7 @@ Alpha Classic CLI 是为 **Alpha 律所管理系统** 开发的 AI-friendly CLI
|
|
|
5
5
|
- CLI 命令能访问 Web 应用 API
|
|
6
6
|
- Codex 能通过 Skill 理解该怎么调用 CLI
|
|
7
7
|
- 登录、诊断、业务查询形成最小闭环
|
|
8
|
-
-
|
|
8
|
+
- 默认环境是 `prod`,也可以通过 `env use` 在预设环境间切换
|
|
9
9
|
|
|
10
10
|
## 安装依赖
|
|
11
11
|
|
|
@@ -16,10 +16,10 @@ npm install
|
|
|
16
16
|
## 构建
|
|
17
17
|
|
|
18
18
|
```bash
|
|
19
|
-
npm run build
|
|
19
|
+
npm run build
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
默认构建生产环境产物;本地调试也保留按环境构建的脚本:
|
|
23
23
|
|
|
24
24
|
```bash
|
|
25
25
|
npm run build:local
|
|
@@ -28,10 +28,23 @@ npm run build:test
|
|
|
28
28
|
npm run build:prod
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
## 发布到 npm
|
|
32
|
+
|
|
33
|
+
正式发布会使用 `build:prod`,避免把 dev 环境固化进 npm 包。
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npm run release:dry-run
|
|
37
|
+
npm run release:patch
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
- `release:dry-run`:执行类型检查、测试、生产环境构建和 `npm pack --dry-run`,只检查发包内容,不发布。
|
|
41
|
+
- `release:patch`:先确认 npm 登录用户,再完成发布前检查、自动升级补丁版本、重新生产构建并发布到公开 npm 仓库。
|
|
42
|
+
- 如果 npm 要求 OTP,命令后追加参数即可,例如 `npm run release:patch -- --otp=123456`。
|
|
43
|
+
|
|
44
|
+
默认 prod 环境:
|
|
32
45
|
|
|
33
46
|
```text
|
|
34
|
-
baseUrl/apiBaseUrl: https://
|
|
47
|
+
baseUrl/apiBaseUrl: https://alphalawyer.cn
|
|
35
48
|
current user API: GET /im/v1/users/me
|
|
36
49
|
auth header: token: <token>
|
|
37
50
|
device header: deviceType: ai
|
|
@@ -43,7 +56,10 @@ device header: deviceType: ai
|
|
|
43
56
|
|
|
44
57
|
```bash
|
|
45
58
|
alpha-classic-cli version
|
|
59
|
+
alpha-classic-cli env list
|
|
46
60
|
alpha-classic-cli env current
|
|
61
|
+
alpha-classic-cli env use test
|
|
62
|
+
alpha-classic-cli env use prod
|
|
47
63
|
alpha-classic-cli login
|
|
48
64
|
alpha-classic-cli doctor
|
|
49
65
|
alpha-classic-cli matter search --keyword 合同 --limit 10
|
|
@@ -55,7 +71,7 @@ alpha-classic-cli appro initiators --keyword 张三
|
|
|
55
71
|
alpha-classic-cli appro detail --id <审批ID>
|
|
56
72
|
```
|
|
57
73
|
|
|
58
|
-
`env use
|
|
74
|
+
`env use <local|dev|test|prod>` 会写入本地配置并清空旧登录态,切换后需要重新执行 `alpha-classic-cli login`。
|
|
59
75
|
|
|
60
76
|
源码调试时也可以使用:
|
|
61
77
|
|
|
@@ -208,5 +224,5 @@ alpha-classic-cli capabilities
|
|
|
208
224
|
- 默认输出 JSON envelope,方便 AI 解析。
|
|
209
225
|
- 只支持查询,不执行写操作。
|
|
210
226
|
- 不在终端输出 token。
|
|
211
|
-
-
|
|
227
|
+
- 运行时只允许切换内置环境预设,不接受任意 baseUrl/apiBaseUrl 参数。
|
|
212
228
|
- Skill 负责告诉 AI 什么时候用哪个命令。
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
- 使用前先运行 `alpha-classic-cli doctor`。
|
|
11
11
|
- 未登录时提示用户运行 `alpha-classic-cli login`。
|
|
12
12
|
- Agent 异步登录使用 `alpha-classic-cli login --no-wait --json`,把 `data.verification_url` 原样交给用户;用户确认后运行 `alpha-classic-cli login --device-code <device_code>`。
|
|
13
|
-
-
|
|
13
|
+
- 默认环境是 `prod`;如环境不对,使用 `alpha-classic-cli env use <local|dev|test|prod>` 切换,并在切换后重新登录。
|
|
14
14
|
|
|
15
15
|
## 输出处理
|
|
16
16
|
|
|
@@ -107,7 +107,7 @@ alpha-classic-cli appro detail --id <approId> --comments 10
|
|
|
107
107
|
|
|
108
108
|
- 除非用户明确要求做 CLI 开发工作,否则只使用查询 / 读取命令。
|
|
109
109
|
- 不要输出 token 或 refreshToken。
|
|
110
|
-
-
|
|
110
|
+
- 默认环境是 `prod`;需要切换时使用 `alpha-classic-cli env use <local|dev|test|prod>`,切换后重新登录。
|
|
111
111
|
- 优先使用 `matter`,`project` 只是别名。
|
|
112
112
|
- 在项目详情页里,任务表用 `matter task`。
|
|
113
113
|
- 最终回答默认隐藏内部 ID,包括 `项目ID`、`审批ID`、`任务ID`、`流程任务ID`、`节点ID`、`字段ID`、`文件ID`、`评论ID`、`动态ID`;这些只留给后续 CLI 调用。`项目编号`、`审批编号` 这类业务编号可以展示。
|
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 = "
|
|
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,
|
|
@@ -77,7 +87,7 @@ function normalizePreset(name, preset) {
|
|
|
77
87
|
};
|
|
78
88
|
}
|
|
79
89
|
function resolveBuildEnvironmentName() {
|
|
80
|
-
const rawName = "
|
|
90
|
+
const rawName = "prod".trim() ? "prod" : DEFAULT_ENVIRONMENT_NAME;
|
|
81
91
|
const normalized = rawName.trim().toLowerCase();
|
|
82
92
|
if (normalized in PRESETS) {
|
|
83
93
|
return normalized;
|
|
@@ -220,7 +230,7 @@ var ApiClient = class {
|
|
|
220
230
|
if (envelope) {
|
|
221
231
|
const code = envelope.code ?? envelope.resultCode;
|
|
222
232
|
const success = envelope.success ?? envelope.isSuccess;
|
|
223
|
-
if (success !== false && (code === void 0 ||
|
|
233
|
+
if (success !== false && (code === void 0 || isSuccessCode(code))) {
|
|
224
234
|
return envelope.data;
|
|
225
235
|
}
|
|
226
236
|
if (Number(code) === RESULT_CODE_AUTH && retry.allowRefresh) {
|
|
@@ -307,16 +317,20 @@ function asResultEnvelope(value) {
|
|
|
307
317
|
return null;
|
|
308
318
|
}
|
|
309
319
|
const record = value;
|
|
310
|
-
const hasModernEnvelope = typeof record.success === "boolean" && (record.code === void 0 || typeof record.code === "number") && (record.msg === void 0 || typeof record.msg === "string");
|
|
311
|
-
const hasLegacyEnvelope = typeof record.isSuccess === "boolean" && (record.resultCode === void 0 || typeof record.resultCode === "number" || typeof record.resultCode === "string") && (record.resultMsg === void 0 || typeof record.resultMsg === "string");
|
|
320
|
+
const hasModernEnvelope = (typeof record.success === "boolean" || typeof record.code === "number" || typeof record.code === "string") && (record.code === void 0 || typeof record.code === "number" || typeof record.code === "string") && (record.msg === void 0 || typeof record.msg === "string");
|
|
321
|
+
const hasLegacyEnvelope = (typeof record.isSuccess === "boolean" || typeof record.resultCode === "number" || typeof record.resultCode === "string") && (record.resultCode === void 0 || typeof record.resultCode === "number" || typeof record.resultCode === "string") && (record.resultMsg === void 0 || typeof record.resultMsg === "string") && (record.resultMess === void 0 || typeof record.resultMess === "string");
|
|
312
322
|
if ("data" in record && (hasModernEnvelope || hasLegacyEnvelope)) {
|
|
313
323
|
return value;
|
|
314
324
|
}
|
|
315
325
|
return null;
|
|
316
326
|
}
|
|
327
|
+
function isSuccessCode(code) {
|
|
328
|
+
const numericCode2 = Number(code);
|
|
329
|
+
return numericCode2 === 0 || numericCode2 === 1 || numericCode2 === RESULT_CODE_SUCCESS;
|
|
330
|
+
}
|
|
317
331
|
function throwApiEnvelopeError(envelope, status) {
|
|
318
332
|
const code = envelope.code ?? envelope.resultCode;
|
|
319
|
-
const message = envelope.msg ?? envelope.resultMsg ?? envelope.message ?? "API request failed.";
|
|
333
|
+
const message = envelope.msg ?? envelope.resultMsg ?? envelope.resultMess ?? envelope.message ?? "API request failed.";
|
|
320
334
|
if (Number(code) === RESULT_CODE_AUTH) {
|
|
321
335
|
throw new AuthError(message, code, status);
|
|
322
336
|
}
|
|
@@ -364,6 +378,7 @@ async function createLoginDeviceAuthorization(options, sessionStore) {
|
|
|
364
378
|
client: CLIENT_NAME,
|
|
365
379
|
deviceName: buildDeviceName()
|
|
366
380
|
});
|
|
381
|
+
const normalizedAuth = normalizeDeviceAuthorizationUrls(auth, context.baseUrl);
|
|
367
382
|
await sessionStore.saveConfig({
|
|
368
383
|
environment: context.environment.name,
|
|
369
384
|
baseUrl: context.baseUrl,
|
|
@@ -374,7 +389,7 @@ async function createLoginDeviceAuthorization(options, sessionStore) {
|
|
|
374
389
|
baseUrl: context.baseUrl,
|
|
375
390
|
apiBaseUrl: context.apiBaseUrl,
|
|
376
391
|
timeoutMs: context.timeoutMs,
|
|
377
|
-
auth
|
|
392
|
+
auth: normalizedAuth
|
|
378
393
|
};
|
|
379
394
|
}
|
|
380
395
|
async function pollLoginDeviceAuthorization(options, sessionStore, deviceCode) {
|
|
@@ -435,7 +450,7 @@ async function runTokenLogin(options, sessionStore) {
|
|
|
435
450
|
if (!options.token) {
|
|
436
451
|
throw new Error("Missing token.");
|
|
437
452
|
}
|
|
438
|
-
const environment =
|
|
453
|
+
const environment = await getCurrentEnvironmentPreset(sessionStore);
|
|
439
454
|
const currentUser = await verifyToken(environment.apiBaseUrl, options.token);
|
|
440
455
|
const currentUserData = getCurrentUserData(currentUser);
|
|
441
456
|
const userId = options.userId ?? currentUserData?.accid ?? currentUserData?.id ?? currentUserData?.user_id;
|
|
@@ -464,9 +479,9 @@ async function runTokenLogin(options, sessionStore) {
|
|
|
464
479
|
}
|
|
465
480
|
async function resolveLoginContext(options, sessionStore) {
|
|
466
481
|
const config = await sessionStore.getConfig();
|
|
467
|
-
const environment =
|
|
468
|
-
const baseUrl = normalizeBaseUrl(
|
|
469
|
-
const apiBaseUrl = normalizeBaseUrl(
|
|
482
|
+
const environment = await getCurrentEnvironmentPreset(sessionStore);
|
|
483
|
+
const baseUrl = normalizeBaseUrl(environment.baseUrl);
|
|
484
|
+
const apiBaseUrl = normalizeBaseUrl(environment.apiBaseUrl);
|
|
470
485
|
const timeoutMs = options.timeoutMs ?? config.timeoutMs ?? DEFAULT_LOGIN_TIMEOUT_MS;
|
|
471
486
|
const apiClient = options.apiClient ?? new ApiClient({
|
|
472
487
|
sessionStore,
|
|
@@ -569,6 +584,27 @@ ${qrcode}
|
|
|
569
584
|
}
|
|
570
585
|
emitProgress(reporter, `login: open ${auth.verificationUriComplete}`);
|
|
571
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
|
+
}
|
|
572
608
|
function emitProgress(reporter, message) {
|
|
573
609
|
reporter?.(`[${(/* @__PURE__ */ new Date()).toLocaleTimeString("zh-CN", { hour12: false })}] ${message}`);
|
|
574
610
|
}
|
|
@@ -639,7 +675,7 @@ function printError(type, message, options) {
|
|
|
639
675
|
// src/commands/api.ts
|
|
640
676
|
async function runApiCommand(method, apiPath, options, sessionStore) {
|
|
641
677
|
const config = await sessionStore.getConfig();
|
|
642
|
-
const environment =
|
|
678
|
+
const environment = await getCurrentEnvironmentPreset(sessionStore);
|
|
643
679
|
const client = new ApiClient({
|
|
644
680
|
sessionStore,
|
|
645
681
|
apiBaseUrl: environment.apiBaseUrl,
|
|
@@ -649,7 +685,7 @@ async function runApiCommand(method, apiPath, options, sessionStore) {
|
|
|
649
685
|
params: options.params ? parseJsonObject(options.params, "--params") : void 0,
|
|
650
686
|
data: options.data ? JSON.parse(options.data) : void 0
|
|
651
687
|
});
|
|
652
|
-
printSuccess(data);
|
|
688
|
+
printSuccess(redactSensitiveData(data));
|
|
653
689
|
}
|
|
654
690
|
function parseJsonObject(value, flagName) {
|
|
655
691
|
const parsed = JSON.parse(value);
|
|
@@ -658,6 +694,23 @@ function parseJsonObject(value, flagName) {
|
|
|
658
694
|
}
|
|
659
695
|
return parsed;
|
|
660
696
|
}
|
|
697
|
+
function redactSensitiveData(value) {
|
|
698
|
+
if (Array.isArray(value)) {
|
|
699
|
+
return value.map(redactSensitiveData);
|
|
700
|
+
}
|
|
701
|
+
if (!value || typeof value !== "object") {
|
|
702
|
+
return value;
|
|
703
|
+
}
|
|
704
|
+
return Object.fromEntries(
|
|
705
|
+
Object.entries(value).map(([key, item]) => [
|
|
706
|
+
key,
|
|
707
|
+
isSensitiveKey(key) ? "[REDACTED]" : redactSensitiveData(item)
|
|
708
|
+
])
|
|
709
|
+
);
|
|
710
|
+
}
|
|
711
|
+
function isSensitiveKey(key) {
|
|
712
|
+
return key.toLowerCase().includes("token");
|
|
713
|
+
}
|
|
661
714
|
|
|
662
715
|
// src/commands/appro.ts
|
|
663
716
|
var APPRO_SCOPE_TO_ENUM = {
|
|
@@ -673,7 +726,7 @@ async function runApproList(options, sessionStore) {
|
|
|
673
726
|
const approTypes = parseNumberList(options.approType);
|
|
674
727
|
const status = parseApproStatus(options.status);
|
|
675
728
|
const config = await sessionStore.getConfig();
|
|
676
|
-
const environment =
|
|
729
|
+
const environment = await getCurrentEnvironmentPreset(sessionStore);
|
|
677
730
|
const client = new ApiClient({
|
|
678
731
|
sessionStore,
|
|
679
732
|
apiBaseUrl: environment.apiBaseUrl,
|
|
@@ -726,7 +779,7 @@ async function runApproList(options, sessionStore) {
|
|
|
726
779
|
async function runApproInitiators(options, sessionStore) {
|
|
727
780
|
const limit = clampLimit(options.limit ?? 50);
|
|
728
781
|
const config = await sessionStore.getConfig();
|
|
729
|
-
const environment =
|
|
782
|
+
const environment = await getCurrentEnvironmentPreset(sessionStore);
|
|
730
783
|
const client = new ApiClient({
|
|
731
784
|
sessionStore,
|
|
732
785
|
apiBaseUrl: environment.apiBaseUrl,
|
|
@@ -754,7 +807,7 @@ async function runApproDetail(options, sessionStore) {
|
|
|
754
807
|
throw new Error("Missing appro id. Use: alpha-classic-cli appro detail --id <approId>");
|
|
755
808
|
}
|
|
756
809
|
const config = await sessionStore.getConfig();
|
|
757
|
-
const environment =
|
|
810
|
+
const environment = await getCurrentEnvironmentPreset(sessionStore);
|
|
758
811
|
const client = new ApiClient({
|
|
759
812
|
sessionStore,
|
|
760
813
|
apiBaseUrl: environment.apiBaseUrl,
|
|
@@ -1954,8 +2007,8 @@ function clampCommentLimit(limit) {
|
|
|
1954
2007
|
}
|
|
1955
2008
|
|
|
1956
2009
|
// src/commands/capabilities.ts
|
|
1957
|
-
function runCapabilities(version) {
|
|
1958
|
-
const environment =
|
|
2010
|
+
async function runCapabilities(version, sessionStore) {
|
|
2011
|
+
const environment = await getCurrentEnvironmentPreset(sessionStore);
|
|
1959
2012
|
printSuccess({
|
|
1960
2013
|
"\u5DE5\u5177": {
|
|
1961
2014
|
"\u540D\u79F0": "alpha-classic-cli",
|
|
@@ -1967,8 +2020,9 @@ function runCapabilities(version) {
|
|
|
1967
2020
|
"\u5F53\u524D\u73AF\u5883": environment.name,
|
|
1968
2021
|
"baseUrl": environment.baseUrl,
|
|
1969
2022
|
"apiBaseUrl": environment.apiBaseUrl,
|
|
1970
|
-
"\u662F\u5426\
|
|
1971
|
-
"\
|
|
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>"
|
|
1972
2026
|
},
|
|
1973
2027
|
"\u8BA4\u8BC1": {
|
|
1974
2028
|
"\u68C0\u67E5\u767B\u5F55": "alpha-classic-cli doctor",
|
|
@@ -1995,7 +2049,7 @@ function runCapabilities(version) {
|
|
|
1995
2049
|
"\u5378\u8F7D Claude Code": "alpha-classic-cli uninstall --agent claude",
|
|
1996
2050
|
"\u5378\u8F7D Alpha-claw": "alpha-classic-cli uninstall --agent alphaclaw",
|
|
1997
2051
|
"\u5378\u8F7D\u5168\u90E8": "alpha-classic-cli uninstall --agent all",
|
|
1998
|
-
"\u8BF4\u660E": "\u7528\u6237\u81EA\u884C\u9009\u62E9\u5B89\u88C5\u76EE\u6807\uFF1BAlpha-claw \u4F1A\u6309 CLI \
|
|
2052
|
+
"\u8BF4\u660E": "\u7528\u6237\u81EA\u884C\u9009\u62E9\u5B89\u88C5\u76EE\u6807\uFF1BAlpha-claw \u4F1A\u6309\u5F53\u524D CLI \u73AF\u5883\u5B89\u88C5\u5230\u5BF9\u5E94 .openclaw-<env>alphaclaw \u5DE5\u4F5C\u533A\u3002"
|
|
1999
2053
|
},
|
|
2000
2054
|
"\u8F93\u51FA\u534F\u8BAE": {
|
|
2001
2055
|
"\u6210\u529F": { "ok": true, "data": "\u4E1A\u52A1\u6570\u636E" },
|
|
@@ -2279,7 +2333,7 @@ function runCapabilities(version) {
|
|
|
2279
2333
|
"\u4E0D\u8981\u8F93\u51FA token\u3002",
|
|
2280
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",
|
|
2281
2335
|
"\u4F18\u5148\u4F7F\u7528 capabilities \u4E2D\u58F0\u660E\u7684\u7A33\u5B9A\u4E1A\u52A1\u547D\u4EE4\u3002",
|
|
2282
|
-
"\u73AF\u5883\
|
|
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"
|
|
2283
2337
|
]
|
|
2284
2338
|
});
|
|
2285
2339
|
}
|
|
@@ -2335,11 +2389,10 @@ function resolveClaudeGuidePath(homeDir = os2.homedir()) {
|
|
|
2335
2389
|
function resolveClaudeMemoryPath(homeDir = os2.homedir()) {
|
|
2336
2390
|
return path2.join(homeDir, ".claude", "CLAUDE.md");
|
|
2337
2391
|
}
|
|
2338
|
-
function resolveAlphaClawSkillPath(homeDir = os2.homedir()) {
|
|
2339
|
-
const environment = getDefaultEnvironmentPreset();
|
|
2392
|
+
function resolveAlphaClawSkillPath(homeDir = os2.homedir(), environmentName = DEFAULT_ENVIRONMENT_NAME) {
|
|
2340
2393
|
return path2.join(
|
|
2341
2394
|
homeDir,
|
|
2342
|
-
`.openclaw-${
|
|
2395
|
+
`.openclaw-${environmentName}alphaclaw`,
|
|
2343
2396
|
"workspace",
|
|
2344
2397
|
"skills",
|
|
2345
2398
|
SKILL_NAME
|
|
@@ -2388,8 +2441,8 @@ async function uninstallAgentGuides(options) {
|
|
|
2388
2441
|
result.claudeMemoryUpdated = claudeResult.claudeMemoryUpdated;
|
|
2389
2442
|
}
|
|
2390
2443
|
if (agent === "alphaclaw" || agent === "all") {
|
|
2391
|
-
await fs2.rm(resolveAlphaClawSkillPath(options?.homeDir), { recursive: true, force: true });
|
|
2392
|
-
result.alphaClawSkillPath = resolveAlphaClawSkillPath(options?.homeDir);
|
|
2444
|
+
await fs2.rm(resolveAlphaClawSkillPath(options?.homeDir, options?.environmentName), { recursive: true, force: true });
|
|
2445
|
+
result.alphaClawSkillPath = resolveAlphaClawSkillPath(options?.homeDir, options?.environmentName);
|
|
2393
2446
|
result.alphaClawSkillInstalled = false;
|
|
2394
2447
|
}
|
|
2395
2448
|
return result;
|
|
@@ -2404,7 +2457,7 @@ async function installCodexSkill(options) {
|
|
|
2404
2457
|
};
|
|
2405
2458
|
}
|
|
2406
2459
|
async function installAlphaClawSkill(options) {
|
|
2407
|
-
const skillPath = resolveAlphaClawSkillPath(options?.homeDir);
|
|
2460
|
+
const skillPath = resolveAlphaClawSkillPath(options?.homeDir, options?.environmentName);
|
|
2408
2461
|
await fs2.rm(skillPath, { recursive: true, force: true });
|
|
2409
2462
|
await copyDirectory(SKILL_TEMPLATE_ROOT, skillPath);
|
|
2410
2463
|
return {
|
|
@@ -2461,7 +2514,7 @@ async function inspectInstallState(options) {
|
|
|
2461
2514
|
} catch {
|
|
2462
2515
|
claudeGuideInstalled = false;
|
|
2463
2516
|
}
|
|
2464
|
-
const alphaClawSkillPath = resolveAlphaClawSkillPath(options?.homeDir);
|
|
2517
|
+
const alphaClawSkillPath = resolveAlphaClawSkillPath(options?.homeDir, options?.environmentName);
|
|
2465
2518
|
let alphaClawSkillInstalled = false;
|
|
2466
2519
|
try {
|
|
2467
2520
|
await fs2.access(path2.join(alphaClawSkillPath, "SKILL.md"));
|
|
@@ -2528,8 +2581,10 @@ async function removeClaudeImport(memoryPath) {
|
|
|
2528
2581
|
async function runDoctor(sessionStore) {
|
|
2529
2582
|
const config = await sessionStore.getConfig();
|
|
2530
2583
|
let session = await sessionStore.getSession();
|
|
2531
|
-
const environment =
|
|
2532
|
-
const installState = await inspectInstallState(
|
|
2584
|
+
const environment = await getCurrentEnvironmentPreset(sessionStore);
|
|
2585
|
+
const installState = await inspectInstallState({
|
|
2586
|
+
environmentName: environment.name
|
|
2587
|
+
});
|
|
2533
2588
|
let apiCheck = {
|
|
2534
2589
|
ok: false,
|
|
2535
2590
|
message: "\u672A\u767B\u5F55\u3002\u8BF7\u6267\u884C\uFF1Aalpha-classic-cli login"
|
|
@@ -2563,8 +2618,8 @@ async function runDoctor(sessionStore) {
|
|
|
2563
2618
|
environment: environment.name,
|
|
2564
2619
|
baseUrl: environment.baseUrl,
|
|
2565
2620
|
apiBaseUrl: environment.apiBaseUrl,
|
|
2566
|
-
locked:
|
|
2567
|
-
source:
|
|
2621
|
+
locked: false,
|
|
2622
|
+
source: environment.source,
|
|
2568
2623
|
configPath: sessionStore.configPath
|
|
2569
2624
|
},
|
|
2570
2625
|
session: session ? {
|
|
@@ -2612,30 +2667,52 @@ function getCurrentUserData2(response) {
|
|
|
2612
2667
|
}
|
|
2613
2668
|
|
|
2614
2669
|
// src/commands/env.ts
|
|
2615
|
-
async function runEnvCommand(action,
|
|
2670
|
+
async function runEnvCommand(action, name, sessionStore) {
|
|
2616
2671
|
const normalizedAction = action?.trim().toLowerCase() ?? "current";
|
|
2617
2672
|
if (normalizedAction === "list") {
|
|
2673
|
+
const currentEnvironment = await getCurrentEnvironmentPreset(sessionStore);
|
|
2618
2674
|
printSuccess(listEnvironmentPresets(), {
|
|
2619
|
-
count: listEnvironmentPresets().length
|
|
2675
|
+
count: listEnvironmentPresets().length,
|
|
2676
|
+
current: currentEnvironment.name
|
|
2620
2677
|
});
|
|
2621
2678
|
return;
|
|
2622
2679
|
}
|
|
2623
2680
|
if (normalizedAction === "current") {
|
|
2624
|
-
const
|
|
2681
|
+
const currentEnvironment = await getCurrentEnvironmentPreset(sessionStore);
|
|
2625
2682
|
printSuccess({
|
|
2626
|
-
environment:
|
|
2627
|
-
label:
|
|
2628
|
-
baseUrl:
|
|
2629
|
-
apiBaseUrl:
|
|
2630
|
-
locked:
|
|
2631
|
-
source:
|
|
2683
|
+
environment: currentEnvironment.name,
|
|
2684
|
+
label: currentEnvironment.label,
|
|
2685
|
+
baseUrl: currentEnvironment.baseUrl,
|
|
2686
|
+
apiBaseUrl: currentEnvironment.apiBaseUrl,
|
|
2687
|
+
locked: false,
|
|
2688
|
+
source: currentEnvironment.source,
|
|
2689
|
+
configPath: sessionStore.configPath
|
|
2632
2690
|
});
|
|
2633
2691
|
return;
|
|
2634
2692
|
}
|
|
2635
2693
|
if (normalizedAction === "use") {
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2694
|
+
if (!name?.trim()) {
|
|
2695
|
+
throw new Error("Missing environment name. Use: alpha-classic-cli env use <local|dev|test|prod>");
|
|
2696
|
+
}
|
|
2697
|
+
const nextEnvironment = getEnvironmentPresetOrThrow(name);
|
|
2698
|
+
await sessionStore.saveConfig({
|
|
2699
|
+
environment: nextEnvironment.name,
|
|
2700
|
+
baseUrl: nextEnvironment.baseUrl,
|
|
2701
|
+
apiBaseUrl: nextEnvironment.apiBaseUrl
|
|
2702
|
+
});
|
|
2703
|
+
await sessionStore.clearAuthState();
|
|
2704
|
+
printSuccess({
|
|
2705
|
+
environment: nextEnvironment.name,
|
|
2706
|
+
label: nextEnvironment.label,
|
|
2707
|
+
baseUrl: nextEnvironment.baseUrl,
|
|
2708
|
+
apiBaseUrl: nextEnvironment.apiBaseUrl,
|
|
2709
|
+
locked: false,
|
|
2710
|
+
source: "config",
|
|
2711
|
+
session: "cleared",
|
|
2712
|
+
hint: "\u73AF\u5883\u5DF2\u5207\u6362\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C alpha-classic-cli login\u3002",
|
|
2713
|
+
configPath: sessionStore.configPath
|
|
2714
|
+
});
|
|
2715
|
+
return;
|
|
2639
2716
|
}
|
|
2640
2717
|
throw new Error(`Unknown env action: ${normalizedAction}`);
|
|
2641
2718
|
}
|
|
@@ -2643,7 +2720,7 @@ async function runEnvCommand(action, _name, _sessionStore) {
|
|
|
2643
2720
|
// src/commands/matter.ts
|
|
2644
2721
|
async function runMatterSearch(options, sessionStore) {
|
|
2645
2722
|
const config = await sessionStore.getConfig();
|
|
2646
|
-
const environment =
|
|
2723
|
+
const environment = await getCurrentEnvironmentPreset(sessionStore);
|
|
2647
2724
|
const client = new ApiClient({
|
|
2648
2725
|
sessionStore,
|
|
2649
2726
|
apiBaseUrl: environment.apiBaseUrl,
|
|
@@ -2694,7 +2771,7 @@ async function runMatterDetail(options, sessionStore) {
|
|
|
2694
2771
|
throw new Error("Missing matter id. Use: alpha-classic-cli matter detail --id <matterId>");
|
|
2695
2772
|
}
|
|
2696
2773
|
const config = await sessionStore.getConfig();
|
|
2697
|
-
const environment =
|
|
2774
|
+
const environment = await getCurrentEnvironmentPreset(sessionStore);
|
|
2698
2775
|
const client = new ApiClient({
|
|
2699
2776
|
sessionStore,
|
|
2700
2777
|
apiBaseUrl: environment.apiBaseUrl,
|
|
@@ -2725,7 +2802,7 @@ async function runMatterTaskList(options, sessionStore) {
|
|
|
2725
2802
|
throw new Error("Missing matter id. Use: alpha-classic-cli matter task --id <matterId>");
|
|
2726
2803
|
}
|
|
2727
2804
|
const config = await sessionStore.getConfig();
|
|
2728
|
-
const environment =
|
|
2805
|
+
const environment = await getCurrentEnvironmentPreset(sessionStore);
|
|
2729
2806
|
const client = new ApiClient({
|
|
2730
2807
|
sessionStore,
|
|
2731
2808
|
apiBaseUrl: environment.apiBaseUrl,
|
|
@@ -2777,7 +2854,7 @@ async function runMatterTaskDetail(options, sessionStore) {
|
|
|
2777
2854
|
throw new Error("Missing task id. Use: alpha-classic-cli matter task-detail --id <taskId>");
|
|
2778
2855
|
}
|
|
2779
2856
|
const config = await sessionStore.getConfig();
|
|
2780
|
-
const environment =
|
|
2857
|
+
const environment = await getCurrentEnvironmentPreset(sessionStore);
|
|
2781
2858
|
const client = new ApiClient({
|
|
2782
2859
|
sessionStore,
|
|
2783
2860
|
apiBaseUrl: environment.apiBaseUrl,
|
|
@@ -2843,18 +2920,21 @@ async function runMatterTaskDetail(options, sessionStore) {
|
|
|
2843
2920
|
if (commentResponse.succeed === false) {
|
|
2844
2921
|
throw new Error(commentResponse.message ?? commentResponse.detail ?? "Matter task comments request failed.");
|
|
2845
2922
|
}
|
|
2846
|
-
const task = detailResponse
|
|
2923
|
+
const task = unwrapEnvelopeData2(detailResponse);
|
|
2847
2924
|
if (!task) {
|
|
2848
2925
|
throw new Error("\u4EFB\u52A1\u4E0D\u5B58\u5728\u6216\u5F53\u524D\u7528\u6237\u65E0\u6743\u67E5\u770B\u3002");
|
|
2849
2926
|
}
|
|
2850
|
-
const
|
|
2927
|
+
const checkItems = unwrapEnvelopeData2(checkItemResponse) ?? [];
|
|
2928
|
+
const attachmentPage = unwrapEnvelopeData2(attachmentResponse) ?? {};
|
|
2851
2929
|
const attachments = attachmentPage.data ?? attachmentPage.items ?? [];
|
|
2852
2930
|
const attachmentDetails = await fetchDocumentDetailsForAttachments(client, attachments);
|
|
2853
|
-
const timingPage = timingResponse
|
|
2854
|
-
const commentPage = commentResponse.result ??
|
|
2931
|
+
const timingPage = unwrapEnvelopeData2(timingResponse) ?? {};
|
|
2932
|
+
const commentPage = commentResponse.result ?? unwrapEnvelopeData2(
|
|
2933
|
+
commentResponse
|
|
2934
|
+
) ?? {};
|
|
2855
2935
|
printSuccess({
|
|
2856
2936
|
"\u4EFB\u52A1\u6982\u89C8": toMatterTaskDetailSummary(task),
|
|
2857
|
-
"\u68C0\u67E5\u9879":
|
|
2937
|
+
"\u68C0\u67E5\u9879": checkItems.map(toMatterTaskCheckItemSummary),
|
|
2858
2938
|
"\u9644\u4EF6": attachments.map(
|
|
2859
2939
|
(attachment) => toMatterTaskAttachmentSummary(attachment, attachmentDetails.get(getAttachmentDocumentKey(attachment)))
|
|
2860
2940
|
),
|
|
@@ -3558,7 +3638,7 @@ async function buildJoinedMatterMemberFilter(client, sessionStore) {
|
|
|
3558
3638
|
};
|
|
3559
3639
|
}
|
|
3560
3640
|
function unwrapEnvelopeData2(response) {
|
|
3561
|
-
if (response && typeof response === "object" && "data" in response && ("isSuccess" in response || "resultMsg" in response)) {
|
|
3641
|
+
if (response && typeof response === "object" && "data" in response && ("isSuccess" in response || "resultCode" in response || "resultMsg" in response || "resultMess" in response || "code" in response || "msg" in response)) {
|
|
3562
3642
|
return response.data;
|
|
3563
3643
|
}
|
|
3564
3644
|
return response;
|
|
@@ -3796,8 +3876,8 @@ function dateFromTimestamp2(timestamp) {
|
|
|
3796
3876
|
}
|
|
3797
3877
|
|
|
3798
3878
|
// src/commands/version.ts
|
|
3799
|
-
function runVersion(info) {
|
|
3800
|
-
const environment =
|
|
3879
|
+
async function runVersion(info, sessionStore) {
|
|
3880
|
+
const environment = await getCurrentEnvironmentPreset(sessionStore);
|
|
3801
3881
|
printSuccess({
|
|
3802
3882
|
"\u540D\u79F0": info.name,
|
|
3803
3883
|
"\u7248\u672C": info.version,
|
|
@@ -3805,7 +3885,8 @@ function runVersion(info) {
|
|
|
3805
3885
|
"\u73AF\u5883": environment.name,
|
|
3806
3886
|
"baseUrl": environment.baseUrl,
|
|
3807
3887
|
"apiBaseUrl": environment.apiBaseUrl,
|
|
3808
|
-
"\u73AF\u5883\u662F\u5426\
|
|
3888
|
+
"\u73AF\u5883\u662F\u5426\u53EF\u8FD0\u884C\u65F6\u5207\u6362": true,
|
|
3889
|
+
"\u73AF\u5883\u6765\u6E90": environment.source
|
|
3809
3890
|
});
|
|
3810
3891
|
}
|
|
3811
3892
|
|
|
@@ -3890,22 +3971,33 @@ async function main() {
|
|
|
3890
3971
|
program.name("alpha-classic-cli").description("Alpha Classic AI-friendly CLI for Alpha web app").version(packageJson.version ?? "0.0.0");
|
|
3891
3972
|
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) => {
|
|
3892
3973
|
const agent = parseAgentInstallTarget(options.agent);
|
|
3893
|
-
const
|
|
3974
|
+
const environment = await getCurrentEnvironmentPreset(sessionStore);
|
|
3975
|
+
const result = await installAgentGuides({
|
|
3976
|
+
agent,
|
|
3977
|
+
environmentName: environment.name
|
|
3978
|
+
});
|
|
3894
3979
|
printSuccess(result);
|
|
3895
3980
|
});
|
|
3896
3981
|
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) => {
|
|
3897
3982
|
const agent = parseAgentInstallTarget(options.agent);
|
|
3898
|
-
const
|
|
3983
|
+
const environment = await getCurrentEnvironmentPreset(sessionStore);
|
|
3984
|
+
const result = await uninstallAgentGuides({
|
|
3985
|
+
agent,
|
|
3986
|
+
environmentName: environment.name
|
|
3987
|
+
});
|
|
3899
3988
|
printSuccess(result);
|
|
3900
3989
|
});
|
|
3901
|
-
program.command("capabilities").description("Print machine-readable CLI capabilities for agents").action(() => {
|
|
3902
|
-
runCapabilities(packageJson.version ?? "0.0.0");
|
|
3990
|
+
program.command("capabilities").description("Print machine-readable CLI capabilities for agents").action(async () => {
|
|
3991
|
+
await runCapabilities(packageJson.version ?? "0.0.0", sessionStore);
|
|
3903
3992
|
});
|
|
3904
|
-
program.command("version").description("Print machine-readable CLI version").action(() => {
|
|
3905
|
-
runVersion(
|
|
3906
|
-
|
|
3907
|
-
|
|
3908
|
-
|
|
3993
|
+
program.command("version").description("Print machine-readable CLI version").action(async () => {
|
|
3994
|
+
await runVersion(
|
|
3995
|
+
{
|
|
3996
|
+
name: packageJson.name ?? "alpha-classic-cli",
|
|
3997
|
+
version: packageJson.version ?? "0.0.0"
|
|
3998
|
+
},
|
|
3999
|
+
sessionStore
|
|
4000
|
+
);
|
|
3909
4001
|
});
|
|
3910
4002
|
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(
|
|
3911
4003
|
async (options) => {
|
|
@@ -3968,7 +4060,7 @@ async function main() {
|
|
|
3968
4060
|
program.command("doctor").description("Inspect config, session, skill install, and API health").action(async () => {
|
|
3969
4061
|
await runDoctor(sessionStore);
|
|
3970
4062
|
});
|
|
3971
|
-
program.command("env").description("Inspect the
|
|
4063
|
+
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) => {
|
|
3972
4064
|
await runEnvCommand(action, name, sessionStore);
|
|
3973
4065
|
});
|
|
3974
4066
|
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(
|