@actiondock/core 2.0.11 → 2.2.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.
Files changed (258) hide show
  1. package/README.md +61 -30
  2. package/dist/app/app.d.ts +73 -0
  3. package/dist/app/app.js +700 -0
  4. package/dist/app/index.d.ts +2 -0
  5. package/dist/app/index.js +2 -0
  6. package/dist/app/types.d.ts +283 -0
  7. package/dist/app/types.js +1 -0
  8. package/dist/catalog/action-index.d.ts +9 -0
  9. package/dist/catalog/action-index.js +93 -0
  10. package/dist/catalog/action-resolver.d.ts +20 -0
  11. package/dist/catalog/action-resolver.js +95 -0
  12. package/dist/catalog/index.d.ts +5 -0
  13. package/dist/catalog/index.js +5 -0
  14. package/dist/catalog/location-registry.d.ts +15 -0
  15. package/dist/catalog/location-registry.js +138 -0
  16. package/dist/catalog/package-catalog.d.ts +7 -0
  17. package/dist/catalog/package-catalog.js +76 -0
  18. package/dist/catalog/types.d.ts +68 -0
  19. package/dist/catalog/types.js +1 -0
  20. package/dist/doctor/doctor.d.ts +7 -0
  21. package/dist/doctor/doctor.js +613 -0
  22. package/dist/doctor/index.d.ts +2 -0
  23. package/dist/doctor/index.js +2 -0
  24. package/dist/doctor/types.d.ts +23 -0
  25. package/dist/doctor/types.js +1 -0
  26. package/dist/errors.d.ts +122 -0
  27. package/dist/errors.js +123 -0
  28. package/dist/execution/index.d.ts +2 -0
  29. package/dist/execution/index.js +2 -0
  30. package/dist/execution/service.d.ts +79 -0
  31. package/dist/execution/service.js +633 -0
  32. package/dist/execution/types.d.ts +131 -0
  33. package/dist/execution/types.js +1 -0
  34. package/dist/export/index.d.ts +1 -0
  35. package/dist/export/index.js +1 -0
  36. package/dist/export/templates.d.ts +71 -0
  37. package/dist/export/templates.js +621 -0
  38. package/dist/filter/index.d.ts +1 -0
  39. package/dist/filter/index.js +1 -0
  40. package/dist/filter/intent.d.ts +33 -0
  41. package/dist/filter/intent.js +123 -0
  42. package/dist/host/host.d.ts +55 -0
  43. package/dist/host/host.js +740 -0
  44. package/dist/host/index.d.ts +2 -0
  45. package/dist/host/index.js +2 -0
  46. package/dist/host/types.d.ts +81 -0
  47. package/dist/host/types.js +1 -0
  48. package/dist/index.d.ts +21 -0
  49. package/dist/index.js +20 -0
  50. package/dist/ipc/diagnostic.d.ts +65 -0
  51. package/dist/ipc/diagnostic.js +129 -0
  52. package/dist/ipc/host.d.ts +7 -0
  53. package/dist/ipc/host.js +93 -0
  54. package/dist/ipc/index.d.ts +4 -0
  55. package/dist/ipc/index.js +4 -0
  56. package/dist/ipc/target.d.ts +56 -0
  57. package/dist/ipc/target.js +297 -0
  58. package/dist/ipc/types.d.ts +42 -0
  59. package/dist/ipc/types.js +1 -0
  60. package/dist/platform/default.d.ts +32 -0
  61. package/dist/platform/default.js +40 -0
  62. package/dist/platform/index.d.ts +3 -0
  63. package/dist/platform/index.js +3 -0
  64. package/dist/platform/node-fs.d.ts +37 -0
  65. package/dist/platform/node-fs.js +81 -0
  66. package/dist/platform/types.d.ts +104 -0
  67. package/dist/platform/types.js +1 -0
  68. package/dist/profile/client.d.ts +162 -0
  69. package/dist/profile/client.js +467 -0
  70. package/dist/profile/index.d.ts +3 -0
  71. package/dist/profile/index.js +3 -0
  72. package/dist/profile/manager.d.ts +47 -0
  73. package/dist/profile/manager.js +294 -0
  74. package/dist/profile/types.d.ts +61 -0
  75. package/dist/profile/types.js +1 -0
  76. package/dist/project/closure.d.ts +25 -0
  77. package/dist/project/closure.js +68 -0
  78. package/dist/project/digest.d.ts +29 -0
  79. package/dist/project/digest.js +324 -0
  80. package/dist/project/index.d.ts +10 -0
  81. package/dist/project/index.js +10 -0
  82. package/dist/project/init.d.ts +26 -0
  83. package/dist/project/init.js +175 -0
  84. package/dist/project/loader.d.ts +99 -0
  85. package/dist/project/loader.js +484 -0
  86. package/dist/project/lockfile.d.ts +55 -0
  87. package/dist/project/lockfile.js +175 -0
  88. package/dist/project/manifest.d.ts +22 -0
  89. package/dist/project/manifest.js +220 -0
  90. package/dist/project/resolver.d.ts +116 -0
  91. package/dist/project/resolver.js +376 -0
  92. package/dist/project/transactions.d.ts +103 -0
  93. package/dist/project/transactions.js +1203 -0
  94. package/dist/project/types-generator.d.ts +33 -0
  95. package/dist/project/types-generator.js +168 -0
  96. package/dist/project/types.d.ts +107 -0
  97. package/dist/project/types.js +1 -0
  98. package/dist/registry/index.d.ts +5 -0
  99. package/dist/registry/index.js +5 -0
  100. package/dist/registry/lock.d.ts +27 -0
  101. package/dist/registry/lock.js +93 -0
  102. package/dist/registry/registry.d.ts +45 -0
  103. package/dist/registry/registry.js +611 -0
  104. package/dist/registry/resolve.d.ts +62 -0
  105. package/dist/registry/resolve.js +195 -0
  106. package/dist/registry/scan.d.ts +38 -0
  107. package/dist/registry/scan.js +135 -0
  108. package/dist/registry/types.d.ts +117 -0
  109. package/dist/registry/types.js +1 -0
  110. package/dist/runtime/action-collection.d.ts +27 -0
  111. package/dist/runtime/action-collection.js +57 -0
  112. package/dist/runtime/clock.d.ts +19 -0
  113. package/dist/runtime/clock.js +17 -0
  114. package/dist/runtime/context.d.ts +86 -0
  115. package/dist/runtime/context.js +242 -0
  116. package/dist/runtime/env.d.ts +56 -0
  117. package/dist/runtime/env.js +159 -0
  118. package/dist/runtime/events.d.ts +93 -0
  119. package/dist/runtime/events.js +604 -0
  120. package/dist/runtime/execution-manager.d.ts +48 -0
  121. package/dist/runtime/execution-manager.js +66 -0
  122. package/dist/runtime/index.d.ts +10 -0
  123. package/dist/runtime/index.js +10 -0
  124. package/dist/runtime/module-loader.d.ts +34 -0
  125. package/dist/runtime/module-loader.js +16 -0
  126. package/dist/runtime/process.d.ts +9 -0
  127. package/dist/runtime/process.js +146 -0
  128. package/dist/runtime/runner.d.ts +293 -0
  129. package/dist/runtime/runner.js +984 -0
  130. package/dist/runtime/standalone.d.ts +89 -0
  131. package/dist/runtime/standalone.js +536 -0
  132. package/dist/schema/validator.d.ts +28 -0
  133. package/dist/schema/validator.js +116 -0
  134. package/dist/server/body.d.ts +40 -0
  135. package/dist/server/body.js +93 -0
  136. package/dist/server/index.d.ts +5 -0
  137. package/dist/server/index.js +5 -0
  138. package/dist/server/routes/actions.d.ts +5 -0
  139. package/dist/server/routes/actions.js +298 -0
  140. package/dist/server/routes/common.d.ts +47 -0
  141. package/dist/server/routes/common.js +104 -0
  142. package/dist/server/routes/config.d.ts +6 -0
  143. package/dist/server/routes/config.js +173 -0
  144. package/dist/server/routes/doctor.d.ts +5 -0
  145. package/dist/server/routes/doctor.js +63 -0
  146. package/dist/server/routes/health.d.ts +5 -0
  147. package/dist/server/routes/health.js +35 -0
  148. package/dist/server/routes/index.d.ts +9 -0
  149. package/dist/server/routes/index.js +9 -0
  150. package/dist/server/routes/info.d.ts +7 -0
  151. package/dist/server/routes/info.js +158 -0
  152. package/dist/server/routes/playbooks.d.ts +5 -0
  153. package/dist/server/routes/playbooks.js +134 -0
  154. package/dist/server/routes/runs.d.ts +5 -0
  155. package/dist/server/routes/runs.js +343 -0
  156. package/dist/server/routes/state.d.ts +6 -0
  157. package/dist/server/routes/state.js +169 -0
  158. package/dist/server/security.d.ts +44 -0
  159. package/dist/server/security.js +101 -0
  160. package/dist/server/server.d.ts +15 -0
  161. package/dist/server/server.js +355 -0
  162. package/dist/server/types.d.ts +78 -0
  163. package/dist/server/types.js +1 -0
  164. package/dist/storage/data-dir-lock.d.ts +119 -0
  165. package/dist/storage/data-dir-lock.js +1016 -0
  166. package/dist/storage/driver.d.ts +9 -0
  167. package/dist/storage/driver.js +59 -0
  168. package/dist/storage/index.d.ts +64 -0
  169. package/dist/storage/index.js +98 -0
  170. package/dist/storage/lazy.d.ts +8 -0
  171. package/dist/storage/lazy.js +44 -0
  172. package/dist/storage/mask.d.ts +26 -0
  173. package/dist/storage/mask.js +48 -0
  174. package/dist/storage/params.d.ts +13 -0
  175. package/dist/storage/params.js +32 -0
  176. package/dist/storage/sqlite.d.ts +79 -0
  177. package/dist/storage/sqlite.js +689 -0
  178. package/dist/storage/types.d.ts +172 -0
  179. package/dist/storage/types.js +14 -0
  180. package/dist/target/index.d.ts +4 -0
  181. package/dist/target/index.js +4 -0
  182. package/dist/target/local.d.ts +52 -0
  183. package/dist/target/local.js +343 -0
  184. package/dist/target/remote.d.ts +76 -0
  185. package/dist/target/remote.js +839 -0
  186. package/dist/target/target.d.ts +6 -0
  187. package/dist/target/target.js +35 -0
  188. package/dist/target/types.d.ts +246 -0
  189. package/dist/target/types.js +34 -0
  190. package/dist/utils/index.d.ts +49 -0
  191. package/dist/utils/index.js +180 -0
  192. package/dist/version.d.ts +4 -0
  193. package/dist/version.js +4 -0
  194. package/package.json +13 -13
  195. package/src/build/index.ts +0 -1
  196. package/src/build/templates.ts +0 -59
  197. package/src/catalog/action-index.ts +0 -92
  198. package/src/catalog/action-resolver.ts +0 -120
  199. package/src/catalog/index.ts +0 -5
  200. package/src/catalog/location-registry.ts +0 -134
  201. package/src/catalog/package-catalog.ts +0 -87
  202. package/src/catalog/types.ts +0 -75
  203. package/src/doctor/doctor.ts +0 -419
  204. package/src/doctor/index.ts +0 -2
  205. package/src/doctor/types.ts +0 -25
  206. package/src/execution/index.ts +0 -2
  207. package/src/execution/service.ts +0 -322
  208. package/src/execution/types.ts +0 -73
  209. package/src/export/index.ts +0 -1
  210. package/src/export/templates.ts +0 -590
  211. package/src/filter/index.ts +0 -1
  212. package/src/filter/intent.ts +0 -154
  213. package/src/index.ts +0 -16
  214. package/src/profile/client.ts +0 -552
  215. package/src/profile/index.ts +0 -3
  216. package/src/profile/manager.ts +0 -341
  217. package/src/profile/types.ts +0 -71
  218. package/src/project/index.ts +0 -4
  219. package/src/project/init.ts +0 -242
  220. package/src/project/loader.ts +0 -479
  221. package/src/project/manifest.ts +0 -299
  222. package/src/project/types.ts +0 -141
  223. package/src/registry/index.ts +0 -2
  224. package/src/registry/registry.ts +0 -940
  225. package/src/registry/types.ts +0 -127
  226. package/src/runtime/clock.ts +0 -41
  227. package/src/runtime/context.ts +0 -259
  228. package/src/runtime/env.ts +0 -172
  229. package/src/runtime/events.ts +0 -142
  230. package/src/runtime/execution-manager.ts +0 -74
  231. package/src/runtime/index.ts +0 -10
  232. package/src/runtime/module-loader.ts +0 -67
  233. package/src/runtime/process.ts +0 -245
  234. package/src/runtime/runner.ts +0 -527
  235. package/src/runtime/standalone.ts +0 -429
  236. package/src/schema/validator.ts +0 -61
  237. package/src/server/body.ts +0 -112
  238. package/src/server/index.ts +0 -7
  239. package/src/server/routes/actions.ts +0 -262
  240. package/src/server/routes/common.ts +0 -126
  241. package/src/server/routes/config.ts +0 -147
  242. package/src/server/routes/doctor.ts +0 -29
  243. package/src/server/routes/health.ts +0 -40
  244. package/src/server/routes/index.ts +0 -9
  245. package/src/server/routes/info.ts +0 -221
  246. package/src/server/routes/playbooks.ts +0 -109
  247. package/src/server/routes/runs.ts +0 -301
  248. package/src/server/routes/state.ts +0 -133
  249. package/src/server/runtime-registry.ts +0 -115
  250. package/src/server/security.ts +0 -115
  251. package/src/server/server.ts +0 -251
  252. package/src/server/types.ts +0 -57
  253. package/src/storage/driver.ts +0 -126
  254. package/src/storage/index.ts +0 -81
  255. package/src/storage/mask.ts +0 -34
  256. package/src/storage/sqlite.ts +0 -714
  257. package/src/storage/types.ts +0 -139
  258. package/src/utils/index.ts +0 -62
