@actiondock/builder 2.0.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/src/planner.ts ADDED
@@ -0,0 +1,453 @@
1
+ import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
2
+ import { basename, dirname, join, relative, resolve } from "node:path";
3
+ import YAML from "yaml";
4
+ import {
5
+ type ActionDockManifest,
6
+ type ActionManifestEntry,
7
+ loadManifest,
8
+ loadProjectConfig,
9
+ type PlaybookDefinition,
10
+ type ProjectConfig,
11
+ validateManifest,
12
+ } from "@actiondock/core";
13
+ import { PlannerError } from "./errors";
14
+ import type {
15
+ ActionDependency,
16
+ AssetDependency,
17
+ BuildPlan,
18
+ BuildPlanDependencies,
19
+ BuildPlannerOptions,
20
+ ExternalDependency,
21
+ PlaybookPlanEntry,
22
+ } from "./types";
23
+
24
+ /**
25
+ * 递归扫描指定目录下的文件,返回绝对路径列表。
26
+ */
27
+ function walkDirectory(dir: string): string[] {
28
+ if (!existsSync(dir)) return [];
29
+ const results: string[] = [];
30
+ const entries = readdirSync(dir);
31
+ for (const entry of entries) {
32
+ const fullPath = join(dir, entry);
33
+ const stat = statSync(fullPath);
34
+ if (stat.isDirectory()) {
35
+ results.push(...walkDirectory(fullPath));
36
+ } else if (stat.isFile()) {
37
+ results.push(fullPath);
38
+ }
39
+ }
40
+ return results;
41
+ }
42
+
43
+ /**
44
+ * 纯文本解析 Playbook Markdown 文件,提取 YAML Frontmatter,不执行任何业务代码。
45
+ */
46
+ function parsePlaybookFile(filePath: string): PlaybookPlanEntry | null {
47
+ try {
48
+ const content = readFileSync(filePath, "utf-8");
49
+ const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
50
+ if (match) {
51
+ const parsed = YAML.parse(match[1]) || {};
52
+ const id = parsed.id || basename(filePath, ".md");
53
+ return {
54
+ id,
55
+ filePath,
56
+ actions: Array.isArray(parsed.actions) ? parsed.actions : [],
57
+ description: parsed.description,
58
+ };
59
+ }
60
+ return {
61
+ id: basename(filePath, ".md"),
62
+ filePath,
63
+ actions: [],
64
+ };
65
+ } catch {
66
+ return null;
67
+ }
68
+ }
69
+
70
+ /**
71
+ * 静态加载项目目录下的 Playbook 列表。
72
+ */
73
+ function loadProjectPlaybooks(projectRoot: string, playbooksDir = "playbooks"): Map<string, PlaybookPlanEntry> {
74
+ const map = new Map<string, PlaybookPlanEntry>();
75
+ const dir = join(projectRoot, playbooksDir);
76
+ if (!existsSync(dir)) return map;
77
+
78
+ const files = walkDirectory(dir).filter((f) => f.endsWith(".md"));
79
+ for (const file of files) {
80
+ const pb = parsePlaybookFile(file);
81
+ if (pb) {
82
+ map.set(pb.id, pb);
83
+ }
84
+ }
85
+ return map;
86
+ }
87
+
88
+ /**
89
+ * 静态扫描 actions 目录生成备用清单,杜绝动态 import 与代码执行。
90
+ */
91
+ function generateStaticManifest(projectRoot: string, actionsDir = "actions"): ActionDockManifest {
92
+ const dir = join(projectRoot, actionsDir);
93
+ const actions: Record<string, ActionManifestEntry> = {};
94
+
95
+ if (existsSync(dir)) {
96
+ const files = walkDirectory(dir).filter(
97
+ (f) =>
98
+ (f.endsWith(".ts") || f.endsWith(".js")) &&
99
+ !f.endsWith(".d.ts") &&
100
+ !f.endsWith(".test.ts") &&
101
+ !f.endsWith(".spec.ts")
102
+ );
103
+
104
+ for (const file of files) {
105
+ const relPath = relative(projectRoot, file);
106
+ const filename = basename(file);
107
+ const actionId = filename.replace(/\.(ts|js)$/, "");
108
+
109
+ // 静态正则提取 id 与 uses,不执行模块代码
110
+ let parsedId = actionId;
111
+ const uses: string[] = [];
112
+ try {
113
+ const source = readFileSync(file, "utf-8");
114
+ const idMatch = source.match(/id\s*:\s*["'`]([^"'`]+)["'`]/);
115
+ if (idMatch && idMatch[1]) {
116
+ parsedId = idMatch[1];
117
+ }
118
+ const usesMatch = source.match(/uses\s*:\s*\[([^\]]*)\]/);
119
+ if (usesMatch && usesMatch[1]) {
120
+ const rawItems = usesMatch[1].split(",");
121
+ for (const raw of rawItems) {
122
+ const clean = raw.trim().replace(/^["'`]|["'`]$/g, "");
123
+ if (clean) {
124
+ uses.push(clean);
125
+ }
126
+ }
127
+ }
128
+ } catch {
129
+ // 忽略文件读取异常
130
+ }
131
+
132
+ actions[parsedId] = {
133
+ entry: relPath,
134
+ description: `Action ${parsedId}`,
135
+ uses,
136
+ };
137
+ }
138
+ }
139
+
140
+ return {
141
+ schemaVersion: 1,
142
+ actions,
143
+ };
144
+ }
145
+
146
+ /**
147
+ * 收集项目根目录 package.json 中声明的外部 npm 依赖。
148
+ */
149
+ function extractExternalDependencies(projectRoot: string): ExternalDependency[] {
150
+ const pkgPath = join(projectRoot, "package.json");
151
+ if (!existsSync(pkgPath)) return [];
152
+
153
+ try {
154
+ const raw = readFileSync(pkgPath, "utf-8");
155
+ const parsed = JSON.parse(raw);
156
+ const deps: ExternalDependency[] = [];
157
+
158
+ if (parsed.dependencies && typeof parsed.dependencies === "object") {
159
+ for (const [name, versionRange] of Object.entries(parsed.dependencies)) {
160
+ deps.push({
161
+ name,
162
+ versionRange: String(versionRange),
163
+ isDev: false,
164
+ });
165
+ }
166
+ }
167
+
168
+ if (parsed.devDependencies && typeof parsed.devDependencies === "object") {
169
+ for (const [name, versionRange] of Object.entries(parsed.devDependencies)) {
170
+ deps.push({
171
+ name,
172
+ versionRange: String(versionRange),
173
+ isDev: true,
174
+ });
175
+ }
176
+ }
177
+
178
+ return deps;
179
+ } catch {
180
+ return [];
181
+ }
182
+ }
183
+
184
+ /**
185
+ * 构建规划器。
186
+ * 纯声明式解析 actiondock.manifest.json 与配置,绝不执行 Action 业务代码。
187
+ */
188
+ export class BuildPlanner {
189
+ private projectRoot: string;
190
+
191
+ constructor(options?: { projectRoot?: string }) {
192
+ this.projectRoot = resolve(options?.projectRoot || process.cwd());
193
+ }
194
+
195
+ /**
196
+ * 执行依赖闭包裁剪与构建规划。
197
+ *
198
+ * @param options 规划参数
199
+ * @returns 完整的 BuildPlan 结构
200
+ */
201
+ public plan(options?: BuildPlannerOptions): BuildPlan {
202
+ const root = resolve(options?.projectRoot || this.projectRoot);
203
+
204
+ // 1. 获取项目配置(优先使用传入对象,缺失则读取 actiondock.json)
205
+ let config = options?.config;
206
+ if (!config) {
207
+ try {
208
+ config = loadProjectConfig(root);
209
+ } catch (err: any) {
210
+ throw new PlannerError(
211
+ `Failed to load project config: ${err.message}`,
212
+ "CONFIG_LOAD_ERROR"
213
+ );
214
+ }
215
+ }
216
+
217
+ // 2. 获取声明式清单(优先使用传入清单,缺失则读取 actiondock.manifest.json,未提供则采用安全静态扫描回退)
218
+ let manifest = options?.manifest;
219
+ if (!manifest) {
220
+ const loaded = loadManifest(root);
221
+ if (loaded) {
222
+ manifest = loaded;
223
+ } else {
224
+ manifest = generateStaticManifest(root, config.actionsDir || "actions");
225
+ }
226
+ }
227
+
228
+ const validation = validateManifest(manifest);
229
+ if (!validation.valid) {
230
+ throw new PlannerError(
231
+ `Invalid actiondock.manifest.json: ${(validation.errors || []).join("; ")}`,
232
+ "INVALID_MANIFEST"
233
+ );
234
+ }
235
+
236
+ // 3. 静态读取 Playbook 规程定义
237
+ const playbooksMap = loadProjectPlaybooks(root, config.playbooksDir || "playbooks");
238
+
239
+ // 4. 计算初始 Action 与 Playbook 集合
240
+ const initialActionIds = new Set<string>();
241
+ let selectedPlaybooks: PlaybookPlanEntry[] = [];
242
+
243
+ // 若指定了 Playbook 列表,进行过滤并提取关联 Action
244
+ if (options?.playbooks && options.playbooks.length > 0) {
245
+ for (const pbId of options.playbooks) {
246
+ const pb = playbooksMap.get(pbId);
247
+ if (!pb) {
248
+ throw new PlannerError(
249
+ `Playbook '${pbId}' specified in build options was not found in project`,
250
+ "PLAYBOOK_NOT_FOUND"
251
+ );
252
+ }
253
+ selectedPlaybooks.push(pb);
254
+ if (pb.actions && pb.actions.length > 0) {
255
+ for (const act of pb.actions) {
256
+ initialActionIds.add(act);
257
+ }
258
+ }
259
+ }
260
+ } else {
261
+ selectedPlaybooks = Array.from(playbooksMap.values());
262
+ }
263
+
264
+ // 若显式指定了 Action 列表,加入集合
265
+ if (options?.actions && options.actions.length > 0) {
266
+ for (const actId of options.actions) {
267
+ if (!manifest.actions[actId]) {
268
+ throw new PlannerError(
269
+ `Action '${actId}' specified in build options was not found in manifest`,
270
+ "ACTION_NOT_FOUND"
271
+ );
272
+ }
273
+ initialActionIds.add(actId);
274
+ }
275
+ }
276
+
277
+ // 若均未显式指定,默认打包清单中的全部 Action
278
+ if ((!options?.actions || options.actions.length === 0) && (!options?.playbooks || options.playbooks.length === 0)) {
279
+ for (const actId of Object.keys(manifest.actions)) {
280
+ initialActionIds.add(actId);
281
+ }
282
+ }
283
+
284
+ // 5. 进行依赖闭包(uses)解析计算,自动处理环形依赖与传递依赖
285
+ const resolvedActionIds = new Set<string>();
286
+ const queue = Array.from(initialActionIds);
287
+
288
+ while (queue.length > 0) {
289
+ const currentId = queue.shift()!;
290
+ if (resolvedActionIds.has(currentId)) {
291
+ continue;
292
+ }
293
+
294
+ const entry = manifest.actions[currentId];
295
+ if (!entry) {
296
+ throw new PlannerError(
297
+ `Action '${currentId}' referenced in dependency closure (uses) was not found in manifest`,
298
+ "MISSING_DEPENDENCY"
299
+ );
300
+ }
301
+
302
+ resolvedActionIds.add(currentId);
303
+
304
+ if (entry.uses && Array.isArray(entry.uses)) {
305
+ for (const depId of entry.uses) {
306
+ if (!resolvedActionIds.has(depId)) {
307
+ queue.push(depId);
308
+ }
309
+ }
310
+ }
311
+ }
312
+
313
+ // 6. 若指定了 Action 但未指定 Playbook,反向裁剪排除无法满足依赖的 Playbook
314
+ if (options?.actions && options.actions.length > 0 && (!options.playbooks || options.playbooks.length === 0)) {
315
+ selectedPlaybooks = selectedPlaybooks.filter((pb) => {
316
+ if (!pb.actions || pb.actions.length === 0) return true;
317
+ return pb.actions.every((a) => resolvedActionIds.has(a));
318
+ });
319
+ }
320
+
321
+ // 7. 构造 Action 依赖结构
322
+ const actionDependencies: ActionDependency[] = [];
323
+ for (const actId of resolvedActionIds) {
324
+ const entry = manifest.actions[actId];
325
+ const resolvedPath = resolve(root, entry.entry);
326
+ if (!existsSync(resolvedPath)) {
327
+ throw new PlannerError(
328
+ `Action '${actId}' entry file not found on disk: ${entry.entry}`,
329
+ "ENTRY_FILE_NOT_FOUND"
330
+ );
331
+ }
332
+ actionDependencies.push({
333
+ id: actId,
334
+ entry: entry.entry,
335
+ resolvedPath,
336
+ uses: entry.uses || [],
337
+ description: entry.description,
338
+ inputSchema: entry.inputSchema,
339
+ outputSchema: entry.outputSchema,
340
+ tags: entry.tags,
341
+ annotations: entry.annotations,
342
+ });
343
+ }
344
+
345
+ // 8. 构造模块与资产依赖结构
346
+ const modulesAndAssets: AssetDependency[] = [];
347
+ const assetPathSet = new Set<string>();
348
+
349
+ // 清单声明资产
350
+ if (manifest.assets && Array.isArray(manifest.assets)) {
351
+ for (const assetRel of manifest.assets) {
352
+ if (!assetPathSet.has(assetRel)) {
353
+ assetPathSet.add(assetRel);
354
+ modulesAndAssets.push({
355
+ path: assetRel,
356
+ resolvedPath: resolve(root, assetRel),
357
+ type: "asset",
358
+ });
359
+ }
360
+ }
361
+ }
362
+
363
+ // 默认 assets 目录资产扫描
364
+ const defaultAssetsDir = join(root, "assets");
365
+ if (existsSync(defaultAssetsDir)) {
366
+ const assetFiles = walkDirectory(defaultAssetsDir);
367
+ for (const file of assetFiles) {
368
+ const rel = relative(root, file);
369
+ if (!assetPathSet.has(rel)) {
370
+ assetPathSet.add(rel);
371
+ modulesAndAssets.push({
372
+ path: rel,
373
+ resolvedPath: file,
374
+ type: "asset",
375
+ });
376
+ }
377
+ }
378
+ }
379
+
380
+ // Playbook 规程文档依赖
381
+ for (const pb of selectedPlaybooks) {
382
+ const rel = relative(root, pb.filePath);
383
+ modulesAndAssets.push({
384
+ path: rel,
385
+ resolvedPath: pb.filePath,
386
+ type: "playbook",
387
+ });
388
+ }
389
+
390
+ // 项目核心配置文件
391
+ const configPath = join(root, "actiondock.json");
392
+ if (existsSync(configPath)) {
393
+ modulesAndAssets.push({
394
+ path: "actiondock.json",
395
+ resolvedPath: configPath,
396
+ type: "config",
397
+ });
398
+ }
399
+
400
+ const manifestPath = join(root, "actiondock.manifest.json");
401
+ if (existsSync(manifestPath)) {
402
+ modulesAndAssets.push({
403
+ path: "actiondock.manifest.json",
404
+ resolvedPath: manifestPath,
405
+ type: "config",
406
+ });
407
+ }
408
+
409
+ // 9. 外部 npm 依赖解析
410
+ const externalDependencies = extractExternalDependencies(root);
411
+
412
+ // 10. 生成最终 BuildPlan
413
+ const dependencies: BuildPlanDependencies = {
414
+ actions: actionDependencies,
415
+ modulesAndAssets,
416
+ external: externalDependencies,
417
+ };
418
+
419
+ return {
420
+ packageId: config.id,
421
+ packageName: config.name || config.id,
422
+ version: config.version || "0.1.0",
423
+ description: config.description,
424
+ projectRoot: root,
425
+ actions: actionDependencies,
426
+ playbooks: selectedPlaybooks,
427
+ dependencies,
428
+ assets: Array.from(assetPathSet),
429
+ configDefs: config.config,
430
+ metadata: {
431
+ plannedAt: new Date().toISOString(),
432
+ schemaVersion: 1,
433
+ actionCount: actionDependencies.length,
434
+ playbookCount: selectedPlaybooks.length,
435
+ },
436
+ };
437
+ }
438
+
439
+ /**
440
+ * 静态辅助调用方法。
441
+ */
442
+ public static plan(options: BuildPlannerOptions): BuildPlan {
443
+ const planner = new BuildPlanner({ projectRoot: options.projectRoot });
444
+ return planner.plan(options);
445
+ }
446
+ }
447
+
448
+ /**
449
+ * 快捷构建规划函数。
450
+ */
451
+ export function buildPlan(options: BuildPlannerOptions): BuildPlan {
452
+ return BuildPlanner.plan(options);
453
+ }
package/src/types.ts ADDED
@@ -0,0 +1,262 @@
1
+ import type { ActionDockManifest, ActionManifestEntry, PlaybookDefinition, ProjectConfig } from "@actiondock/core";
2
+
3
+ /**
4
+ * Action 依赖描述。
5
+ */
6
+ export interface ActionDependency {
7
+ /** Action 唯一标识符 */
8
+ id: string;
9
+ /** Action 入口文件相对路径 */
10
+ entry: string;
11
+ /** Action 源码文件绝对路径 */
12
+ resolvedPath: string;
13
+ /** 静态依赖的下游 Action ID 列表 */
14
+ uses: string[];
15
+ /** Action 功能描述 */
16
+ description?: string;
17
+ /** 入参校验模式 */
18
+ inputSchema?: Record<string, unknown> | boolean;
19
+ /** 出参校验模式 */
20
+ outputSchema?: Record<string, unknown> | boolean;
21
+ /** 标签列表 */
22
+ tags?: string[];
23
+ /** 扩展注解 */
24
+ annotations?: Record<string, unknown>;
25
+ }
26
+
27
+ /**
28
+ * 资产或模块依赖描述。
29
+ */
30
+ export interface AssetDependency {
31
+ /** 资产相对路径 */
32
+ path: string;
33
+ /** 资产绝对物理路径 */
34
+ resolvedPath: string;
35
+ /** 资产类型:静态资产、规程文档、配置文件或模块源码 */
36
+ type: "asset" | "playbook" | "config" | "module";
37
+ }
38
+
39
+ /**
40
+ * 外部依赖描述。
41
+ */
42
+ export interface ExternalDependency {
43
+ /** 外部依赖包名 */
44
+ name: string;
45
+ /** 版本约束范围 */
46
+ versionRange?: string;
47
+ /** 是否为开发期依赖 */
48
+ isDev?: boolean;
49
+ }
50
+
51
+ /**
52
+ * 构建规划中的依赖集合分类。
53
+ */
54
+ export interface BuildPlanDependencies {
55
+ /** Action 依赖闭包 */
56
+ actions: ActionDependency[];
57
+ /** 模块与资产依赖 */
58
+ modulesAndAssets: AssetDependency[];
59
+ /** 外部 npm 依赖 */
60
+ external: ExternalDependency[];
61
+ }
62
+
63
+ /**
64
+ * Playbook 规划项。
65
+ */
66
+ export interface PlaybookPlanEntry {
67
+ id: string;
68
+ filePath: string;
69
+ actions?: string[];
70
+ description?: string;
71
+ }
72
+
73
+ /**
74
+ * 构建规划产物结构。
75
+ */
76
+ export interface BuildPlan {
77
+ /** 所属 Package ID */
78
+ packageId: string;
79
+ /** 项目展示名称 */
80
+ packageName: string;
81
+ /** 版本号 */
82
+ version: string;
83
+ /** 描述信息 */
84
+ description?: string;
85
+ /** 项目根目录绝对路径 */
86
+ projectRoot: string;
87
+ /** 参与构建的 Action 列表 */
88
+ actions: ActionDependency[];
89
+ /** 参与构建的 Playbook 列表 */
90
+ playbooks: PlaybookPlanEntry[];
91
+ /** 分类依赖明细 */
92
+ dependencies: BuildPlanDependencies;
93
+ /** 资产路径列表 */
94
+ assets: string[];
95
+ /** 声明的配置定义字典 */
96
+ configDefs?: Record<string, unknown>;
97
+ /** 规划元数据 */
98
+ metadata: {
99
+ plannedAt: string;
100
+ schemaVersion: number;
101
+ actionCount: number;
102
+ playbookCount: number;
103
+ };
104
+ }
105
+
106
+ /**
107
+ * 构建规划器配置选项。
108
+ */
109
+ export interface BuildPlannerOptions {
110
+ /** 项目根目录绝对路径 */
111
+ projectRoot: string;
112
+ /** 显式传入的项目配置(若未提供则从 actiondock.json 读取) */
113
+ config?: ProjectConfig;
114
+ /** 显式传入的声明式清单(若未提供则从 actiondock.manifest.json 读取) */
115
+ manifest?: ActionDockManifest;
116
+ /** 挑选的 Action ID 列表(用于依赖闭包裁剪) */
117
+ actions?: string[];
118
+ /** 挑选的 Playbook ID 列表(用于 Playbook 驱动的依赖闭包裁剪) */
119
+ playbooks?: string[];
120
+ }
121
+
122
+ /**
123
+ * 支持的 Bun 独立编译目标平台。
124
+ */
125
+ export type CompileTarget =
126
+ | "bun"
127
+ | "host"
128
+ | "bun-linux-x64"
129
+ | "linux-x64"
130
+ | "bun-linux-arm64"
131
+ | "linux-arm64"
132
+ | "bun-darwin-x64"
133
+ | "darwin-x64"
134
+ | "bun-darwin-arm64"
135
+ | "darwin-arm64"
136
+ | "bun-windows-x64"
137
+ | "windows-x64"
138
+ | "bun-linux-x64-baseline"
139
+ | "linux-x64-baseline"
140
+ | "bun-linux-x64-modern"
141
+ | "linux-x64-modern";
142
+
143
+ /**
144
+ * Bun 独立编译器参数选项。
145
+ */
146
+ export interface BunCompilerOptions {
147
+ /** 编译入口文件绝对路径 */
148
+ entrypoint: string;
149
+ /** 目标二进制文件输出路径 */
150
+ outfile: string;
151
+ /** 编译目标平台架构(默认 host) */
152
+ target?: CompileTarget | string;
153
+ /** 是否开启代码压缩混淆(默认 true) */
154
+ minify?: boolean;
155
+ /** 是否启用字节码预编译(默认 true) */
156
+ bytecode?: boolean;
157
+ /** 构建工作目录(默认入口文件所在根目录) */
158
+ cwd?: string;
159
+ /** 自定义环境变量 */
160
+ env?: Record<string, string>;
161
+ /** 所属 Package ID(写入元数据用) */
162
+ packageId?: string;
163
+ /** 所属版本号(写入元数据用) */
164
+ version?: string;
165
+ /** 包含的 Action ID 列表(写入元数据用) */
166
+ actions?: string[];
167
+ /** 是否生成 artifact.json 元数据文件(默认 true) */
168
+ emitMetadata?: boolean;
169
+ }
170
+
171
+ /**
172
+ * Bun 独立编译器输出结果。
173
+ */
174
+ export interface BunCompilerResult {
175
+ /** 所属 Package ID */
176
+ packageId?: string;
177
+ /** 版本号 */
178
+ version?: string;
179
+ /** 编译目标架构 */
180
+ target: string;
181
+ /** 独立二进制文件绝对路径 */
182
+ executablePath: string;
183
+ /** 独立二进制文件字节大小 */
184
+ sizeBytes: number;
185
+ /** 独立二进制文件的 SHA-256 校验和 */
186
+ sha256: string;
187
+ /** 生成的元数据文件绝对路径(若生成) */
188
+ metadataPath?: string;
189
+ /** 编译是否开启混淆 */
190
+ minify: boolean;
191
+ /** 编译是否启用字节码 */
192
+ bytecode: boolean;
193
+ /** 编译耗时(毫秒) */
194
+ durationMs: number;
195
+ /** 编译完成时间戳 */
196
+ compiledAt: string;
197
+ }
198
+
199
+ /**
200
+ * 归档压缩格式。
201
+ */
202
+ export type ArchiveFormat = "zip" | "tar.gz";
203
+
204
+ /**
205
+ * Skill 导出选项。
206
+ */
207
+ export interface SkillExporterOptions {
208
+ /** 源码项目根目录绝对路径 */
209
+ projectRoot: string;
210
+ /** 导出模式:source 源码模式 或 standalone 独立二进制模式(默认 source) */
211
+ mode?: "source" | "standalone";
212
+ /** 是否开启独立二进制模式(简写选项) */
213
+ standalone?: boolean;
214
+ /** 二进制编译目标架构(仅在独立二进制模式生效,默认 host) */
215
+ target?: CompileTarget | string;
216
+ /** 导出产物目标目录(默认输出至 dist 目录) */
217
+ outDir?: string;
218
+ /** 是否执行归档压缩,亦可直接指定归档格式 */
219
+ archive?: boolean | ArchiveFormat;
220
+ /** 归档压缩格式(zip 或 tar.gz) */
221
+ archiveFormat?: ArchiveFormat;
222
+ /** 挑选的 Playbook 列表(用于 Playbook 驱动的依赖闭包裁剪) */
223
+ playbooks?: string[];
224
+ /** 挑选的 Action 列表(用于 Action 驱动的依赖闭包裁剪) */
225
+ actions?: string[];
226
+ /** 独立二进制模式下是否开启代码混淆(默认 true) */
227
+ minify?: boolean;
228
+ /** 独立二进制模式下是否编译为字节码(默认 true) */
229
+ bytecode?: boolean;
230
+ /** 预置的项目配置(可选) */
231
+ config?: ProjectConfig;
232
+ /** 预置的声明式清单(可选) */
233
+ manifest?: ActionDockManifest;
234
+ }
235
+
236
+ /**
237
+ * Skill 导出完成结果。
238
+ */
239
+ export interface SkillExportResult {
240
+ /** 所属 Package ID */
241
+ packageId: string;
242
+ /** 项目版本号 */
243
+ version: string;
244
+ /** 导出模式 */
245
+ mode: "source" | "standalone";
246
+ /** 目标平台架构 */
247
+ target: string;
248
+ /** 生成的 Skill 目录绝对路径 */
249
+ skillDir: string;
250
+ /** 生成的归档文件绝对路径(若开启压缩) */
251
+ archivePath?: string;
252
+ /** 导出的 Action 数量 */
253
+ actionsCount: number;
254
+ /** 导出的 Playbook 数量 */
255
+ playbooksCount: number;
256
+ /** 导出的 Action ID 列表 */
257
+ actions: string[];
258
+ /** 导出的 Playbook ID 列表 */
259
+ playbooks: string[];
260
+ /** 导出的文件相对路径清单 */
261
+ files: string[];
262
+ }