@actiondock/core 2.13.0 → 2.15.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/dist/catalog/discovery.d.ts +3 -3
- package/dist/catalog/graph.d.ts +6 -8
- package/dist/catalog/graph.js +197 -62
- package/dist/catalog/resolve-playbook.d.ts +2 -2
- package/dist/catalog/resolve-playbook.js +12 -53
- package/dist/execution/types.d.ts +2 -2
- package/dist/host/routing.d.ts +1 -1
- package/dist/host/routing.js +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +1 -1
- package/dist/package/runtime.d.ts +2 -2
- package/dist/package/runtime.js +3 -1
- package/dist/package/static-index.d.ts +4 -6
- package/dist/package/static-index.js +12 -60
- package/dist/package/types.d.ts +5 -5
- package/dist/project/index.d.ts +1 -0
- package/dist/project/index.js +1 -0
- package/dist/project/init.js +2 -2
- package/dist/project/loader.d.ts +4 -2
- package/dist/project/loader.js +38 -34
- package/dist/project/manifest.d.ts +2 -0
- package/dist/project/manifest.js +17 -1
- package/dist/project/skill-dir.d.ts +72 -0
- package/dist/project/skill-dir.js +244 -0
- package/dist/project/types.d.ts +31 -0
- package/dist/registry/registry.js +27 -15
- package/dist/runtime/context.d.ts +3 -3
- package/dist/runtime/standalone-commands.js +8 -2
- package/dist/runtime/standalone.d.ts +2 -0
- package/dist/storage/sqlite-driver.d.ts +0 -1
- package/dist/storage/sqlite-driver.js +0 -1
- package/dist/utils/index.d.ts +0 -1
- package/dist/utils/index.js +0 -1
- package/dist/utils/semver.d.ts +2 -1
- package/dist/utils/semver.js +11 -5
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -7
- package/dist/utils/warning.d.ts +0 -1
- package/dist/utils/warning.js +0 -52
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ActionDockManifest } from "../project/types.js";
|
|
1
|
+
import type { ActionDockManifest, PlaybookSourceManifest } from "../project/types.js";
|
|
2
2
|
import type { PackageIdentity } from "../runtime/identity.js";
|
|
3
3
|
/**
|
|
4
4
|
* 发现的包基本信息规范。
|
|
@@ -8,8 +8,8 @@ export interface DiscoveredPackage {
|
|
|
8
8
|
readonly id: string;
|
|
9
9
|
/** 包物理根目录绝对路径 */
|
|
10
10
|
readonly root: string;
|
|
11
|
-
/**
|
|
12
|
-
readonly manifest: ActionDockManifest;
|
|
11
|
+
/** 包清单定义(支持磁盘声明式清单与运行时规程来源清单) */
|
|
12
|
+
readonly manifest: ActionDockManifest | PlaybookSourceManifest;
|
|
13
13
|
/** 包物理与快照身份凭证(可选,由已有运行时传入) */
|
|
14
14
|
readonly identity?: PackageIdentity;
|
|
15
15
|
/** 是否来自工作区目录扫描发现 */
|
package/dist/catalog/graph.d.ts
CHANGED
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
import { ActionDockError } from "../errors.js";
|
|
2
2
|
import { type ActionDockLockfile } from "../project/lockfile.js";
|
|
3
|
-
import type { ActionDockManifest, PlaybookDefinition } from "../project/types.js";
|
|
3
|
+
import type { ActionDockManifest, PlaybookDefinition, PlaybookSourceManifest } from "../project/types.js";
|
|
4
4
|
import { type PackageIdentity } from "../runtime/identity.js";
|
|
5
5
|
import { parseSemVer, type SemVer } from "../utils/index.js";
|
|
6
6
|
import { type DiscoveredPackage, type PackageDiscoveryOptions } from "./discovery.js";
|
|
7
7
|
export type { SemVer };
|
|
8
8
|
export { parseSemVer };
|
|
9
|
-
/**
|
|
10
|
-
* 校验两个语义化版本范围是否兼容并能收敛为单一解析版本。
|
|
11
|
-
* 遵循设计规范:直接或传递版本范围无法收敛时拒绝并抛出 ACTION_PACKAGE_VERSION_CONFLICT。
|
|
12
|
-
*/
|
|
13
9
|
export declare function areVersionsCompatible(v1: string, v2: string): boolean;
|
|
14
10
|
/**
|
|
15
11
|
* 版本冲突错误。
|
|
@@ -55,8 +51,8 @@ export interface PackageNode {
|
|
|
55
51
|
readonly packageId: string;
|
|
56
52
|
/** 包根目录绝对物理路径 */
|
|
57
53
|
readonly root: string;
|
|
58
|
-
/**
|
|
59
|
-
readonly manifest: ActionDockManifest;
|
|
54
|
+
/** 包清单规范(支持磁盘声明式清单与运行时规程来源清单) */
|
|
55
|
+
readonly manifest: ActionDockManifest | PlaybookSourceManifest;
|
|
60
56
|
/** 包清单摘要哈希 */
|
|
61
57
|
readonly manifestDigest: string;
|
|
62
58
|
/** 包版本号 */
|
|
@@ -145,12 +141,14 @@ export declare class DefaultPackageGraph implements PackageGraph {
|
|
|
145
141
|
export interface PackageGraphBuilderOptions {
|
|
146
142
|
/** 预先发现的包集合,若未提供则通过 PackageDiscovery 自动发现 */
|
|
147
143
|
packages?: DiscoveredPackage[];
|
|
144
|
+
/** 完整显式集合的依赖存在性与选定版本校验(Host 增量注册时不启用)。 */
|
|
145
|
+
validateDependencies?: boolean;
|
|
148
146
|
/** 根工程根目录或根包标识(与 projectRoot 互为别名) */
|
|
149
147
|
root?: string;
|
|
150
148
|
/** 当前工程根目录绝对或相对物理路径 */
|
|
151
149
|
projectRoot?: string;
|
|
152
150
|
/** 显式根清单 */
|
|
153
|
-
manifest?: ActionDockManifest;
|
|
151
|
+
manifest?: ActionDockManifest | PlaybookSourceManifest;
|
|
154
152
|
/** 锁文件规范对象(若未显式提供且 projectRoot 存在,则尝试自动读取 actiondock.lock.json) */
|
|
155
153
|
lockfile?: ActionDockLockfile;
|
|
156
154
|
/** 是否允许扫描与链接开发软链接包(默认根据 discoveryOptions 判定) */
|
package/dist/catalog/graph.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from "node:fs";
|
|
2
2
|
import { basename, dirname, join, resolve } from "node:path";
|
|
3
|
-
import { ActionDockError, ACTION_PACKAGE_VERSION_CONFLICT, MANIFEST_DIGEST_MISMATCH, MANIFEST_NOT_FOUND, MANIFEST_READ_FAILED, PACKAGE_NOT_FOUND, UNDECLARED_ACTION_DEPENDENCY, } from "../errors.js";
|
|
3
|
+
import { ActionDockError, ACTION_PACKAGE_VERSION_CONFLICT, MANIFEST_DIGEST_MISMATCH, MANIFEST_NOT_FOUND, MANIFEST_READ_FAILED, PACKAGE_NOT_FOUND, PACKAGE_ID_CONFLICT, INVALID_ARGUMENT, UNDECLARED_ACTION_DEPENDENCY, } from "../errors.js";
|
|
4
4
|
import { computeManifestDigest, parseJsonWithoutDuplicates } from "../project/digest.js";
|
|
5
5
|
import { loadLockfile } from "../project/lockfile.js";
|
|
6
6
|
import { loadPlaybooks, loadProjectConfig } from "../project/loader.js";
|
|
@@ -10,30 +10,124 @@ import { createPackageIdentity } from "../runtime/identity.js";
|
|
|
10
10
|
import { parseSemVer } from "../utils/index.js";
|
|
11
11
|
import { PackageDiscovery } from "./discovery.js";
|
|
12
12
|
export { parseSemVer };
|
|
13
|
-
/**
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
13
|
+
/** 有限版本契约:严格三段版本(允许 v/= 前缀)、^、~、*;不猜测其他范围。 */
|
|
14
|
+
function parseVersionRange(value) {
|
|
15
|
+
const text = value.trim();
|
|
16
|
+
if (!text || text === "*")
|
|
17
|
+
return {};
|
|
18
|
+
const prefix = text[0];
|
|
19
|
+
const minimum = parseSemVer(prefix === "^" || prefix === "~" ? text.slice(1) : text);
|
|
20
|
+
if (!minimum)
|
|
21
|
+
return undefined;
|
|
22
|
+
if (prefix !== "^" && prefix !== "~")
|
|
23
|
+
return { minimum, exact: true };
|
|
24
|
+
const maximum = prefix === "~"
|
|
25
|
+
? { major: minimum.major, minor: minimum.minor + 1, patch: 0 }
|
|
26
|
+
: minimum.major > 0 ? { major: minimum.major + 1, minor: 0, patch: 0 }
|
|
27
|
+
: minimum.minor > 0 ? { major: 0, minor: minimum.minor + 1, patch: 0 }
|
|
28
|
+
: { major: 0, minor: 0, patch: minimum.patch + 1 };
|
|
29
|
+
return { minimum, maximum };
|
|
30
|
+
}
|
|
31
|
+
function compareVersions(a, b) {
|
|
32
|
+
const core = a.major - b.major || a.minor - b.minor || a.patch - b.patch;
|
|
33
|
+
if (core)
|
|
34
|
+
return core;
|
|
35
|
+
if (a.prerelease === b.prerelease)
|
|
36
|
+
return 0;
|
|
37
|
+
if (a.prerelease === undefined)
|
|
38
|
+
return 1;
|
|
39
|
+
if (b.prerelease === undefined)
|
|
40
|
+
return -1;
|
|
41
|
+
const left = a.prerelease.split(".");
|
|
42
|
+
const right = b.prerelease.split(".");
|
|
43
|
+
for (let i = 0; i < Math.max(left.length, right.length); i++) {
|
|
44
|
+
if (left[i] === undefined)
|
|
45
|
+
return -1;
|
|
46
|
+
if (right[i] === undefined)
|
|
47
|
+
return 1;
|
|
48
|
+
if (left[i] === right[i])
|
|
49
|
+
continue;
|
|
50
|
+
const numericLeft = /^\d+$/.test(left[i]);
|
|
51
|
+
const numericRight = /^\d+$/.test(right[i]);
|
|
52
|
+
if (numericLeft && numericRight)
|
|
53
|
+
return BigInt(left[i]) < BigInt(right[i]) ? -1 : 1;
|
|
54
|
+
if (numericLeft !== numericRight)
|
|
55
|
+
return numericLeft ? -1 : 1;
|
|
56
|
+
return left[i] < right[i] ? -1 : 1;
|
|
20
57
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
58
|
+
return 0;
|
|
59
|
+
}
|
|
60
|
+
function satisfiesRange(version, range) {
|
|
61
|
+
if (range.exact)
|
|
62
|
+
return compareVersions(version, range.minimum) === 0;
|
|
63
|
+
if (range.minimum && compareVersions(version, range.minimum) < 0)
|
|
64
|
+
return false;
|
|
65
|
+
if (range.maximum && compareVersions(version, range.maximum) >= 0)
|
|
66
|
+
return false;
|
|
67
|
+
// 预发布版本仅在范围下界显式点名同一核心版本的预发布时纳入。
|
|
68
|
+
if (version.prerelease !== undefined) {
|
|
69
|
+
const min = range.minimum;
|
|
70
|
+
return Boolean(min?.prerelease && version.major === min.major && version.minor === min.minor && version.patch === min.patch);
|
|
27
71
|
}
|
|
28
|
-
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
export function areVersionsCompatible(v1, v2) {
|
|
75
|
+
const left = parseVersionRange(v1);
|
|
76
|
+
const right = parseVersionRange(v2);
|
|
77
|
+
if (!left || !right)
|
|
29
78
|
return false;
|
|
79
|
+
const candidate = !left.minimum ? right.minimum : !right.minimum ? left.minimum
|
|
80
|
+
: compareVersions(left.minimum, right.minimum) >= 0 ? left.minimum : right.minimum;
|
|
81
|
+
if (!candidate)
|
|
82
|
+
return true;
|
|
83
|
+
if (satisfiesRange(candidate, left) && satisfiesRange(candidate, right))
|
|
84
|
+
return true;
|
|
85
|
+
// 两个范围可以在预发布下界之后的稳定版本交汇,但不能改变精确版本。
|
|
86
|
+
const stable = { major: candidate.major, minor: candidate.minor, patch: candidate.patch };
|
|
87
|
+
return satisfiesRange(stable, left) && satisfiesRange(stable, right);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* 判定给定的依赖规格是否为不支持的语义化版本范围形态(而非获取描述)。
|
|
91
|
+
*
|
|
92
|
+
* 规则:
|
|
93
|
+
* - 范围操作符开头:^, ~, <, >, =, *;
|
|
94
|
+
* - 复合范围操作符:|| 或 - 范围;
|
|
95
|
+
* - X 范围与通配:如 1.x, 1.2.x, 1.*, 1.2.*, v1.x 等;
|
|
96
|
+
* - 不完整两段或一段版本:如 1, 1.2, v1, v1.2 等;
|
|
97
|
+
* - 版本三段式开头但未被严格解析器支持的非法形态。
|
|
98
|
+
*/
|
|
99
|
+
function isUnsupportedVersionRange(spec) {
|
|
100
|
+
const text = spec.trim();
|
|
101
|
+
if (!text)
|
|
102
|
+
return false;
|
|
103
|
+
if (/^[~^<>=*]/.test(text))
|
|
104
|
+
return true;
|
|
105
|
+
if (/\|\||\s+-\s+/.test(text))
|
|
106
|
+
return true;
|
|
107
|
+
if (/^v?\d+\.(?:[xX*]|\d+\.[xX*])(?:$|[-+])/.test(text))
|
|
108
|
+
return true;
|
|
109
|
+
if (/^v?\d+(?:\.\d+)?$/.test(text))
|
|
110
|
+
return true;
|
|
111
|
+
if (/^v?\d+\.\d+\.\d+/.test(text))
|
|
112
|
+
return true;
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
/** 获取描述不是版本约束;仅真实范围及锁定版本参与版本兼容校验。 */
|
|
116
|
+
function dependencyVersionRequirements(spec, locked) {
|
|
117
|
+
const requirements = [];
|
|
118
|
+
const range = spec === undefined ? undefined : parseVersionRange(spec);
|
|
119
|
+
if (spec !== undefined && range)
|
|
120
|
+
requirements.push(spec);
|
|
121
|
+
else if (spec !== undefined && isUnsupportedVersionRange(spec)) {
|
|
122
|
+
throw new ActionDockError(INVALID_ARGUMENT, `Unsupported Action package version range '${spec}'; supported forms are exact versions, ^, ~ and *`);
|
|
30
123
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
124
|
+
const lockedVersion = locked?.resolved || locked?.version;
|
|
125
|
+
if (lockedVersion && parseSemVer(lockedVersion))
|
|
126
|
+
requirements.push(lockedVersion);
|
|
127
|
+
else if (lockedVersion) {
|
|
128
|
+
throw new ActionDockError(INVALID_ARGUMENT, `Invalid locked Action package version '${lockedVersion}'`);
|
|
35
129
|
}
|
|
36
|
-
return
|
|
130
|
+
return requirements;
|
|
37
131
|
}
|
|
38
132
|
/**
|
|
39
133
|
* 版本冲突错误。
|
|
@@ -227,30 +321,20 @@ function computeTransitiveDependencies(nodes) {
|
|
|
227
321
|
function collectVisiblePlaybooks(rootNode, nodes) {
|
|
228
322
|
const visiblePlaybooks = new Map();
|
|
229
323
|
const delegatedActions = new Set();
|
|
230
|
-
if (rootNode
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
visiblePlaybooks.set(`${rootNode.packageId}/${id}`, pb);
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
catch {
|
|
239
|
-
// 忽略根包 Playbook 加载异常
|
|
324
|
+
if (rootNode) {
|
|
325
|
+
const rootPbs = loadPlaybooks(rootNode.root || "", undefined, rootNode.manifest);
|
|
326
|
+
for (const [id, pb] of rootPbs.entries()) {
|
|
327
|
+
visiblePlaybooks.set(id, pb);
|
|
328
|
+
visiblePlaybooks.set(`${rootNode.packageId}/${id}`, pb);
|
|
240
329
|
}
|
|
241
330
|
for (const depId of rootNode.directDependencies) {
|
|
242
331
|
if (depId === rootNode.packageId)
|
|
243
332
|
continue;
|
|
244
333
|
const depNode = nodes.get(depId);
|
|
245
|
-
if (depNode
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
visiblePlaybooks.set(`${depId}/${id}`, pb);
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
catch {
|
|
253
|
-
// 忽略依赖包 Playbook 加载异常
|
|
334
|
+
if (depNode) {
|
|
335
|
+
const depPbs = loadPlaybooks(depNode.root || "", undefined, depNode.manifest);
|
|
336
|
+
for (const [id, pb] of depPbs.entries()) {
|
|
337
|
+
visiblePlaybooks.set(`${depId}/${id}`, pb);
|
|
254
338
|
}
|
|
255
339
|
}
|
|
256
340
|
}
|
|
@@ -280,13 +364,16 @@ export class PackageGraphBuilder {
|
|
|
280
364
|
*/
|
|
281
365
|
buildFromPackages(nodes, generation) {
|
|
282
366
|
for (const pkg of this.options.packages) {
|
|
367
|
+
if (nodes.has(pkg.id)) {
|
|
368
|
+
throw new ActionDockError(PACKAGE_ID_CONFLICT, `Package ID '${pkg.id}' occurs more than once in explicit package graph`);
|
|
369
|
+
}
|
|
283
370
|
const fields = createPackageNodeFields({
|
|
284
371
|
id: pkg.id,
|
|
285
372
|
root: pkg.root,
|
|
286
373
|
manifest: pkg.manifest,
|
|
287
374
|
npmPackage: pkg.id,
|
|
288
375
|
isDirect: Boolean(pkg.isCurrentProject),
|
|
289
|
-
isRoot:
|
|
376
|
+
isRoot: false,
|
|
290
377
|
identity: pkg.identity,
|
|
291
378
|
generation,
|
|
292
379
|
});
|
|
@@ -308,18 +395,46 @@ export class PackageGraphBuilder {
|
|
|
308
395
|
}
|
|
309
396
|
}
|
|
310
397
|
if (!rootIdentity) {
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
break;
|
|
315
|
-
}
|
|
398
|
+
const currentProjectNodes = Array.from(nodes.values()).filter((n) => n.isDirect);
|
|
399
|
+
if (currentProjectNodes.length === 1) {
|
|
400
|
+
rootIdentity = currentProjectNodes[0].identity;
|
|
316
401
|
}
|
|
317
402
|
}
|
|
318
|
-
|
|
319
|
-
const
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
403
|
+
for (const [id, node] of nodes) {
|
|
404
|
+
const isTheRoot = Boolean(rootIdentity && node.identity.id === rootIdentity.id);
|
|
405
|
+
nodes.set(id, { ...node, isRoot: isTheRoot, isDirect: isTheRoot || Boolean(node.isDirect) });
|
|
406
|
+
}
|
|
407
|
+
if (this.options.validateDependencies) {
|
|
408
|
+
for (const node of nodes.values()) {
|
|
409
|
+
const lockfile = node.root ? loadLockfile(node.root) : null;
|
|
410
|
+
for (const [depId, spec] of Object.entries(node.manifest.dependencies || {})) {
|
|
411
|
+
const dep = nodes.get(depId);
|
|
412
|
+
if (!dep) {
|
|
413
|
+
throw new ActionDockError(PACKAGE_NOT_FOUND, `Package '${depId}' required by '${node.packageId}' is missing from explicit graph`);
|
|
414
|
+
}
|
|
415
|
+
for (const requirement of dependencyVersionRequirements(spec)) {
|
|
416
|
+
if (!areVersionsCompatible(requirement, dep.version)) {
|
|
417
|
+
throw new ActionPackageVersionConflictError(depId, [
|
|
418
|
+
{ requester: node.packageId, rangeOrVersion: requirement },
|
|
419
|
+
{ requester: depId, rangeOrVersion: dep.version },
|
|
420
|
+
]);
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
// 根锁文件也可能锁定传递依赖,不能只检查直接 dependencies。
|
|
425
|
+
for (const [depId, locked] of Object.entries(lockfile?.packages || {})) {
|
|
426
|
+
const dep = nodes.get(depId);
|
|
427
|
+
if (!dep)
|
|
428
|
+
continue;
|
|
429
|
+
for (const requirement of dependencyVersionRequirements(undefined, locked)) {
|
|
430
|
+
if (!areVersionsCompatible(requirement, dep.version)) {
|
|
431
|
+
throw new ActionPackageVersionConflictError(depId, [
|
|
432
|
+
{ requester: node.packageId, rangeOrVersion: requirement },
|
|
433
|
+
{ requester: depId, rangeOrVersion: dep.version },
|
|
434
|
+
]);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
}
|
|
323
438
|
}
|
|
324
439
|
}
|
|
325
440
|
linkDirectDependencies(nodes);
|
|
@@ -415,6 +530,13 @@ export class PackageGraphBuilder {
|
|
|
415
530
|
// 忽略扫描外部链接包异常
|
|
416
531
|
}
|
|
417
532
|
}
|
|
533
|
+
const requesterLocks = new Map([[rootPackageId, lockfile]]);
|
|
534
|
+
const getRequesterLock = (requester) => {
|
|
535
|
+
if (!requesterLocks.has(requester)) {
|
|
536
|
+
requesterLocks.set(requester, loadLockfile(nodes.get(requester).root));
|
|
537
|
+
}
|
|
538
|
+
return requesterLocks.get(requester);
|
|
539
|
+
};
|
|
418
540
|
const versionRequirements = new Map();
|
|
419
541
|
function recordRequirement(pkgId, requester, rangeOrVersion) {
|
|
420
542
|
const existing = versionRequirements.get(pkgId) || [];
|
|
@@ -429,10 +551,22 @@ export class PackageGraphBuilder {
|
|
|
429
551
|
existing.push({ requester, rangeOrVersion });
|
|
430
552
|
versionRequirements.set(pkgId, existing);
|
|
431
553
|
}
|
|
554
|
+
const recordDependency = (pkgId, requester, spec) => {
|
|
555
|
+
const requesterLocked = getRequesterLock(requester)?.packages[pkgId];
|
|
556
|
+
for (const requirement of dependencyVersionRequirements(spec, requesterLocked)) {
|
|
557
|
+
recordRequirement(pkgId, requester, requirement);
|
|
558
|
+
}
|
|
559
|
+
const rootLocked = lockfile?.packages[pkgId];
|
|
560
|
+
if (rootLocked && rootLocked !== requesterLocked) {
|
|
561
|
+
for (const requirement of dependencyVersionRequirements(undefined, rootLocked)) {
|
|
562
|
+
recordRequirement(pkgId, rootPackageId, requirement);
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
};
|
|
432
566
|
const queue = [];
|
|
433
567
|
for (const [depId, spec] of Object.entries(rootManifest.dependencies || {})) {
|
|
434
568
|
rootNode.directDependencies.add(depId);
|
|
435
|
-
|
|
569
|
+
recordDependency(depId, rootPackageId, spec);
|
|
436
570
|
queue.push({
|
|
437
571
|
pkgId: depId,
|
|
438
572
|
requester: rootPackageId,
|
|
@@ -460,7 +594,7 @@ export class PackageGraphBuilder {
|
|
|
460
594
|
continue;
|
|
461
595
|
}
|
|
462
596
|
let pkgDir = null;
|
|
463
|
-
const locked = lockfile?.packages
|
|
597
|
+
const locked = getRequesterLock(item.requester)?.packages[item.pkgId] || lockfile?.packages[item.pkgId];
|
|
464
598
|
if (packageRootsRecord?.[item.pkgId]) {
|
|
465
599
|
pkgDir = packageRootsRecord[item.pkgId];
|
|
466
600
|
}
|
|
@@ -474,7 +608,7 @@ export class PackageGraphBuilder {
|
|
|
474
608
|
}
|
|
475
609
|
candidateNames.push(item.rangeOrSpec);
|
|
476
610
|
candidateNames.push(item.pkgId);
|
|
477
|
-
let cur = absProjectRoot;
|
|
611
|
+
let cur = nodes.get(item.requester)?.root || absProjectRoot;
|
|
478
612
|
while (true) {
|
|
479
613
|
for (const candName of candidateNames) {
|
|
480
614
|
const candPath = join(cur, "node_modules", candName);
|
|
@@ -506,6 +640,9 @@ export class PackageGraphBuilder {
|
|
|
506
640
|
throw new ActionDockError(MANIFEST_READ_FAILED, `Failed to read manifest for '${item.pkgId}': ${err.message}`);
|
|
507
641
|
}
|
|
508
642
|
const depManifest = parseJsonWithoutDuplicates(manifestRaw);
|
|
643
|
+
if (depManifest.id !== item.pkgId) {
|
|
644
|
+
throw new ActionDockError(PACKAGE_ID_CONFLICT, `Expected package '${item.pkgId}' at '${pkgDir}', found '${depManifest.id}'`);
|
|
645
|
+
}
|
|
509
646
|
const actualDigest = computeManifestDigest(depManifest);
|
|
510
647
|
if (locked?.manifestDigest && locked.manifestDigest !== actualDigest) {
|
|
511
648
|
throw new ActionDockError(MANIFEST_DIGEST_MISMATCH, `Manifest digest mismatch for package '${item.pkgId}': expected '${locked.manifestDigest}', got '${actualDigest}'. Re-resolution required.`);
|
|
@@ -538,15 +675,13 @@ export class PackageGraphBuilder {
|
|
|
538
675
|
};
|
|
539
676
|
nodes.set(item.pkgId, newNode);
|
|
540
677
|
for (const [subDepId, subSpec] of Object.entries(depManifest.dependencies || {})) {
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
});
|
|
549
|
-
}
|
|
678
|
+
recordDependency(subDepId, item.pkgId, subSpec);
|
|
679
|
+
queue.push({
|
|
680
|
+
pkgId: subDepId,
|
|
681
|
+
requester: item.pkgId,
|
|
682
|
+
rangeOrSpec: subSpec,
|
|
683
|
+
isDirect: false,
|
|
684
|
+
});
|
|
550
685
|
}
|
|
551
686
|
}
|
|
552
687
|
if (scanLinked) {
|
|
@@ -20,7 +20,7 @@ export interface ResolvePlaybookContext {
|
|
|
20
20
|
readonly caller?: string;
|
|
21
21
|
}
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
23
|
+
* 基于 PackageGraph 的规程寻址函数,正文统一由规程加载层提供。
|
|
24
|
+
* 替代原 registry 内部的 resolvePlaybookProject 启发式搜索。
|
|
25
25
|
*/
|
|
26
26
|
export declare function resolvePlaybook(identifier: string, context: ResolvePlaybookContext): ResolvedPlaybook;
|
|
@@ -1,48 +1,12 @@
|
|
|
1
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
-
import { resolve } from "node:path";
|
|
3
1
|
import { loadPlaybooks } from "../project/loader.js";
|
|
4
2
|
import { getPackageSlug } from "../utils/index.js";
|
|
5
3
|
import { ActionDockError, INVALID_ACTION_REF, NOT_FOUND, PACKAGE_NOT_FOUND } from "../errors.js";
|
|
6
4
|
function getNodePlaybooks(node) {
|
|
7
|
-
|
|
8
|
-
if (node.root && existsSync(node.root)) {
|
|
9
|
-
try {
|
|
10
|
-
const diskPlaybooks = loadPlaybooks(node.root, node.manifest?.playbooksDir);
|
|
11
|
-
for (const [k, v] of diskPlaybooks) {
|
|
12
|
-
map.set(k, v);
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
catch {
|
|
16
|
-
// 忽略磁盘规程目录扫描异常
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
if (node.manifest?.playbooks && typeof node.manifest.playbooks === "object") {
|
|
20
|
-
for (const [id, item] of Object.entries(node.manifest.playbooks)) {
|
|
21
|
-
const existing = map.get(id);
|
|
22
|
-
let content = item.content ?? existing?.content ?? "";
|
|
23
|
-
let filePath = item.entry && node.root
|
|
24
|
-
? resolve(node.root, item.entry)
|
|
25
|
-
: existing?.filePath;
|
|
26
|
-
if (!content && filePath && existsSync(filePath)) {
|
|
27
|
-
try {
|
|
28
|
-
content = readFileSync(filePath, "utf-8");
|
|
29
|
-
}
|
|
30
|
-
catch { }
|
|
31
|
-
}
|
|
32
|
-
map.set(id, {
|
|
33
|
-
id,
|
|
34
|
-
description: item.description ?? existing?.description,
|
|
35
|
-
actions: item.actions ?? existing?.actions ?? [],
|
|
36
|
-
content,
|
|
37
|
-
filePath: filePath || "",
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
return map;
|
|
5
|
+
return loadPlaybooks(node.root, node.manifest.playbooksDir, node.manifest);
|
|
42
6
|
}
|
|
43
7
|
/**
|
|
44
|
-
*
|
|
45
|
-
*
|
|
8
|
+
* 基于 PackageGraph 的规程寻址函数,正文统一由规程加载层提供。
|
|
9
|
+
* 替代原 registry 内部的 resolvePlaybookProject 启发式搜索。
|
|
46
10
|
*/
|
|
47
11
|
export function resolvePlaybook(identifier, context) {
|
|
48
12
|
const str = identifier.trim();
|
|
@@ -87,20 +51,15 @@ export function resolvePlaybook(identifier, context) {
|
|
|
87
51
|
// 3. 全局搜索
|
|
88
52
|
const matches = [];
|
|
89
53
|
for (const node of context.graph.packages.values()) {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
catch {
|
|
103
|
-
// 忽略单个包加载异常
|
|
54
|
+
const playbooks = getNodePlaybooks(node);
|
|
55
|
+
const pb = playbooks.get(str);
|
|
56
|
+
if (pb) {
|
|
57
|
+
matches.push({
|
|
58
|
+
packageId: node.identity.id,
|
|
59
|
+
projectRoot: node.root,
|
|
60
|
+
playbookId: str,
|
|
61
|
+
playbook: pb,
|
|
62
|
+
});
|
|
104
63
|
}
|
|
105
64
|
}
|
|
106
65
|
if (matches.length === 1) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ActionDefinition, ActionRef, ExecutionEvent, ExecutionResult, JsonValue, Logger, ProcessAPI, RunRecord, RunStatus } from "@actiondock/sdk";
|
|
2
|
-
import type { ProjectConfig } from "../project/types.js";
|
|
2
|
+
import type { ProjectConfig, RuntimeProjectConfig } from "../project/types.js";
|
|
3
3
|
import type { Clock } from "../storage/clock.js";
|
|
4
4
|
import type { EventSink } from "../runtime/events.js";
|
|
5
5
|
import type { RuntimeStorage } from "../storage/types.js";
|
|
@@ -40,7 +40,7 @@ export interface ExecutionServiceOptions {
|
|
|
40
40
|
storage: RuntimeStorage;
|
|
41
41
|
globalStorage?: RuntimeStorage;
|
|
42
42
|
projectRoot?: string;
|
|
43
|
-
projectConfig?: ProjectConfig;
|
|
43
|
+
projectConfig?: ProjectConfig | RuntimeProjectConfig;
|
|
44
44
|
configOverrides?: Record<string, unknown>;
|
|
45
45
|
actions?: Map<string, ActionDefinition>;
|
|
46
46
|
process?: ProcessAPI;
|
package/dist/host/routing.d.ts
CHANGED
|
@@ -25,7 +25,7 @@ export declare function listVisiblePlaybooks(runtimes: readonly PackageRuntime[]
|
|
|
25
25
|
graph?: PackageGraph;
|
|
26
26
|
}): Promise<PlaybookSummary[]>;
|
|
27
27
|
/**
|
|
28
|
-
* 静态查询指定 Playbook
|
|
28
|
+
* 静态查询指定 Playbook 规范:委托 resolvePlaybook 统一寻址与来源加载。
|
|
29
29
|
*/
|
|
30
30
|
export declare function describeVisiblePlaybook(runtimes: readonly PackageRuntime[], id: string, visibility: {
|
|
31
31
|
hostPublicPackageIds: ReadonlySet<string>;
|
package/dist/host/routing.js
CHANGED
|
@@ -83,7 +83,7 @@ function buildFallbackGraph(runtimes) {
|
|
|
83
83
|
])));
|
|
84
84
|
}
|
|
85
85
|
/**
|
|
86
|
-
* 静态查询指定 Playbook
|
|
86
|
+
* 静态查询指定 Playbook 规范:委托 resolvePlaybook 统一寻址与来源加载。
|
|
87
87
|
*/
|
|
88
88
|
export async function describeVisiblePlaybook(runtimes, id, visibility) {
|
|
89
89
|
const graph = visibility.graph || buildFallbackGraph(runtimes);
|
package/dist/index.d.ts
CHANGED
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
* 平台大对象驱动与解析器工具移至特定子路径导出(./server, ./project, ./registry,
|
|
6
6
|
* ./profile, ./graph, ./package),严格杜绝在根导出泄露内部执行与平台上下文机制。
|
|
7
7
|
*/
|
|
8
|
-
export { suppressExperimentalWarnings } from "./utils/warning.js";
|
|
9
8
|
export { ACTIONDOCK_VERSION } from "./version.js";
|
|
10
9
|
export { createActionDock, connectActionDock, } from "./service/factory.js";
|
|
11
10
|
export type { ActionDockService, ActionDockService as ActionDock, DiscoveryPort, ExecutionPort, RunsPort, EventsPort, RunEventSubscriptionOptions, ConfigPort, StatePort, CreateActionDockOptions, ConnectActionDockOptions, RemoteServiceOptions, ConfigValueView, ListRunsOptions, RunReadOptions, StateScopeOptions, } from "./service/types.js";
|
|
@@ -23,6 +22,8 @@ export { startActionDockServer, } from "./server/server.js";
|
|
|
23
22
|
export type { ServerOptions, ServerOptions as ActionDockServerOptions, ActionDockServerInstance, } from "./server/types.js";
|
|
24
23
|
export { initProject } from "./project/init.js";
|
|
25
24
|
export { loadProjectConfig, findProjectRoot, } from "./project/loader.js";
|
|
26
|
-
export
|
|
25
|
+
export { discoverLocalSkillDirectory, inspectLocalPackageDirectory, queryLocalPackageDirectory, validateLocalSkillPackages, isExplicitPath, } from "./project/skill-dir.js";
|
|
26
|
+
export type { ProjectConfig, PlaybookSourceManifest, RuntimeProjectConfig, } from "./project/types.js";
|
|
27
|
+
export type { LocalSkillDirectory, LocalPackageEntry, } from "./project/skill-dir.js";
|
|
27
28
|
export type { PackageGraph, } from "./catalog/graph.js";
|
|
28
29
|
export { ActionDockError, ProcessError, PACKAGE_NOT_FOUND, ACTION_PACKAGE_VERSION_CONFLICT, ACTION_NOT_FOUND, ACTION_LOAD_FAILED, ACTION_FAILED, ACTION_TIMEOUT, ACTION_CANCELLED, INPUT_VALIDATION_FAILED, OUTPUT_VALIDATION_FAILED, INPUT_NOT_JSON, OUTPUT_NOT_JSON, ACTION_SUBRUN_LIMIT, ACTION_CALL_CYCLE, UNDECLARED_ACTION_DEPENDENCY, INVALID_ACTION_REF, IDEMPOTENCY_CONFLICT, EXECUTION_FAILED, UNHANDLED_EXECUTION_ERROR, RUN_REPOSITORY_UNAVAILABLE, RUN_PERSISTENCE_FAILED, STANDALONE_ASYNC_UNSUPPORTED, HOST_PROCESS_EXITED, EXECUTION_ABORTED, TIMEOUT, NETWORK_ERROR, CAPABILITY_UNAVAILABLE, STATE_KEY_NOT_FOUND, STORAGE_BUSY, PROJECT_BUSY, PROJECT_RECOVERY_REQUIRED, EVENT_BACKPRESSURE_LIMIT, EVENT_CURSOR_EXPIRED, PROCESS_OUTPUT_LIMIT, PROCESS_SPAWN_ERROR, PROCESS_CANCELLED, PROCESS_TIMEOUT, UNAUTHORIZED, NOT_FOUND, SERVER_ERROR, PACKAGE_FORBIDDEN, ACTION_FORBIDDEN, PLAYBOOK_NOT_FOUND, REQUEST_TOO_LARGE, ACTION_START_FAILED, ACTION_EXECUTION_ERROR, DATA_DIR_IN_USE, DATA_DIR_RECOVERY_REQUIRED, PROCESS_FAILED, MCP_TOOL_NAME_COLLISION, ACCESS_DENIED, INVALID_FLAT_ARGUMENT, INVALID_JSON, INVALID_JSON_LITERAL, INPUT_PATH_CONFLICT, FLAT_INPUT_LIMIT_EXCEEDED, INPUT_LIMIT_EXCEEDED, INPUT_POLICY_VIOLATION, INPUT_CONFLICT, INPUT_FILE_NOT_FOUND, INPUT_FILE_READ_FAILED, INVALID_ARGUMENT, PACKAGE_NOT_ALLOWED, INVALID_PACKAGE_ID, PATH_TRAVERSAL, AMBIGUOUS_STATE_KEY, RUN_NOT_FOUND, RUN_ALREADY_FINISHED, PROJECT_ROOT_NOT_FOUND, describeActionLoadFailure, createErrorEnvelope, resolveExecutionHint, } from "./errors.js";
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
* 平台大对象驱动与解析器工具移至特定子路径导出(./server, ./project, ./registry,
|
|
6
6
|
* ./profile, ./graph, ./package),严格杜绝在根导出泄露内部执行与平台上下文机制。
|
|
7
7
|
*/
|
|
8
|
-
export { suppressExperimentalWarnings } from "./utils/warning.js";
|
|
9
8
|
// 1. 核心版本号单一事实源
|
|
10
9
|
export { ACTIONDOCK_VERSION } from "./version.js";
|
|
11
10
|
// 2. 统一服务门面与聚合契约接口
|
|
@@ -20,5 +19,6 @@ export { startActionDockServer, } from "./server/server.js";
|
|
|
20
19
|
// 6. 核心工程辅助
|
|
21
20
|
export { initProject } from "./project/init.js";
|
|
22
21
|
export { loadProjectConfig, findProjectRoot, } from "./project/loader.js";
|
|
22
|
+
export { discoverLocalSkillDirectory, inspectLocalPackageDirectory, queryLocalPackageDirectory, validateLocalSkillPackages, isExplicitPath, } from "./project/skill-dir.js";
|
|
23
23
|
// 8. 统一错误模型与核心标准错误码常量
|
|
24
24
|
export { ActionDockError, ProcessError, PACKAGE_NOT_FOUND, ACTION_PACKAGE_VERSION_CONFLICT, ACTION_NOT_FOUND, ACTION_LOAD_FAILED, ACTION_FAILED, ACTION_TIMEOUT, ACTION_CANCELLED, INPUT_VALIDATION_FAILED, OUTPUT_VALIDATION_FAILED, INPUT_NOT_JSON, OUTPUT_NOT_JSON, ACTION_SUBRUN_LIMIT, ACTION_CALL_CYCLE, UNDECLARED_ACTION_DEPENDENCY, INVALID_ACTION_REF, IDEMPOTENCY_CONFLICT, EXECUTION_FAILED, UNHANDLED_EXECUTION_ERROR, RUN_REPOSITORY_UNAVAILABLE, RUN_PERSISTENCE_FAILED, STANDALONE_ASYNC_UNSUPPORTED, HOST_PROCESS_EXITED, EXECUTION_ABORTED, TIMEOUT, NETWORK_ERROR, CAPABILITY_UNAVAILABLE, STATE_KEY_NOT_FOUND, STORAGE_BUSY, PROJECT_BUSY, PROJECT_RECOVERY_REQUIRED, EVENT_BACKPRESSURE_LIMIT, EVENT_CURSOR_EXPIRED, PROCESS_OUTPUT_LIMIT, PROCESS_SPAWN_ERROR, PROCESS_CANCELLED, PROCESS_TIMEOUT, UNAUTHORIZED, NOT_FOUND, SERVER_ERROR, PACKAGE_FORBIDDEN, ACTION_FORBIDDEN, PLAYBOOK_NOT_FOUND, REQUEST_TOO_LARGE, ACTION_START_FAILED, ACTION_EXECUTION_ERROR, DATA_DIR_IN_USE, DATA_DIR_RECOVERY_REQUIRED, PROCESS_FAILED, MCP_TOOL_NAME_COLLISION, ACCESS_DENIED, INVALID_FLAT_ARGUMENT, INVALID_JSON, INVALID_JSON_LITERAL, INPUT_PATH_CONFLICT, FLAT_INPUT_LIMIT_EXCEEDED, INPUT_LIMIT_EXCEEDED, INPUT_POLICY_VIOLATION, INPUT_CONFLICT, INPUT_FILE_NOT_FOUND, INPUT_FILE_READ_FAILED, INVALID_ARGUMENT, PACKAGE_NOT_ALLOWED, INVALID_PACKAGE_ID, PATH_TRAVERSAL, AMBIGUOUS_STATE_KEY, RUN_NOT_FOUND, RUN_ALREADY_FINISHED, PROJECT_ROOT_NOT_FOUND, describeActionLoadFailure, createErrorEnvelope, resolveExecutionHint, } from "./errors.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ExecutionEvent, ExecutionResult, JsonValue, RunRecord } from "@actiondock/sdk";
|
|
2
2
|
import type { ActionInvoker, CancelResult, ExecutionTicket } from "../execution/types.js";
|
|
3
|
-
import type { ProjectConfig } from "../project/types.js";
|
|
3
|
+
import type { ProjectConfig, RuntimeProjectConfig } from "../project/types.js";
|
|
4
4
|
import { type PackageIdentity } from "../runtime/identity.js";
|
|
5
5
|
import { type InvocationContext, type RunOptions } from "../invocation/types.js";
|
|
6
6
|
import type { ActionSpec, ActionSummary, ConfigValueView, HostManagedPackageRuntime, ListActionsOptions, ListRunsOptions, PackageInfo, PackageRuntime, PackageRuntimeOptions, PackageRuntimeInternalOptions, PlaybookSpec, PlaybookSummary, StateScopeOptions } from "./types.js";
|
|
@@ -21,7 +21,7 @@ export declare class DefaultPackageRuntime implements HostManagedPackageRuntime
|
|
|
21
21
|
readonly packageInstanceId: string;
|
|
22
22
|
readonly generationId: string;
|
|
23
23
|
readonly packageRoot?: string;
|
|
24
|
-
readonly projectConfig: ProjectConfig;
|
|
24
|
+
readonly projectConfig: ProjectConfig | RuntimeProjectConfig;
|
|
25
25
|
readonly inMemory: boolean;
|
|
26
26
|
private readonly platform;
|
|
27
27
|
private readonly actionsMap;
|
package/dist/package/runtime.js
CHANGED
|
@@ -2,7 +2,7 @@ import { existsSync } from "node:fs";
|
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { DefaultExecutionService } from "../execution/service.js";
|
|
4
4
|
import { createNodePlatform } from "../platform/index.js";
|
|
5
|
-
import { findProjectRoot, loadProjectConfig } from "../project/loader.js";
|
|
5
|
+
import { completeRuntimeProjectConfig, findProjectRoot, loadProjectConfig } from "../project/loader.js";
|
|
6
6
|
import { RuntimeConfig } from "../runtime/context.js";
|
|
7
7
|
import { normalizeActionCollection } from "../runtime/action-collection.js";
|
|
8
8
|
import { isSecretConfigKey, sanitizeConfigDefinitions } from "../storage/mask.js";
|
|
@@ -125,6 +125,8 @@ export class DefaultPackageRuntime {
|
|
|
125
125
|
version: "0.1.0",
|
|
126
126
|
};
|
|
127
127
|
}
|
|
128
|
+
// 在唯一装配边界确定规程来源,索引与包图共享同一份完整配置快照。
|
|
129
|
+
projectConfig = completeRuntimeProjectConfig(packageRoot, projectConfig);
|
|
128
130
|
this.packageRoot = packageRoot;
|
|
129
131
|
this.projectConfig = projectConfig;
|
|
130
132
|
// 兼容未在公开选项契约中显式声明的包实例标识与代系标识内部参数透传
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ActionDefinition } from "@actiondock/sdk";
|
|
2
|
-
import type { ProjectConfig } from "../project/types.js";
|
|
2
|
+
import type { ProjectConfig, RuntimeProjectConfig } from "../project/types.js";
|
|
3
3
|
import type { ActionSpec, PlaybookSpec } from "./types.js";
|
|
4
4
|
/**
|
|
5
5
|
* 静态清单索引构建入参:同一包的全部静态事实来源。
|
|
@@ -10,8 +10,8 @@ export interface StaticIndexInput {
|
|
|
10
10
|
packageRoot?: string;
|
|
11
11
|
/** 包唯一标识 */
|
|
12
12
|
packageId: string;
|
|
13
|
-
/**
|
|
14
|
-
projectConfig: ProjectConfig;
|
|
13
|
+
/** 项目配置(规范化清单配置快照或运行时来源,单一事实源) */
|
|
14
|
+
projectConfig: ProjectConfig | RuntimeProjectConfig;
|
|
15
15
|
}
|
|
16
16
|
/** Action 索引构建入参:静态事实来源之上叠加内存注入的 Action 定义集合 */
|
|
17
17
|
export interface StaticActionIndexInput extends StaticIndexInput {
|
|
@@ -29,8 +29,6 @@ export interface StaticActionIndexInput extends StaticIndexInput {
|
|
|
29
29
|
export declare function buildStaticActionMap(input: StaticActionIndexInput): Map<string, ActionSpec>;
|
|
30
30
|
/**
|
|
31
31
|
* 静态读取并聚合指定包的 Playbook 规范索引。
|
|
32
|
-
*
|
|
33
|
-
* 聚合来源:磁盘规程目录扫描(以 actiondock.json 声明为事实源)与
|
|
34
|
-
* 项目配置中声明的 playbooks;同键时配置声明覆盖磁盘扫描结果。
|
|
32
|
+
* 统一复用 project/loader 的 loadPlaybooks(单一事实源),不再自行读文件或吞异常。
|
|
35
33
|
*/
|
|
36
34
|
export declare function buildStaticPlaybookMap(input: StaticIndexInput): Map<string, PlaybookSpec>;
|