@@ -0,0 +1,33 @@
1
+ import type { ActionDockManifest } from "./types.js";
2
+ export declare const GENERATED_TYPES_REL_PATH: string;
3
+ export declare const GENERATED_TYPES_OUTDATED_CODE = "GENERATED_TYPES_OUTDATED";
4
+ /**
5
+ * 将 JSON Schema 递归转换为 TypeScript 类型声明字符串。
6
+ */
7
+ export declare function jsonSchemaToTypeScript(schema: any, indent?: number): string;
8
+ /**
9
+ * 根据项目清单 Schema 生成类型声明文件内容,头部注入 RFC 8785 Manifest SHA-256 摘要。
10
+ */
11
+ export declare function generateActionTypes(manifest: ActionDockManifest): {
12
+ code: string;
13
+ digest: string;
14
+ };
15
+ /**
16
+ * 将生成的类型声明写入到项目的 .actiondock/generated/actions.d.ts 文件。
17
+ */
18
+ export declare function writeActionTypes(projectRoot: string, manifest?: ActionDockManifest | null): {
19
+ filePath: string;
20
+ digest: string;
21
+ };
22
+ /**
23
+ * 只读检查项目中的 .actiondock/generated/actions.d.ts 是否过期。
24
+ * 若文件不存在,则认为无需校验通过(返回 exists: false, outdated: false)。
25
+ * 若文件存在但摘要与当前 actiondock.json 不一致,则返回 outdated: true。
26
+ */
27
+ export declare function checkGeneratedTypes(projectRoot: string, manifest?: ActionDockManifest | null): {
28
+ exists: boolean;
29
+ outdated: boolean;
30
+ expectedDigest?: string;
31
+ actualDigest?: string;
32
+ filePath: string;
33
+ };
@@ -0,0 +1,168 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
+ import { dirname, join } from "node:path";
3
+ import { computeManifestDigest } from "./digest.js";
4
+ import { loadManifest } from "./manifest.js";
5
+ export const GENERATED_TYPES_REL_PATH = join(".actiondock", "generated", "actions.d.ts");
6
+ export const GENERATED_TYPES_OUTDATED_CODE = "GENERATED_TYPES_OUTDATED";
7
+ /**
8
+ * 将 JSON Schema 递归转换为 TypeScript 类型声明字符串。
9
+ */
10
+ export function jsonSchemaToTypeScript(schema, indent = 0) {
11
+ if (!schema || typeof schema !== "object" || Object.keys(schema).length === 0) {
12
+ return "unknown";
13
+ }
14
+ if (schema.enum && Array.isArray(schema.enum)) {
15
+ return schema.enum.map((v) => JSON.stringify(v)).join(" | ");
16
+ }
17
+ if (schema.anyOf && Array.isArray(schema.anyOf)) {
18
+ return `(${schema.anyOf.map((s) => jsonSchemaToTypeScript(s, indent)).join(" | ")})`;
19
+ }
20
+ if (schema.oneOf && Array.isArray(schema.oneOf)) {
21
+ return `(${schema.oneOf.map((s) => jsonSchemaToTypeScript(s, indent)).join(" | ")})`;
22
+ }
23
+ if (schema.allOf && Array.isArray(schema.allOf)) {
24
+ return `(${schema.allOf.map((s) => jsonSchemaToTypeScript(s, indent)).join(" & ")})`;
25
+ }
26
+ const type = schema.type;
27
+ if (type === "string")
28
+ return "string";
29
+ if (type === "number" || type === "integer")
30
+ return "number";
31
+ if (type === "boolean")
32
+ return "boolean";
33
+ if (type === "null")
34
+ return "null";
35
+ if (type === "array") {
36
+ const items = schema.items ? jsonSchemaToTypeScript(schema.items, indent) : "unknown";
37
+ return `Array<${items}>`;
38
+ }
39
+ if (type === "object" || schema.properties) {
40
+ const props = schema.properties || {};
41
+ const required = new Set(Array.isArray(schema.required) ? schema.required : []);
42
+ const propKeys = Object.keys(props);
43
+ if (propKeys.length === 0) {
44
+ return "Record<string, unknown>";
45
+ }
46
+ const spaces = " ".repeat(indent + 2);
47
+ const closeSpaces = " ".repeat(indent);
48
+ const lines = propKeys.map((k) => {
49
+ const isReq = required.has(k);
50
+ const safeKey = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(k) ? k : JSON.stringify(k);
51
+ const opt = isReq ? "" : "?";
52
+ const doc = props[k]?.description
53
+ ? `${spaces}/** ${props[k].description.replace(/\*\//g, "* /")} */\n`
54
+ : "";
55
+ return `${doc}${spaces}${safeKey}${opt}: ${jsonSchemaToTypeScript(props[k], indent + 2)};`;
56
+ });
57
+ return `{\n${lines.join("\n")}\n${closeSpaces}}`;
58
+ }
59
+ return "unknown";
60
+ }
61
+ /**
62
+ * 将 Action 标识符转换为合法的 TypeScript 标识符(PascalCase)。
63
+ */
64
+ function toPascalCase(str) {
65
+ return str
66
+ .replace(/[^a-zA-Z0-9]+(.)/g, (_, chr) => chr.toUpperCase())
67
+ .replace(/^[a-z]/, (chr) => chr.toUpperCase())
68
+ .replace(/[^a-zA-Z0-9]/g, "");
69
+ }
70
+ /**
71
+ * 根据项目清单 Schema 生成类型声明文件内容,头部注入 RFC 8785 Manifest SHA-256 摘要。
72
+ */
73
+ export function generateActionTypes(manifest) {
74
+ const digest = computeManifestDigest(manifest);
75
+ const actions = manifest.actions || {};
76
+ const actionEntries = Object.entries(actions);
77
+ const namespaceBlocks = actionEntries.map(([actionId, item]) => {
78
+ const name = toPascalCase(actionId);
79
+ const inType = jsonSchemaToTypeScript(item.inputSchema, 4);
80
+ const outType = jsonSchemaToTypeScript(item.outputSchema, 4);
81
+ const descComment = item.description
82
+ ? ` /**\n * ${item.description.replace(/\*\//g, "* /")}\n */\n`
83
+ : "";
84
+ return ` export namespace ${name} {\n${descComment} export type Input = ${inType};\n export type Output = ${outType};\n }`;
85
+ });
86
+ const mapEntries = actionEntries.map(([actionId]) => {
87
+ const name = toPascalCase(actionId);
88
+ return ` "${actionId}": {\n Input: Actions.${name}.Input;\n Output: Actions.${name}.Output;\n };`;
89
+ });
90
+ const code = `/**
91
+ * AUTO-GENERATED BY ACTIONDOCK. DO NOT EDIT DIRECTLY.
92
+ * @manifest-digest ${digest}
93
+ */
94
+
95
+ import type { ActionContext, ActionDefinition } from "@actiondock/sdk";
96
+
97
+ export namespace Actions {
98
+ ${namespaceBlocks.join("\n\n")}
99
+ }
100
+
101
+ export interface ActionSchemaMap {
102
+ ${mapEntries.join("\n")}
103
+ }
104
+
105
+ export type ActionInput<T extends keyof ActionSchemaMap> = ActionSchemaMap[T]["Input"];
106
+ export type ActionOutput<T extends keyof ActionSchemaMap> = ActionSchemaMap[T]["Output"];
107
+
108
+ export type TypedActionDefinition<T extends keyof ActionSchemaMap> = ActionDefinition<
109
+ ActionSchemaMap[T]["Input"],
110
+ ActionSchemaMap[T]["Output"]
111
+ >;
112
+ `;
113
+ return { code, digest };
114
+ }
115
+ /**
116
+ * 将生成的类型声明写入到项目的 .actiondock/generated/actions.d.ts 文件。
117
+ */
118
+ export function writeActionTypes(projectRoot, manifest) {
119
+ const targetManifest = manifest || loadManifest(projectRoot);
120
+ if (!targetManifest) {
121
+ throw new Error(`actiondock.json not found in ${projectRoot}`);
122
+ }
123
+ const { code, digest } = generateActionTypes(targetManifest);
124
+ const fullPath = join(projectRoot, GENERATED_TYPES_REL_PATH);
125
+ const dir = dirname(fullPath);
126
+ if (!existsSync(dir)) {
127
+ mkdirSync(dir, { recursive: true });
128
+ }
129
+ writeFileSync(fullPath, code, "utf-8");
130
+ return { filePath: fullPath, digest };
131
+ }
132
+ /**
133
+ * 只读检查项目中的 .actiondock/generated/actions.d.ts 是否过期。
134
+ * 若文件不存在,则认为无需校验通过(返回 exists: false, outdated: false)。
135
+ * 若文件存在但摘要与当前 actiondock.json 不一致,则返回 outdated: true。
136
+ */
137
+ export function checkGeneratedTypes(projectRoot, manifest) {
138
+ const fullPath = join(projectRoot, GENERATED_TYPES_REL_PATH);
139
+ if (!existsSync(fullPath)) {
140
+ return { exists: false, outdated: false, filePath: fullPath };
141
+ }
142
+ const targetManifest = manifest || loadManifest(projectRoot);
143
+ if (!targetManifest) {
144
+ return { exists: true, outdated: true, filePath: fullPath };
145
+ }
146
+ const expectedDigest = computeManifestDigest(targetManifest);
147
+ try {
148
+ const content = readFileSync(fullPath, "utf-8");
149
+ const match = content.match(/@manifest-digest\s+([^\s*]+)/);
150
+ const actualDigest = match ? match[1] : undefined;
151
+ const outdated = actualDigest !== expectedDigest;
152
+ return {
153
+ exists: true,
154
+ outdated,
155
+ expectedDigest,
156
+ actualDigest,
157
+ filePath: fullPath,
158
+ };
159
+ }
160
+ catch {
161
+ return {
162
+ exists: true,
163
+ outdated: true,
164
+ expectedDigest,
165
+ filePath: fullPath,
166
+ };
167
+ }
168
+ }
@@ -0,0 +1,107 @@
1
+ /**
2
+ * 配置项的值类型枚举。用于自动类型推断与环境变量自动转换。
3
+ */
4
+ export type ConfigValueType = "string" | "number" | "boolean" | "object" | "array";
5
+ /**
6
+ * 在 actiondock.json 中声明的单项配置定义。
7
+ */
8
+ export interface ConfigItemDefinition {
9
+ /** 配置项的功能描述,展示在 CLI 配置提示与帮助文档中 */
10
+ description?: string;
11
+ /** 默认回退值。若未配置任何自定义值或环境变量,将使用此默认值 */
12
+ default?: unknown;
13
+ /** 是否为敏感信息(如 API Key, Password)。若为 true,在日志与 CLI 输出中默认脱敏 */
14
+ secret?: boolean;
15
+ /** 期望的目标数据类型,从 process.env 读取字符串时将自动尝试强转为此类型 */
16
+ type?: ConfigValueType;
17
+ /** 显式绑定的外部环境变量名(支持单个或优先级数组) */
18
+ env?: string | string[];
19
+ /** 是否为必填项 */
20
+ required?: boolean;
21
+ /** 是否允许单次调用覆盖 */
22
+ allowInvocationOverride?: boolean;
23
+ }
24
+ /**
25
+ * 单个 Action 在 actiondock.json 清单中的声明项。
26
+ */
27
+ export interface ActionManifestEntry {
28
+ /** Action 入口文件相对路径(如 "actions/greet.ts") */
29
+ entry: string;
30
+ /** Action 功能描述 */
31
+ description?: string;
32
+ /** 输入参数模式规范 */
33
+ inputSchema?: Record<string, unknown> | boolean;
34
+ /** 输出结果模式规范 */
35
+ outputSchema?: Record<string, unknown> | boolean;
36
+ /** 静态依赖的 Action 列表 */
37
+ uses?: string[];
38
+ /** 标签列表 */
39
+ tags?: string[];
40
+ /** 协议注解元数据 */
41
+ annotations?: Record<string, unknown>;
42
+ }
43
+ /**
44
+ * 单个 Playbook 在 actiondock.json 清单中的声明项。
45
+ */
46
+ export interface PlaybookManifestEntry {
47
+ /** Playbook Markdown 入口文件相对路径(如 "playbooks/greet-user.md") */
48
+ entry: string;
49
+ /** Playbook 任务描述 */
50
+ description?: string;
51
+ /** 该 Playbook 所依赖/调用的 Action ID 列表 */
52
+ actions?: string[];
53
+ }
54
+ /**
55
+ * ActionDock 声明式元数据清单契约(actiondock.json 为唯一事实源)。
56
+ */
57
+ export interface ActionDockManifest {
58
+ /** JSON Schema 声明 URL */
59
+ $schema?: string;
60
+ /** 清单规范版本号(默认 2) */
61
+ schemaVersion?: number;
62
+ /** 项目全局唯一逻辑 ID(例如 "team4u.github-tools") */
63
+ id: string;
64
+ /** 项目展示名称(例如 "GitHub Tools") */
65
+ name?: string;
66
+ /** 项目版本号(如 "1.0.0") */
67
+ version?: string;
68
+ /** 项目描述信息 */
69
+ description?: string;
70
+ /** 声明的项目依赖配置项清单 */
71
+ config?: Record<string, ConfigItemDefinition>;
72
+ /** 声明的 Actions 集合(唯一事实源) */
73
+ actions?: Record<string, ActionManifestEntry>;
74
+ /** 声明的 Playbooks 集合(唯一事实源) */
75
+ playbooks?: Record<string, PlaybookManifestEntry>;
76
+ /** 跨包外部依赖映射(逻辑包 ID 到 npm 包名) */
77
+ dependencies?: Record<string, string>;
78
+ /** 框架导出与分发边界文件列表 */
79
+ files?: string[];
80
+ /** 静态资产列表 */
81
+ assets?: string[];
82
+ /** Action 源码存放目录(向后兼容过渡配置) */
83
+ actionsDir?: string;
84
+ /** Playbook 规程文档存放目录(向后兼容过渡配置) */
85
+ playbooksDir?: string;
86
+ }
87
+ /**
88
+ * ActionDock 项目根配置文件契约(等同于 ActionDockManifest,actiondock.json 为单一事实源)。
89
+ */
90
+ export type ProjectConfig = ActionDockManifest;
91
+ /**
92
+ * 解析后的完整 Playbook 定义对象。
93
+ */
94
+ export interface PlaybookDefinition {
95
+ /** Playbook 唯一标识符(例如 "review-pr") */
96
+ id: string;
97
+ /** Playbook 显示名称 */
98
+ name?: string;
99
+ /** Playbook 任务描述 */
100
+ description?: string;
101
+ /** 该 Playbook 所依赖/调用的 Action ID 列表 */
102
+ actions: string[];
103
+ /** Markdown 正文内容(纯 Markdown 规程内容) */
104
+ content: string;
105
+ /** Playbook 源文件的绝对物理路径 */
106
+ filePath: string;
107
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,5 @@
1
+ export * from "./lock.js";
2
+ export * from "./registry.js";
3
+ export * from "./resolve.js";
4
+ export * from "./scan.js";
5
+ export * from "./types.js";
@@ -0,0 +1,5 @@
1
+ export * from "./lock.js";
2
+ export * from "./registry.js";
3
+ export * from "./resolve.js";
4
+ export * from "./scan.js";
5
+ export * from "./types.js";
@@ -0,0 +1,27 @@
1
+ /**
2
+ * 锁目录创建后超过该时长仍未释放,视为持有进程异常退出的残留锁。
3
+ */
4
+ export declare const REGISTRY_LOCK_STALE_MS = 10000;
5
+ /**
6
+ * 获取锁的最长等待时间,必须大于 REGISTRY_LOCK_STALE_MS,
7
+ * 保证等待方至少有机会观察到残留锁被回收后再判定超时。
8
+ */
9
+ export declare const REGISTRY_LOCK_ACQUIRE_TIMEOUT_MS = 15000;
10
+ /**
11
+ * 两次获取尝试之间的退避间隔,休眠让出事件循环,避免忙等阻塞。
12
+ */
13
+ export declare const REGISTRY_LOCK_RETRY_DELAY_MS = 25;
14
+ /**
15
+ * 异步注册表锁(防止多进程并发读写导致 registry.json 损坏)。
16
+ *
17
+ * 获取方式:fs/promises mkdir 的原子性保证同一时刻仅一个进程能创建锁目录。
18
+ * 冲突处理:EEXIST 时 stat 检查锁目录年龄,超过 stale 阈值则先原子 rename 到
19
+ * 隔离名再删除——rename 仅有一个进程能成功,失败方回到等待重试,消除
20
+ * 「stat 检查后删除再重建」的竞态窗口;未过期的锁通过 sleep 让出事件循环后重试。
21
+ *
22
+ * @param filePath 注册表文件路径,锁目录为其同级 `${filePath}.lock`
23
+ * @param fn 持锁期间执行的操作(同步或异步)
24
+ * @returns fn 的返回值
25
+ * @throws 超过 REGISTRY_LOCK_ACQUIRE_TIMEOUT_MS 仍未获取时抛出描述性错误
26
+ */
27
+ export declare function withRegistryLock<T>(filePath: string, fn: () => T | Promise<T>): Promise<T>;
@@ -0,0 +1,93 @@
1
+ import { mkdir, rename, rm, stat } from "node:fs/promises";
2
+ /**
3
+ * 锁目录创建后超过该时长仍未释放,视为持有进程异常退出的残留锁。
4
+ */
5
+ export const REGISTRY_LOCK_STALE_MS = 10000;
6
+ /**
7
+ * 获取锁的最长等待时间,必须大于 REGISTRY_LOCK_STALE_MS,
8
+ * 保证等待方至少有机会观察到残留锁被回收后再判定超时。
9
+ */
10
+ export const REGISTRY_LOCK_ACQUIRE_TIMEOUT_MS = 15000;
11
+ /**
12
+ * 两次获取尝试之间的退避间隔,休眠让出事件循环,避免忙等阻塞。
13
+ */
14
+ export const REGISTRY_LOCK_RETRY_DELAY_MS = 25;
15
+ function sleep(ms) {
16
+ return new Promise((r) => setTimeout(r, ms));
17
+ }
18
+ /**
19
+ * 异步注册表锁(防止多进程并发读写导致 registry.json 损坏)。
20
+ *
21
+ * 获取方式:fs/promises mkdir 的原子性保证同一时刻仅一个进程能创建锁目录。
22
+ * 冲突处理:EEXIST 时 stat 检查锁目录年龄,超过 stale 阈值则先原子 rename 到
23
+ * 隔离名再删除——rename 仅有一个进程能成功,失败方回到等待重试,消除
24
+ * 「stat 检查后删除再重建」的竞态窗口;未过期的锁通过 sleep 让出事件循环后重试。
25
+ *
26
+ * @param filePath 注册表文件路径,锁目录为其同级 `${filePath}.lock`
27
+ * @param fn 持锁期间执行的操作(同步或异步)
28
+ * @returns fn 的返回值
29
+ * @throws 超过 REGISTRY_LOCK_ACQUIRE_TIMEOUT_MS 仍未获取时抛出描述性错误
30
+ */
31
+ export async function withRegistryLock(filePath, fn) {
32
+ const lockDir = `${filePath}.lock`;
33
+ const deadline = Date.now() + REGISTRY_LOCK_ACQUIRE_TIMEOUT_MS;
34
+ while (true) {
35
+ try {
36
+ // 原子获取:目录创建成功即持有锁,无需二次确认
37
+ await mkdir(lockDir);
38
+ break;
39
+ }
40
+ catch (err) {
41
+ if (err.code !== "EEXIST") {
42
+ throw err;
43
+ }
44
+ }
45
+ // 锁被占用,检查是否为残留的过期锁
46
+ let lockAgeMs;
47
+ try {
48
+ const info = await stat(lockDir);
49
+ lockAgeMs = Date.now() - info.mtimeMs;
50
+ }
51
+ catch (err) {
52
+ if (err.code === "ENOENT") {
53
+ // 持有者恰好在两次探测之间释放,立即重试获取
54
+ continue;
55
+ }
56
+ throw err;
57
+ }
58
+ if (lockAgeMs > REGISTRY_LOCK_STALE_MS) {
59
+ // 原子抢占:rename 到含进程号与时间戳的隔离名,仅一个进程能成功;
60
+ // 失败方说明已被其他等待者抢先处理,回到等待重试即可
61
+ const quarantine = `${lockDir}.stale.${process.pid}.${Date.now()}`;
62
+ try {
63
+ await rename(lockDir, quarantine);
64
+ await rm(quarantine, { recursive: true, force: true });
65
+ continue;
66
+ }
67
+ catch (err) {
68
+ if (err.code === "ENOENT") {
69
+ // 其他等待者已抢先回收该残留锁
70
+ continue;
71
+ }
72
+ // 其他原因的 rename 失败(如瞬时权限问题)不视为致命,退回等待重试
73
+ }
74
+ }
75
+ if (Date.now() > deadline) {
76
+ throw new Error(`Failed to acquire registry lock '${lockDir}' within ${REGISTRY_LOCK_ACQUIRE_TIMEOUT_MS}ms. ` +
77
+ `The lock may be held by another ActionDock process; retry after it exits or remove the stale lock directory manually.`);
78
+ }
79
+ await sleep(REGISTRY_LOCK_RETRY_DELAY_MS);
80
+ }
81
+ try {
82
+ return await fn();
83
+ }
84
+ finally {
85
+ try {
86
+ await rm(lockDir, { recursive: true, force: true });
87
+ }
88
+ catch {
89
+ // 释放失败可忽略:进程未清理的锁目录会随时间超过 stale 阈值,
90
+ // 被后续获取方的原子 rename 抢占回收,不会造成永久死锁
91
+ }
92
+ }
93
+ }
@@ -0,0 +1,45 @@
1
+ import type { GlobalRegistryData, LinkedPackageEntry, LinkedWorkspaceEntry, LinkResult, PruneResult, RegistryStatusReport, ResolvedActionProject, ResolvedPlaybookProject, UnlinkResult } from "./types.js";
2
+ /**
3
+ * 注册表内容解析与 links 迁移(纯函数,同步与异步加载共享的唯一事实源)。
4
+ *
5
+ * @param raw 文件原始文本
6
+ * @param filePath 注册表文件路径(用于错误信息定位)
7
+ * @returns 解析后的注册表数据
8
+ * @throws JSON 非法或顶层非对象时抛出带恢复指引的错误(调用方负责留档原文件)
9
+ */
10
+ export declare function parseRegistryContent(raw: string, filePath: string): GlobalRegistryData;
11
+ export declare function getRegistryFilePath(customHome?: string): string;
12
+ /**
13
+ * 同步加载注册表(保留同步签名供 CLI 与诊断路径使用)。
14
+ *
15
+ * @throws 注册表文件损坏时抛出带恢复指引的错误,绝不静默返回空表,
16
+ * 否则下次 save 会用空数据覆盖原文件导致全部链接记录丢失
17
+ */
18
+ export declare function loadRegistry(customHome?: string): GlobalRegistryData;
19
+ /**
20
+ * 异步加载注册表(损坏语义与同步版一致:留档后抛错,不静默清空)。
21
+ */
22
+ export declare function loadRegistryAsync(customHome?: string): Promise<GlobalRegistryData>;
23
+ /**
24
+ * 原子写入注册表:临时文件写盘后 rename,持锁执行,避免并发撕裂。
25
+ */
26
+ export declare function saveRegistry(data: GlobalRegistryData, customHome?: string): Promise<void>;
27
+ /**
28
+ * 在已持有注册表锁的上下文中直接原子落盘(供复合读改写流程使用,
29
+ * 避免与 saveRegistry 的锁重入死等);调用方必须已持有对应锁。
30
+ */
31
+ export declare function writeRegistryLocked(data: GlobalRegistryData, customHome?: string): Promise<void>;
32
+ export declare function linkPackage(targetPath?: string, customHome?: string, options?: {
33
+ recursive?: boolean;
34
+ }): Promise<LinkResult>;
35
+ export declare function unlinkPackage(identifier?: string, customHome?: string): Promise<UnlinkResult | null>;
36
+ export declare function listLinkedPackages(customHome?: string): LinkedPackageEntry[];
37
+ export declare function listLinkedPackagesAsync(customHome?: string): Promise<LinkedPackageEntry[]>;
38
+ export declare function listLinkedWorkspaces(customHome?: string): LinkedWorkspaceEntry[];
39
+ export declare function resolveActionProjectSync(actionIdentifier: string, cwd?: string, customHome?: string): ResolvedActionProject;
40
+ export declare function resolveActionProject(actionIdentifier: string, cwd?: string, customHome?: string): Promise<ResolvedActionProject>;
41
+ export declare function resolvePlaybookProject(playbookIdentifier: string, cwd?: string, customHome?: string): ResolvedPlaybookProject;
42
+ export declare function resolvePackageRoot(packageIdOrPath?: string, cwd?: string, customHome?: string): string | null;
43
+ export declare function getRegistryStatus(customHome?: string): RegistryStatusReport;
44
+ export declare function pruneRegistry(customHome?: string): Promise<PruneResult>;
45
+ export { discoverProjects, IGNORED_SCAN_DIRS } from "./scan.js";