@actiondock/cli 2.7.0 → 2.8.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.
- package/README.md +4 -6
- package/dist/commands/action/create.js +4 -5
- package/dist/commands/add.js +9 -17
- package/dist/commands/build.js +3 -18
- package/dist/commands/config/delete.js +8 -7
- package/dist/commands/config/env.js +7 -11
- package/dist/commands/config/get.js +8 -5
- package/dist/commands/config/list.js +16 -22
- package/dist/commands/config/schema.d.ts +7 -1
- package/dist/commands/config/schema.js +44 -67
- package/dist/commands/config/set.js +9 -7
- package/dist/commands/describe.js +10 -9
- package/dist/commands/doctor.js +4 -3
- package/dist/commands/export.js +5 -13
- package/dist/commands/generate.js +4 -3
- package/dist/commands/info.js +3 -1
- package/dist/commands/init.js +3 -3
- package/dist/commands/link.js +4 -4
- package/dist/commands/list.js +19 -10
- package/dist/commands/mcp.js +27 -66
- package/dist/commands/pack.js +3 -12
- package/dist/commands/playbook.js +30 -10
- package/dist/commands/profile.js +10 -19
- package/dist/commands/remove.js +5 -14
- package/dist/commands/run.d.ts +5 -2
- package/dist/commands/run.js +19 -20
- package/dist/commands/runs.js +26 -35
- package/dist/commands/serve.js +66 -44
- package/dist/commands/state-list.d.ts +2 -2
- package/dist/commands/state-list.js +10 -8
- package/dist/commands/state.d.ts +2 -2
- package/dist/commands/state.js +110 -103
- package/dist/commands/test.js +1 -1
- package/dist/commands/validate.js +4 -17
- package/dist/errors.d.ts +14 -0
- package/dist/errors.js +46 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +3 -3
- package/dist/renderer.d.ts +1 -1
- package/dist/renderer.js +1 -1
- package/dist/services/config-merge.d.ts +6 -5
- package/dist/services/config-merge.js +10 -8
- package/dist/services/inspect.js +3 -1
- package/dist/standalone/index.d.ts +4 -14
- package/dist/standalone/index.js +5 -44
- package/dist/types.d.ts +2 -1
- package/dist/types.js +1 -1
- package/dist/utils/cert.js +1 -1
- package/dist/utils/duration.d.ts +1 -1
- package/dist/utils/duration.js +1 -1
- package/dist/utils/index.d.ts +1 -2
- package/dist/utils/index.js +1 -2
- package/dist/utils/input.d.ts +9 -1
- package/dist/utils/input.js +12 -1
- package/dist/utils/server-launch.d.ts +61 -0
- package/dist/utils/server-launch.js +114 -0
- package/dist/utils/target.d.ts +14 -13
- package/dist/utils/target.js +20 -39
- package/dist/utils/utils.d.ts +101 -1
- package/dist/utils/utils.js +97 -7
- package/package.json +5 -6
- package/dist/utils/bytes.d.ts +0 -1
- package/dist/utils/bytes.js +0 -1
- package/dist/utils/filter.d.ts +0 -1
- package/dist/utils/filter.js +0 -1
package/dist/commands/runs.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { findProjectRoot, loadProjectConfig, } from "@actiondock/core";
|
|
2
|
+
import { filterWithFallbackInfo, } from "@actiondock/core/project";
|
|
3
|
+
import { listLinkedPackages, resolvePackageRoot, } from "@actiondock/core/registry";
|
|
4
|
+
import { ArgumentError, ExecutionError, NO_PROJECT_NO_LINKED_MESSAGE, packageNotFoundError, } from "../errors.js";
|
|
3
5
|
import { renderResult, renderRunDetail, renderRunsList } from "../renderer.js";
|
|
4
|
-
import { applyTargetOptions, getEffectiveOptions,
|
|
6
|
+
import { applyTargetOptions, getEffectiveOptions, remoteTargetSuffix, requirePackageRoot, resolveFallbackStrategy, resolveIntent, withService, } from "../utils/index.js";
|
|
5
7
|
/**
|
|
6
8
|
* 解析本地目标包根目录与工程配置(仅在 local 分支调用)。
|
|
7
9
|
* 显式指定包且寻址失败时抛出参数错误;工程清单损坏时降级为链接包视图。
|
|
@@ -50,21 +52,26 @@ export function registerRunsCommands(program, context) {
|
|
|
50
52
|
.option("-i, --intent <pattern>", "Regex or fuzzy intent filter; falls back to full list when no match")
|
|
51
53
|
.option("-a, --action <actionId>", "Filter by action ID")
|
|
52
54
|
.option("-n, --limit <count>", "Maximum number of records to return", "20"))
|
|
55
|
+
.option("--fallback", "Enable fallback to full list when no items match intent")
|
|
53
56
|
.option("--no-fallback", "Disable fallback to full list when no items match intent")
|
|
54
57
|
.option("--data-dir <path>", "Custom database storage directory")
|
|
55
58
|
.option("--json", "Output as JSON")
|
|
56
59
|
.action(async (patterns = [], rawOptions, cmd) => {
|
|
57
60
|
const options = getEffectiveOptions(rawOptions, cmd);
|
|
58
61
|
const effectiveIntent = resolveIntent(options.intent, patterns);
|
|
59
|
-
const shouldFallback = options
|
|
62
|
+
const { shouldFallback } = resolveFallbackStrategy(options);
|
|
60
63
|
const limit = Number.parseInt(options.limit, 10) || 20;
|
|
61
64
|
const scope = resolveLocalRunScope(options.package);
|
|
62
|
-
// 通过
|
|
63
|
-
await
|
|
64
|
-
|
|
65
|
+
// 通过 Service 门面统一访问
|
|
66
|
+
await withService(options, context, async (service, resolved) => {
|
|
67
|
+
// limit 下推查询层:intent 过滤发生在内存(过滤后仍需截断到用户值),
|
|
68
|
+
// 下推时附加合理裕量,保证过滤后可截断数量不少于用户请求
|
|
69
|
+
const FETCH_HEADROOM = 200;
|
|
70
|
+
const queryLimit = effectiveIntent ? limit + FETCH_HEADROOM : limit;
|
|
71
|
+
const records = await service.runs.list({
|
|
65
72
|
packageId: options.package,
|
|
66
73
|
actionId: options.action,
|
|
67
|
-
limit:
|
|
74
|
+
limit: queryLimit,
|
|
68
75
|
});
|
|
69
76
|
// 若处于本地无项目环境且无任何软链接包,则直接输出友好提示
|
|
70
77
|
if (resolved.type === "local" && !scope.targetPackageRoot) {
|
|
@@ -85,7 +92,7 @@ export function registerRunsCommands(program, context) {
|
|
|
85
92
|
humanFormatter: () => {
|
|
86
93
|
let title = "Execution Runs";
|
|
87
94
|
if (resolved.type === "remote") {
|
|
88
|
-
title = `Execution Runs
|
|
95
|
+
title = `Execution Runs ${remoteTargetSuffix(resolved)}`;
|
|
89
96
|
}
|
|
90
97
|
else if (scope.projConfig) {
|
|
91
98
|
title = `Execution Runs in ${scope.projConfig.name} (${scope.projConfig.id})`;
|
|
@@ -112,9 +119,9 @@ export function registerRunsCommands(program, context) {
|
|
|
112
119
|
throw new ArgumentError("Run ID is required");
|
|
113
120
|
}
|
|
114
121
|
const scope = resolveLocalRunScope(options.package);
|
|
115
|
-
// 通过
|
|
116
|
-
await
|
|
117
|
-
const run = await
|
|
122
|
+
// 通过 Service 门面统一查询
|
|
123
|
+
await withService(options, context, async (service, resolved) => {
|
|
124
|
+
const run = await service.runs.get(id);
|
|
118
125
|
if (!run) {
|
|
119
126
|
if (resolved.type === "remote") {
|
|
120
127
|
throw new ExecutionError(`Run record '${id}' not found on remote server`);
|
|
@@ -144,12 +151,8 @@ export function registerRunsCommands(program, context) {
|
|
|
144
151
|
if (!id) {
|
|
145
152
|
throw new ArgumentError("Run ID is required for cancel");
|
|
146
153
|
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
throw new ArgumentError("'ad runs cancel' is only supported for remote execution targets. Use --profile <name> or --server <url>.");
|
|
150
|
-
}
|
|
151
|
-
await withRemoteTarget(options, context, async (target) => {
|
|
152
|
-
const result = await target.cancelRun(id, options.reason);
|
|
154
|
+
await withService(options, context, async (service) => {
|
|
155
|
+
const result = await service.runs.cancel(id, options.reason);
|
|
153
156
|
const isErrorOutcome = result.outcome === "not_found" || result.outcome === "not_owner";
|
|
154
157
|
renderResult(result, {
|
|
155
158
|
json: options.json,
|
|
@@ -167,7 +170,7 @@ export function registerRunsCommands(program, context) {
|
|
|
167
170
|
if (isErrorOutcome) {
|
|
168
171
|
process.exitCode = 1;
|
|
169
172
|
}
|
|
170
|
-
});
|
|
173
|
+
}, { requireRemote: true });
|
|
171
174
|
});
|
|
172
175
|
// runs clear
|
|
173
176
|
applyTargetOptions(runsCmd
|
|
@@ -182,19 +185,7 @@ export function registerRunsCommands(program, context) {
|
|
|
182
185
|
let targetPackageRoot;
|
|
183
186
|
let packageId = options.package;
|
|
184
187
|
if (!options.profile && !options.server) {
|
|
185
|
-
|
|
186
|
-
const root = resolvePackageRoot(options.package);
|
|
187
|
-
if (!root) {
|
|
188
|
-
throw packageNotFoundError(options.package);
|
|
189
|
-
}
|
|
190
|
-
targetPackageRoot = root;
|
|
191
|
-
}
|
|
192
|
-
else {
|
|
193
|
-
targetPackageRoot = findProjectRoot() || undefined;
|
|
194
|
-
if (!targetPackageRoot) {
|
|
195
|
-
throw notInProjectError("Please specify -P, --package <id> or cd into a project directory.");
|
|
196
|
-
}
|
|
197
|
-
}
|
|
188
|
+
targetPackageRoot = requirePackageRoot(options.package).root;
|
|
198
189
|
try {
|
|
199
190
|
packageId = loadProjectConfig(targetPackageRoot).id;
|
|
200
191
|
}
|
|
@@ -202,9 +193,9 @@ export function registerRunsCommands(program, context) {
|
|
|
202
193
|
// 清单损坏时保留原始 -P 参数作为包标识
|
|
203
194
|
}
|
|
204
195
|
}
|
|
205
|
-
await
|
|
206
|
-
const count =
|
|
207
|
-
? await
|
|
196
|
+
await withService(options, context, async (service, resolved) => {
|
|
197
|
+
const count = service.runs.clear
|
|
198
|
+
? await service.runs.clear({ packageId, actionId: options.action })
|
|
208
199
|
: 0;
|
|
209
200
|
const payload = { ok: true, clearedCount: count };
|
|
210
201
|
renderResult(payload, {
|
package/dist/commands/serve.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { readFileSync } from "node:fs";
|
|
2
2
|
import { resolve } from "node:path";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
3
|
+
import { createActionDock, createNodePlatform, findProjectRoot, loadProjectConfig, startActionDockServer, } from "@actiondock/core";
|
|
4
|
+
import { resolvePackageRoot } from "@actiondock/core/registry";
|
|
5
|
+
import { formatHostForUrl, } from "@actiondock/core/server";
|
|
6
|
+
import { ArgumentError, ExecutionError, packageNotFoundError } from "../errors.js";
|
|
6
7
|
import { writeStderr, writeStdout } from "../renderer.js";
|
|
7
|
-
import { ensureSelfSignedCertificate, getEffectiveOptions,
|
|
8
|
+
import { ensureSelfSignedCertificate, getEffectiveOptions, normalizeCorsOrigins, registerStopSignalHandler, printServerBanner, resolveMaxBodyBytes, resolveServerHost, resolveServerPort, resolveServerToken, parseListOption, } from "../utils/index.js";
|
|
8
9
|
/**
|
|
9
10
|
* 注册 serve HTTP 服务启动命令。
|
|
10
11
|
*
|
|
@@ -31,17 +32,17 @@ export function registerServeCommand(program, context) {
|
|
|
31
32
|
.option("--tls-ca <path>", "Path to TLS CA certificate file (or set ACTIONDOCK_TLS_CA)")
|
|
32
33
|
.option("--tls-passphrase <passphrase>", "Passphrase for TLS private key (or set ACTIONDOCK_TLS_PASSPHRASE)")
|
|
33
34
|
.option("-d, --dir <path>", "Project root directory (default: current working directory)")
|
|
35
|
+
.option("-P, --package <package-id>", "Specific package ID(s) to serve (can be specified multiple times or comma-separated)", parseListOption, [])
|
|
34
36
|
.option("--data-dir <path>", "Custom database storage directory")
|
|
35
37
|
.action(async (rawOptions, cmd) => {
|
|
36
38
|
const options = getEffectiveOptions(rawOptions, cmd);
|
|
37
|
-
const
|
|
38
|
-
const
|
|
39
|
-
const
|
|
40
|
-
const token = options.token || (typeof process !== "undefined" ? process.env?.ACTIONDOCK_TOKEN : undefined);
|
|
39
|
+
const port = resolveServerPort(options.port, 5177);
|
|
40
|
+
const host = resolveServerHost(options.host);
|
|
41
|
+
const token = resolveServerToken(options.token);
|
|
41
42
|
const allowInsecureNoAuth = Boolean(options.allowInsecureNoAuth);
|
|
42
43
|
const allowQueryToken = Boolean(options.allowQueryToken);
|
|
43
44
|
const enableManagement = Boolean(options.management);
|
|
44
|
-
const corsOrigins = options.corsOrigin
|
|
45
|
+
const corsOrigins = normalizeCorsOrigins(options.corsOrigin);
|
|
45
46
|
const exposeDebugInfo = Boolean(options.exposeDebugInfo);
|
|
46
47
|
const httpsEnabled = Boolean(options.https ||
|
|
47
48
|
options.tlsCert ||
|
|
@@ -82,18 +83,46 @@ export function registerServeCommand(program, context) {
|
|
|
82
83
|
};
|
|
83
84
|
}
|
|
84
85
|
}
|
|
85
|
-
|
|
86
|
-
if (options.maxBody) {
|
|
87
|
-
try {
|
|
88
|
-
maxBodyBytes = parseByteSize(options.maxBody);
|
|
89
|
-
}
|
|
90
|
-
catch (err) {
|
|
91
|
-
throw new ArgumentError(`Invalid max-body format: ${err.message}`);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
86
|
+
const maxBodyBytes = resolveMaxBodyBytes(options.maxBody);
|
|
94
87
|
const projectRoot = options.dir
|
|
95
88
|
? resolve(options.dir)
|
|
96
89
|
: findProjectRoot(process.cwd());
|
|
90
|
+
const rawPackages = options.package || [];
|
|
91
|
+
const packageAllowlist = rawPackages.length > 0 ? [] : undefined;
|
|
92
|
+
const resolvedPackageIds = [];
|
|
93
|
+
const explicitPackages = [];
|
|
94
|
+
if (rawPackages.length > 0) {
|
|
95
|
+
for (const pkgId of rawPackages) {
|
|
96
|
+
const root = resolvePackageRoot(pkgId, projectRoot || undefined, context?.customHome);
|
|
97
|
+
if (!root) {
|
|
98
|
+
throw packageNotFoundError(pkgId);
|
|
99
|
+
}
|
|
100
|
+
if (!projectRoot || root !== projectRoot) {
|
|
101
|
+
if (!explicitPackages.some((p) => p.packageRoot === root)) {
|
|
102
|
+
explicitPackages.push({ packageRoot: root });
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
let resolvedId = pkgId;
|
|
106
|
+
try {
|
|
107
|
+
const config = loadProjectConfig(root);
|
|
108
|
+
if (config.id) {
|
|
109
|
+
resolvedId = config.id;
|
|
110
|
+
if (!packageAllowlist.includes(config.id)) {
|
|
111
|
+
packageAllowlist.push(config.id);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
// 降级使用原始标识符
|
|
117
|
+
}
|
|
118
|
+
if (!packageAllowlist.includes(pkgId)) {
|
|
119
|
+
packageAllowlist.push(pkgId);
|
|
120
|
+
}
|
|
121
|
+
if (!resolvedPackageIds.includes(resolvedId)) {
|
|
122
|
+
resolvedPackageIds.push(resolvedId);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
97
126
|
let projectName = "Global Registry Mode";
|
|
98
127
|
if (projectRoot) {
|
|
99
128
|
try {
|
|
@@ -109,13 +138,14 @@ export function registerServeCommand(program, context) {
|
|
|
109
138
|
dataDir: options.dataDir || context?.dataDir,
|
|
110
139
|
rootDir: projectRoot || undefined,
|
|
111
140
|
});
|
|
112
|
-
const
|
|
141
|
+
const service = await createActionDock({
|
|
113
142
|
type: "local",
|
|
114
143
|
projectRoot: projectRoot || undefined,
|
|
144
|
+
packages: explicitPackages.length > 0 ? explicitPackages : undefined,
|
|
115
145
|
customHome: context?.customHome,
|
|
116
146
|
dataDir: options.dataDir || context?.dataDir,
|
|
117
147
|
platform,
|
|
118
|
-
scanLinkedPackages: !projectRoot,
|
|
148
|
+
scanLinkedPackages: !projectRoot || rawPackages.length > 0,
|
|
119
149
|
});
|
|
120
150
|
let mcpHandler;
|
|
121
151
|
const enableMcp = options.mcp !== false;
|
|
@@ -128,7 +158,9 @@ export function registerServeCommand(program, context) {
|
|
|
128
158
|
]);
|
|
129
159
|
const handler = createMcpHandler(() => {
|
|
130
160
|
return createActionDockMcpServer({
|
|
131
|
-
|
|
161
|
+
service,
|
|
162
|
+
packageAllowlist,
|
|
163
|
+
packageIds: packageAllowlist,
|
|
132
164
|
});
|
|
133
165
|
}, {
|
|
134
166
|
onerror: (err) => {
|
|
@@ -140,7 +172,7 @@ export function registerServeCommand(program, context) {
|
|
|
140
172
|
};
|
|
141
173
|
}
|
|
142
174
|
catch (err) {
|
|
143
|
-
await
|
|
175
|
+
await service.close().catch(() => { });
|
|
144
176
|
throw new ExecutionError(`Failed to initialize MCP endpoint: ${err?.message || String(err)}`, err);
|
|
145
177
|
}
|
|
146
178
|
}
|
|
@@ -159,16 +191,19 @@ export function registerServeCommand(program, context) {
|
|
|
159
191
|
mcpHandler,
|
|
160
192
|
tls,
|
|
161
193
|
projectRoot: projectRoot || undefined,
|
|
162
|
-
|
|
194
|
+
service,
|
|
195
|
+
packageAllowlist,
|
|
163
196
|
});
|
|
164
197
|
const displayHost = formatHostForUrl(host);
|
|
165
198
|
const actualEndpointHost = formatHostForUrl(host === "0.0.0.0" ? "127.0.0.1" : host);
|
|
166
199
|
const scheme = tls ? "https" : "http";
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
200
|
+
printServerBanner(`ActionDock 2.0 HTTP Runner Server`, scheme, displayHost, server.port, context);
|
|
201
|
+
if (resolvedPackageIds.length > 0) {
|
|
202
|
+
writeStdout(` * Packages: ${resolvedPackageIds.join(", ")}`, context);
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
writeStdout(` * Project: ${projectName}`, context);
|
|
206
|
+
}
|
|
172
207
|
if (projectRoot && exposeDebugInfo) {
|
|
173
208
|
writeStdout(` * Root Path: ${projectRoot}`, context);
|
|
174
209
|
}
|
|
@@ -183,30 +218,17 @@ export function registerServeCommand(program, context) {
|
|
|
183
218
|
writeStdout(` * Management APIs: ${enableManagement ? "Enabled" : "Disabled (Default)"}`, context);
|
|
184
219
|
writeStdout(` * CORS Origins: ${corsOrigins ? corsOrigins.join(", ") : "Disabled (Default)"}`, context);
|
|
185
220
|
writeStdout(` * Max Body Size: ${options.maxBody || "1mb"}`, context);
|
|
186
|
-
writeStdout(` * Health Endpoint: ${scheme}://${actualEndpointHost}:${server.port}/api/
|
|
221
|
+
writeStdout(` * Health Endpoint: ${scheme}://${actualEndpointHost}:${server.port}/api/v2/health`, context);
|
|
187
222
|
if (enableMcp) {
|
|
188
223
|
writeStdout(` * MCP Endpoint: ${scheme}://${actualEndpointHost}:${server.port}/mcp`, context);
|
|
189
224
|
}
|
|
190
225
|
writeStdout(`======================================================\n`, context);
|
|
191
226
|
writeStdout(`Server is ready to accept remote requests.`, context);
|
|
192
227
|
writeStdout(`Press Ctrl+C to terminate.\n`, context);
|
|
193
|
-
|
|
194
|
-
writeStdout("\nStopping ActionDock server...", context);
|
|
195
|
-
Promise.resolve(server.stop())
|
|
196
|
-
.catch((err) => {
|
|
197
|
-
// 停止失败必须可见:写入 stderr 一行并标记失败退出码
|
|
198
|
-
writeStderr(`[ERROR] Failed to stop ActionDock server gracefully: ${err instanceof Error ? err.message : String(err)}`, context);
|
|
199
|
-
process.exitCode = 1;
|
|
200
|
-
})
|
|
201
|
-
.finally(() => {
|
|
202
|
-
process.exit(typeof process.exitCode === "number" ? process.exitCode : 0);
|
|
203
|
-
});
|
|
204
|
-
};
|
|
205
|
-
process.once("SIGINT", stopSignalHandler);
|
|
206
|
-
process.once("SIGTERM", stopSignalHandler);
|
|
228
|
+
registerStopSignalHandler(server, `ActionDock server`, context);
|
|
207
229
|
}
|
|
208
230
|
catch (err) {
|
|
209
|
-
await
|
|
231
|
+
await service.close().catch(() => { });
|
|
210
232
|
throw new ExecutionError(`Failed to start ActionDock server: ${err.message}`, err);
|
|
211
233
|
}
|
|
212
234
|
});
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type ActionDockService } from "@actiondock/core";
|
|
2
2
|
import type { CliContext } from "../types.js";
|
|
3
3
|
/**
|
|
4
4
|
* 状态键列表渲染参数视图。
|
|
5
5
|
*/
|
|
6
6
|
export interface StateListRenderArgs {
|
|
7
|
-
|
|
7
|
+
service: ActionDockService;
|
|
8
8
|
actionId: string;
|
|
9
9
|
prefix: string;
|
|
10
10
|
options: any;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { loadProjectConfig, } from "@actiondock/core";
|
|
2
|
+
import { filterWithFallbackInfo, } from "@actiondock/core/project";
|
|
3
|
+
import { listLinkedPackages, } from "@actiondock/core/registry";
|
|
2
4
|
import { existsSync } from "node:fs";
|
|
3
5
|
import { NO_PROJECT_NO_LINKED_MESSAGE } from "../errors.js";
|
|
4
6
|
import { renderResult, renderStateList } from "../renderer.js";
|
|
@@ -6,16 +8,16 @@ import { renderResult, renderStateList } from "../renderer.js";
|
|
|
6
8
|
* 渲染单个项目作用域的状态键列表(含 --detail JSON 明细分支)。
|
|
7
9
|
*/
|
|
8
10
|
export async function renderProjectScopedStateList(args) {
|
|
9
|
-
const {
|
|
11
|
+
const { service, targetRoot, actionId, prefix, options, effectiveIntent, shouldFallback, context } = args;
|
|
10
12
|
const projConfig = loadProjectConfig(targetRoot);
|
|
11
|
-
const allKeys = await
|
|
13
|
+
const allKeys = (await service.management?.state.list(projConfig.id, actionId, {
|
|
12
14
|
namespace: options.namespace !== undefined ? options.namespace : null,
|
|
13
15
|
prefix,
|
|
14
|
-
});
|
|
16
|
+
})) ?? [];
|
|
15
17
|
if (options.detail && options.json) {
|
|
16
18
|
const entries = [];
|
|
17
19
|
for (const k of allKeys) {
|
|
18
|
-
const entry = await
|
|
20
|
+
const entry = await service.management?.state.get(projConfig.id, actionId, k, {
|
|
19
21
|
namespace: options.namespace,
|
|
20
22
|
detail: true,
|
|
21
23
|
});
|
|
@@ -41,7 +43,7 @@ export async function renderProjectScopedStateList(args) {
|
|
|
41
43
|
* 渲染全部链接包聚合的状态键列表(跳过磁盘失效与清单损坏的链接项)。
|
|
42
44
|
*/
|
|
43
45
|
export async function renderLinkedPackagesStateList(args) {
|
|
44
|
-
const {
|
|
46
|
+
const { service, actionId, prefix, options, effectiveIntent, shouldFallback, context } = args;
|
|
45
47
|
// 扫描所有链接的包状态
|
|
46
48
|
const linked = listLinkedPackages();
|
|
47
49
|
if (linked.length === 0) {
|
|
@@ -58,10 +60,10 @@ export async function renderLinkedPackagesStateList(args) {
|
|
|
58
60
|
continue;
|
|
59
61
|
try {
|
|
60
62
|
const config = loadProjectConfig(pkg.path);
|
|
61
|
-
const keys = await
|
|
63
|
+
const keys = (await service.management?.state.list(config.id, actionId, {
|
|
62
64
|
namespace: options.namespace !== undefined ? options.namespace : null,
|
|
63
65
|
prefix,
|
|
64
|
-
});
|
|
66
|
+
})) ?? [];
|
|
65
67
|
for (const k of keys) {
|
|
66
68
|
aggregatedKeys.push(`${config.id}/${k}`);
|
|
67
69
|
}
|
package/dist/commands/state.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { CliContext } from "../types.js";
|
|
|
3
3
|
/**
|
|
4
4
|
* 注册 state 状态管理命令(get、set、delete、clear、keys、list)。
|
|
5
5
|
*
|
|
6
|
-
* @param program Commander
|
|
7
|
-
* @param context
|
|
6
|
+
* @param program Commander 根程序对象
|
|
7
|
+
* @param context CLI 上下文
|
|
8
8
|
*/
|
|
9
9
|
export declare function registerStateCommands(program: Command, context?: CliContext): void;
|