@actiondock/builder 2.16.0 → 2.17.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 +37 -15
- package/dist/dependency-check.d.ts +1 -1
- package/dist/dependency-check.js +5 -0
- package/dist/export-composite.js +5 -2
- package/dist/export-source.d.ts +1 -1
- package/dist/export-source.js +2 -1
- package/dist/exporter.js +4 -3
- package/dist/types.d.ts +8 -0
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -40,21 +40,29 @@ ActionDock 2.x 构建规划、目录交付与技能导出包。
|
|
|
40
40
|
|
|
41
41
|
### SkillExporter 与技能导出
|
|
42
42
|
|
|
43
|
-
[SkillExporter](./src/exporter.ts)
|
|
43
|
+
[SkillExporter](./src/exporter.ts)、`exportSkill` 以及 `exportCompositeSkill` 导出函数将原子 Action 与操作规程 Playbook 打包导出为面向主流 AI 智能体生态的标准 Agent Skill 资产:
|
|
44
44
|
|
|
45
|
-
-
|
|
46
|
-
-
|
|
45
|
+
- 默认单包浅导出机制:默认采用单包源码浅闭包导出,仅复制当前包自身源码与规程,产物清单完整保留 `uses` 跨包逻辑契约,不物理拷贝外部包源码,单包结构纯粹透明,天然支持配合 `playbooks` 或 `actions` 执行规程驱动剪枝。
|
|
46
|
+
- 显式外部依赖物化:支持 `bundleDeps` 选项。当显式开启且依赖闭包跨越外部已链接包时,自顶向下递归解析依赖链并将外部依赖包物理物化进产物根目录的 `packages/*` 子目录,展开为自包含的微型工作区产物结构;展开为复合形态时与过滤参数严格互斥(抛出 `FILTERS_UNSUPPORTED_FOR_COMPOSITE` 错误)。
|
|
47
|
+
- 独立自包含 Node 目录型导出:支持 `standalone` 选项(等价于 `mode: "node"`),生成免全局 `ad` 命令行工具的自包含目录,内置独立运行脚本与说明书,配合 `vendorDeps` 可实现生产依赖完全内置。
|
|
47
48
|
- 本地依赖完整性强校验:严格断言 Action 源码中的相对路径导入。若引用了未在 `actions` 且未在 `files` 字段中声明的本地模块,直接中断构建并抛出 `BuilderError`(错误码 `UNMET_LOCAL_DEPENDENCY`),彻底杜绝缺失依赖的产物分发。
|
|
48
|
-
-
|
|
49
|
-
-
|
|
50
|
-
- 压缩归档:支持
|
|
49
|
+
- 生成 SKILL.md 指令:提取 Playbook 规程内容与工具元数据,合成符合智能体规范的操作指南文档与声明头部。
|
|
50
|
+
- 复合套件导出与说明书定制:支持 `exportCompositeSkill` 函数将工作区内的多个包统一导出为复合工作区技能套件;支持通过 `customMdPath` 注入插槽定制模板,通过 `skillMdOnly` 实现就地仅原位刷新说明书。
|
|
51
|
+
- 压缩归档:支持 `archive` 选项将导出的技能目录打包为 `.zip` 或 `.tar.gz` 格式。
|
|
51
52
|
|
|
52
53
|
---
|
|
53
54
|
|
|
54
55
|
## 编程调用示例
|
|
55
56
|
|
|
56
57
|
```ts
|
|
57
|
-
import {
|
|
58
|
+
import {
|
|
59
|
+
buildProject,
|
|
60
|
+
packProject,
|
|
61
|
+
SelectionPlanner,
|
|
62
|
+
SkillExporter,
|
|
63
|
+
exportSkill,
|
|
64
|
+
exportCompositeSkill,
|
|
65
|
+
} from "@actiondock/builder";
|
|
58
66
|
|
|
59
67
|
// 计算依赖规划闭包
|
|
60
68
|
const planner = new SelectionPlanner({ projectRoot: "/path/to/project" });
|
|
@@ -73,20 +81,34 @@ const packResult = await packProject({
|
|
|
73
81
|
outDir: "./dist/npm",
|
|
74
82
|
});
|
|
75
83
|
|
|
76
|
-
//
|
|
84
|
+
// 默认源码单包浅导出(支持规程定向裁剪)
|
|
77
85
|
const skillResult = await exportSkill({
|
|
78
86
|
projectRoot: "/path/to/project",
|
|
79
|
-
outDir: "./dist/skills",
|
|
87
|
+
outDir: "./dist/skills/review-pr",
|
|
80
88
|
playbooks: ["review-pr"],
|
|
81
|
-
mode: "source",
|
|
82
89
|
});
|
|
83
90
|
|
|
84
|
-
//
|
|
85
|
-
const
|
|
86
|
-
const customResult = await exporter.export({
|
|
91
|
+
// 显式物化外部依赖导出(展开为微型工作区)
|
|
92
|
+
const bundledResult = await exportSkill({
|
|
87
93
|
projectRoot: "/path/to/project",
|
|
88
|
-
outDir: "./dist/skills
|
|
89
|
-
|
|
94
|
+
outDir: "./dist/skills/bundled",
|
|
95
|
+
bundleDeps: true,
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
// 独立自包含 Node.js 目录型导出(免全局 ad 命令行,物化生产依赖)
|
|
99
|
+
const standaloneResult = await exportSkill({
|
|
100
|
+
projectRoot: "/path/to/project",
|
|
101
|
+
outDir: "./dist/skills/standalone",
|
|
102
|
+
standalone: true,
|
|
103
|
+
vendorDeps: true,
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// 复合套件聚合导出与就地原位刷新说明书
|
|
107
|
+
const compositeResult = await exportCompositeSkill({
|
|
108
|
+
bundleName: "vip-agent-tools",
|
|
109
|
+
projectRoots: ["/path/to/pkg-a", "/path/to/pkg-b"],
|
|
110
|
+
outDir: "./dist/composite-skill",
|
|
111
|
+
customMdPath: "/path/to/SKILL.custom.md",
|
|
90
112
|
});
|
|
91
113
|
```
|
|
92
114
|
|
package/dist/dependency-check.js
CHANGED
|
@@ -2,6 +2,7 @@ import { existsSync, readFileSync, realpathSync, statSync } from "node:fs";
|
|
|
2
2
|
import { dirname, join, relative, resolve } from "node:path";
|
|
3
3
|
import { isPathOutsideBoundary } from "@actiondock/core/project";
|
|
4
4
|
import { BuilderError } from "./errors.js";
|
|
5
|
+
import { isOwnAction } from "./types.js";
|
|
5
6
|
/**
|
|
6
7
|
* 移除源码中的单行与多行注释,防止注释内的相对路径字符串误触发依赖解析。
|
|
7
8
|
*/
|
|
@@ -130,6 +131,8 @@ export function assertRelativeDependenciesIntegrity(projectRoot, plan) {
|
|
|
130
131
|
// 收集已包含在构建规划中的全部文件物理绝对路径
|
|
131
132
|
const collectedPaths = new Set();
|
|
132
133
|
for (const act of plan.actions) {
|
|
134
|
+
if (!isOwnAction(act))
|
|
135
|
+
continue;
|
|
133
136
|
if (act.resolvedPath) {
|
|
134
137
|
collectedPaths.add(toRealPath(act.resolvedPath));
|
|
135
138
|
}
|
|
@@ -142,6 +145,8 @@ export function assertRelativeDependenciesIntegrity(projectRoot, plan) {
|
|
|
142
145
|
// 待校验文件队列(包括全部 Action 及其收集的 TS/JS 模块)
|
|
143
146
|
const queue = [];
|
|
144
147
|
for (const act of plan.actions) {
|
|
148
|
+
if (!isOwnAction(act))
|
|
149
|
+
continue;
|
|
145
150
|
if (act.resolvedPath && existsSync(act.resolvedPath)) {
|
|
146
151
|
queue.push({ file: toRealPath(act.resolvedPath), actionId: act.id });
|
|
147
152
|
}
|
package/dist/export-composite.js
CHANGED
|
@@ -20,6 +20,9 @@ export async function exportCompositeImpl(options, exportSubpackage) {
|
|
|
20
20
|
if (!options.bundleName || !options.bundleName.trim()) {
|
|
21
21
|
throw new BuilderError("bundleName is required for composite skill export.");
|
|
22
22
|
}
|
|
23
|
+
if (options.standalone) {
|
|
24
|
+
throw new BuilderError("Composite Skill export currently only supports source mode. Standalone mode is not supported for composite bundles.", "UNSUPPORTED_BUILD_MODE");
|
|
25
|
+
}
|
|
23
26
|
const skillMdOnly = options.skillMdOnly === true;
|
|
24
27
|
const customDeclaration = resolveCustomSkillDeclaration(options);
|
|
25
28
|
const bundleSlug = getPackageSlug(options.bundleName);
|
|
@@ -41,11 +44,11 @@ export async function exportCompositeImpl(options, exportSubpackage) {
|
|
|
41
44
|
const packageSummaries = [];
|
|
42
45
|
let existingSkillPath;
|
|
43
46
|
try {
|
|
44
|
-
//
|
|
47
|
+
// 收集项目根目录;仅在显式指定 bundleDeps 时展开依赖闭包中的外部项目根目录
|
|
45
48
|
const effectiveRoots = new Set();
|
|
46
49
|
for (const r of options.projectRoots) {
|
|
47
50
|
effectiveRoots.add(resolve(r));
|
|
48
|
-
if (!skillMdOnly) {
|
|
51
|
+
if (!skillMdOnly && options.bundleDeps === true) {
|
|
49
52
|
try {
|
|
50
53
|
const p = SelectionPlanner.plan({ projectRoot: r });
|
|
51
54
|
if (p.externalProjectRoots) {
|
package/dist/export-source.d.ts
CHANGED
package/dist/export-source.js
CHANGED
|
@@ -7,6 +7,7 @@ import { BuilderError } from "./errors.js";
|
|
|
7
7
|
import { getInternalDependencyVersion } from "./fs-utils.js";
|
|
8
8
|
import { assertValidManifestActionIds, sanitizeExportDependencies, serializePlanManifest, } from "./manifest.js";
|
|
9
9
|
import { copyPlanEntries } from "./stage-sources.js";
|
|
10
|
+
import { isOwnAction } from "./types.js";
|
|
10
11
|
import { buildConfigForTemplates, writeSkillMd, } from "./skill-md.js";
|
|
11
12
|
/**
|
|
12
13
|
* 源码型 Skill 导出装配层。
|
|
@@ -21,7 +22,7 @@ export function stageSourceSkill(root, skillDir, plan, options, pkgSlug) {
|
|
|
21
22
|
const actionsDir = plan.actionsDir || "actions";
|
|
22
23
|
const playbooksDir = plan.playbooksDir || "playbooks";
|
|
23
24
|
const configForTemplates = buildConfigForTemplates(plan, actionsDir, playbooksDir);
|
|
24
|
-
const usedExistingSkillMd = writeSkillMd(root, skillDir, { skipSkillMd: options.skipSkillMd, skillMdPath: options.skillMdPath, pkgSlug }, () => generateSourceSkillMd(configForTemplates, plan.actions, plan.playbooks));
|
|
25
|
+
const usedExistingSkillMd = writeSkillMd(root, skillDir, { skipSkillMd: options.skipSkillMd, skillMdPath: options.skillMdPath, pkgSlug }, () => generateSourceSkillMd(configForTemplates, plan.actions.filter((a) => isOwnAction(a)), plan.playbooks));
|
|
25
26
|
// 导出精简后的 actiondock.json 项目配置(项目元数据与清单的单一事实源)
|
|
26
27
|
const exportedConfig = serializePlanManifest(plan, {
|
|
27
28
|
omitEmptyConfig: true,
|
package/dist/exporter.js
CHANGED
|
@@ -25,7 +25,7 @@ export class SkillExporter {
|
|
|
25
25
|
*/
|
|
26
26
|
async export(options) {
|
|
27
27
|
const root = resolve(options.projectRoot);
|
|
28
|
-
const mode = options.mode === "node" ? "node" : "source";
|
|
28
|
+
const mode = options.standalone === true || options.mode === "node" ? "node" : "source";
|
|
29
29
|
// 调用 SelectionPlanner 执行声明式构建规划
|
|
30
30
|
const plan = SelectionPlanner.plan({
|
|
31
31
|
projectRoot: root,
|
|
@@ -40,12 +40,12 @@ export class SkillExporter {
|
|
|
40
40
|
const defaultSkillDir = join(root, "dist", defaultFolderName);
|
|
41
41
|
const targetSkillDir = resolve(options.outDir || defaultSkillDir);
|
|
42
42
|
const hasExternalDeps = Boolean(plan.externalProjectRoots && plan.externalProjectRoots.length > 0);
|
|
43
|
-
//
|
|
43
|
+
// 单包源码导出若开启 bundleDeps 且依赖闭包含外部包,导成 mini-workspace 形态(packages/ 下带齐依赖包),和 bundle 统一成一个交付形状
|
|
44
44
|
// 该复合分支会展开全部依赖包,无法保留调用方传入的 actions/playbooks 过滤选项;
|
|
45
45
|
// 静默丢弃过滤会导致产物全量导出,必须显式拒绝并给出调整指引(CLI 侧已有 roots>1 守卫,此处补齐 composite 分支守卫)
|
|
46
46
|
const hasFilters = Boolean((options.actions && options.actions.length > 0) ||
|
|
47
47
|
(options.playbooks && options.playbooks.length > 0));
|
|
48
|
-
const willUseComposite = mode === "source" && !options._isSubpackage && hasExternalDeps;
|
|
48
|
+
const willUseComposite = mode === "source" && !options._isSubpackage && hasExternalDeps && options.bundleDeps === true;
|
|
49
49
|
if (hasFilters && willUseComposite) {
|
|
50
50
|
throw new BuilderError("Filtering options (--actions, --playbook) cannot be combined with a source export whose dependency closure spans external linked packages (composite mini-workspace output). Remove the filtering options to export the full closure, or adjust the 'uses' declarations so the closure stays within a single package.", "FILTERS_UNSUPPORTED_FOR_COMPOSITE");
|
|
51
51
|
}
|
|
@@ -60,6 +60,7 @@ export class SkillExporter {
|
|
|
60
60
|
workspaceRoot: options.workspaceRoot,
|
|
61
61
|
skillMdPath: options.skillMdPath,
|
|
62
62
|
customMdPath: options.customMdPath,
|
|
63
|
+
bundleDeps: options.bundleDeps,
|
|
63
64
|
});
|
|
64
65
|
return {
|
|
65
66
|
packageId: plan.packageId,
|
package/dist/types.d.ts
CHANGED
|
@@ -308,6 +308,10 @@ export interface SkillExporterOptions {
|
|
|
308
308
|
projectRoot: string;
|
|
309
309
|
/** 导出模式:source 源码型 Skill 或 node 目录型 Skill(默认 source) */
|
|
310
310
|
mode?: "source" | "node";
|
|
311
|
+
/** 独立自包含模式(若为 true 则将导出模式设为 node 目录型) */
|
|
312
|
+
standalone?: boolean;
|
|
313
|
+
/** 是否将跨包依赖物理物化为微型工作区复合结构(默认 false) */
|
|
314
|
+
bundleDeps?: boolean;
|
|
311
315
|
/** 导出产物目标目录(默认输出至 dist 目录) */
|
|
312
316
|
outDir?: string;
|
|
313
317
|
/** 是否执行归档压缩,亦可直接指定归档格式 */
|
|
@@ -386,6 +390,10 @@ export interface CompositeSkillExportOptions {
|
|
|
386
390
|
projectRoots: string[];
|
|
387
391
|
/** 复合套件输出目标目录(默认输出至 dist 目录) */
|
|
388
392
|
outDir?: string;
|
|
393
|
+
/** 是否将外部依赖物理物化进复合产物(默认 false) */
|
|
394
|
+
bundleDeps?: boolean;
|
|
395
|
+
/** 独立自包含模式(复合导出暂不支持) */
|
|
396
|
+
standalone?: boolean;
|
|
389
397
|
/** 复合技能描述信息 */
|
|
390
398
|
description?: string;
|
|
391
399
|
/** 是否执行归档压缩,亦可直接指定归档格式 */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@actiondock/builder",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.17.0",
|
|
4
4
|
"description": "ActionDock Build Planner, distribution packaging, and Skill exporter",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
"test": "node ../../scripts/run-tests.ts"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@actiondock/core": "^2.
|
|
33
|
-
"@actiondock/sdk": "^2.
|
|
32
|
+
"@actiondock/core": "^2.17.0",
|
|
33
|
+
"@actiondock/sdk": "^2.17.0"
|
|
34
34
|
},
|
|
35
35
|
"keywords": [
|
|
36
36
|
"actiondock",
|