@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.
- package/README.md +61 -30
- package/dist/app/app.d.ts +73 -0
- package/dist/app/app.js +700 -0
- package/dist/app/index.d.ts +2 -0
- package/dist/app/index.js +2 -0
- package/dist/app/types.d.ts +283 -0
- package/dist/app/types.js +1 -0
- package/dist/catalog/action-index.d.ts +9 -0
- package/dist/catalog/action-index.js +93 -0
- package/dist/catalog/action-resolver.d.ts +20 -0
- package/dist/catalog/action-resolver.js +95 -0
- package/dist/catalog/index.d.ts +5 -0
- package/dist/catalog/index.js +5 -0
- package/dist/catalog/location-registry.d.ts +15 -0
- package/dist/catalog/location-registry.js +138 -0
- package/dist/catalog/package-catalog.d.ts +7 -0
- package/dist/catalog/package-catalog.js +76 -0
- package/dist/catalog/types.d.ts +68 -0
- package/dist/catalog/types.js +1 -0
- package/dist/doctor/doctor.d.ts +7 -0
- package/dist/doctor/doctor.js +613 -0
- package/dist/doctor/index.d.ts +2 -0
- package/dist/doctor/index.js +2 -0
- package/dist/doctor/types.d.ts +23 -0
- package/dist/doctor/types.js +1 -0
- package/dist/errors.d.ts +122 -0
- package/dist/errors.js +123 -0
- package/dist/execution/index.d.ts +2 -0
- package/dist/execution/index.js +2 -0
- package/dist/execution/service.d.ts +79 -0
- package/dist/execution/service.js +633 -0
- package/dist/execution/types.d.ts +131 -0
- package/dist/execution/types.js +1 -0
- package/dist/export/index.d.ts +1 -0
- package/dist/export/index.js +1 -0
- package/dist/export/templates.d.ts +71 -0
- package/dist/export/templates.js +621 -0
- package/dist/filter/index.d.ts +1 -0
- package/dist/filter/index.js +1 -0
- package/dist/filter/intent.d.ts +33 -0
- package/dist/filter/intent.js +123 -0
- package/dist/host/host.d.ts +55 -0
- package/dist/host/host.js +740 -0
- package/dist/host/index.d.ts +2 -0
- package/dist/host/index.js +2 -0
- package/dist/host/types.d.ts +81 -0
- package/dist/host/types.js +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.js +20 -0
- package/dist/ipc/diagnostic.d.ts +65 -0
- package/dist/ipc/diagnostic.js +129 -0
- package/dist/ipc/host.d.ts +7 -0
- package/dist/ipc/host.js +93 -0
- package/dist/ipc/index.d.ts +4 -0
- package/dist/ipc/index.js +4 -0
- package/dist/ipc/target.d.ts +56 -0
- package/dist/ipc/target.js +297 -0
- package/dist/ipc/types.d.ts +42 -0
- package/dist/ipc/types.js +1 -0
- package/dist/platform/default.d.ts +32 -0
- package/dist/platform/default.js +40 -0
- package/dist/platform/index.d.ts +3 -0
- package/dist/platform/index.js +3 -0
- package/dist/platform/node-fs.d.ts +37 -0
- package/dist/platform/node-fs.js +81 -0
- package/dist/platform/types.d.ts +104 -0
- package/dist/platform/types.js +1 -0
- package/dist/profile/client.d.ts +162 -0
- package/dist/profile/client.js +467 -0
- package/dist/profile/index.d.ts +3 -0
- package/dist/profile/index.js +3 -0
- package/dist/profile/manager.d.ts +47 -0
- package/dist/profile/manager.js +294 -0
- package/dist/profile/types.d.ts +61 -0
- package/dist/profile/types.js +1 -0
- package/dist/project/closure.d.ts +25 -0
- package/dist/project/closure.js +68 -0
- package/dist/project/digest.d.ts +29 -0
- package/dist/project/digest.js +324 -0
- package/dist/project/index.d.ts +10 -0
- package/dist/project/index.js +10 -0
- package/dist/project/init.d.ts +26 -0
- package/dist/project/init.js +175 -0
- package/dist/project/loader.d.ts +99 -0
- package/dist/project/loader.js +484 -0
- package/dist/project/lockfile.d.ts +55 -0
- package/dist/project/lockfile.js +175 -0
- package/dist/project/manifest.d.ts +22 -0
- package/dist/project/manifest.js +220 -0
- package/dist/project/resolver.d.ts +116 -0
- package/dist/project/resolver.js +376 -0
- package/dist/project/transactions.d.ts +103 -0
- package/dist/project/transactions.js +1203 -0
- package/dist/project/types-generator.d.ts +33 -0
- package/dist/project/types-generator.js +168 -0
- package/dist/project/types.d.ts +107 -0
- package/dist/project/types.js +1 -0
- package/dist/registry/index.d.ts +5 -0
- package/dist/registry/index.js +5 -0
- package/dist/registry/lock.d.ts +27 -0
- package/dist/registry/lock.js +93 -0
- package/dist/registry/registry.d.ts +45 -0
- package/dist/registry/registry.js +611 -0
- package/dist/registry/resolve.d.ts +62 -0
- package/dist/registry/resolve.js +195 -0
- package/dist/registry/scan.d.ts +38 -0
- package/dist/registry/scan.js +135 -0
- package/dist/registry/types.d.ts +117 -0
- package/dist/registry/types.js +1 -0
- package/dist/runtime/action-collection.d.ts +27 -0
- package/dist/runtime/action-collection.js +57 -0
- package/dist/runtime/clock.d.ts +19 -0
- package/dist/runtime/clock.js +17 -0
- package/dist/runtime/context.d.ts +86 -0
- package/dist/runtime/context.js +242 -0
- package/dist/runtime/env.d.ts +56 -0
- package/dist/runtime/env.js +159 -0
- package/dist/runtime/events.d.ts +93 -0
- package/dist/runtime/events.js +604 -0
- package/dist/runtime/execution-manager.d.ts +48 -0
- package/dist/runtime/execution-manager.js +66 -0
- package/dist/runtime/index.d.ts +10 -0
- package/dist/runtime/index.js +10 -0
- package/dist/runtime/module-loader.d.ts +34 -0
- package/dist/runtime/module-loader.js +16 -0
- package/dist/runtime/process.d.ts +9 -0
- package/dist/runtime/process.js +146 -0
- package/dist/runtime/runner.d.ts +293 -0
- package/dist/runtime/runner.js +984 -0
- package/dist/runtime/standalone.d.ts +89 -0
- package/dist/runtime/standalone.js +536 -0
- package/dist/schema/validator.d.ts +28 -0
- package/dist/schema/validator.js +116 -0
- package/dist/server/body.d.ts +40 -0
- package/dist/server/body.js +93 -0
- package/dist/server/index.d.ts +5 -0
- package/dist/server/index.js +5 -0
- package/dist/server/routes/actions.d.ts +5 -0
- package/dist/server/routes/actions.js +298 -0
- package/dist/server/routes/common.d.ts +47 -0
- package/dist/server/routes/common.js +104 -0
- package/dist/server/routes/config.d.ts +6 -0
- package/dist/server/routes/config.js +173 -0
- package/dist/server/routes/doctor.d.ts +5 -0
- package/dist/server/routes/doctor.js +63 -0
- package/dist/server/routes/health.d.ts +5 -0
- package/dist/server/routes/health.js +35 -0
- package/dist/server/routes/index.d.ts +9 -0
- package/dist/server/routes/index.js +9 -0
- package/dist/server/routes/info.d.ts +7 -0
- package/dist/server/routes/info.js +158 -0
- package/dist/server/routes/playbooks.d.ts +5 -0
- package/dist/server/routes/playbooks.js +134 -0
- package/dist/server/routes/runs.d.ts +5 -0
- package/dist/server/routes/runs.js +343 -0
- package/dist/server/routes/state.d.ts +6 -0
- package/dist/server/routes/state.js +169 -0
- package/dist/server/security.d.ts +44 -0
- package/dist/server/security.js +101 -0
- package/dist/server/server.d.ts +15 -0
- package/dist/server/server.js +355 -0
- package/dist/server/types.d.ts +78 -0
- package/dist/server/types.js +1 -0
- package/dist/storage/data-dir-lock.d.ts +119 -0
- package/dist/storage/data-dir-lock.js +1016 -0
- package/dist/storage/driver.d.ts +9 -0
- package/dist/storage/driver.js +59 -0
- package/dist/storage/index.d.ts +64 -0
- package/dist/storage/index.js +98 -0
- package/dist/storage/lazy.d.ts +8 -0
- package/dist/storage/lazy.js +44 -0
- package/dist/storage/mask.d.ts +26 -0
- package/dist/storage/mask.js +48 -0
- package/dist/storage/params.d.ts +13 -0
- package/dist/storage/params.js +32 -0
- package/dist/storage/sqlite.d.ts +79 -0
- package/dist/storage/sqlite.js +689 -0
- package/dist/storage/types.d.ts +172 -0
- package/dist/storage/types.js +14 -0
- package/dist/target/index.d.ts +4 -0
- package/dist/target/index.js +4 -0
- package/dist/target/local.d.ts +52 -0
- package/dist/target/local.js +343 -0
- package/dist/target/remote.d.ts +76 -0
- package/dist/target/remote.js +839 -0
- package/dist/target/target.d.ts +6 -0
- package/dist/target/target.js +35 -0
- package/dist/target/types.d.ts +246 -0
- package/dist/target/types.js +34 -0
- package/dist/utils/index.d.ts +49 -0
- package/dist/utils/index.js +180 -0
- package/dist/version.d.ts +4 -0
- package/dist/version.js +4 -0
- package/package.json +13 -13
- package/src/build/index.ts +0 -1
- package/src/build/templates.ts +0 -59
- package/src/catalog/action-index.ts +0 -92
- package/src/catalog/action-resolver.ts +0 -120
- package/src/catalog/index.ts +0 -5
- package/src/catalog/location-registry.ts +0 -134
- package/src/catalog/package-catalog.ts +0 -87
- package/src/catalog/types.ts +0 -75
- package/src/doctor/doctor.ts +0 -419
- package/src/doctor/index.ts +0 -2
- package/src/doctor/types.ts +0 -25
- package/src/execution/index.ts +0 -2
- package/src/execution/service.ts +0 -322
- package/src/execution/types.ts +0 -73
- package/src/export/index.ts +0 -1
- package/src/export/templates.ts +0 -590
- package/src/filter/index.ts +0 -1
- package/src/filter/intent.ts +0 -154
- package/src/index.ts +0 -16
- package/src/profile/client.ts +0 -552
- package/src/profile/index.ts +0 -3
- package/src/profile/manager.ts +0 -341
- package/src/profile/types.ts +0 -71
- package/src/project/index.ts +0 -4
- package/src/project/init.ts +0 -242
- package/src/project/loader.ts +0 -479
- package/src/project/manifest.ts +0 -299
- package/src/project/types.ts +0 -141
- package/src/registry/index.ts +0 -2
- package/src/registry/registry.ts +0 -940
- package/src/registry/types.ts +0 -127
- package/src/runtime/clock.ts +0 -41
- package/src/runtime/context.ts +0 -259
- package/src/runtime/env.ts +0 -172
- package/src/runtime/events.ts +0 -142
- package/src/runtime/execution-manager.ts +0 -74
- package/src/runtime/index.ts +0 -10
- package/src/runtime/module-loader.ts +0 -67
- package/src/runtime/process.ts +0 -245
- package/src/runtime/runner.ts +0 -527
- package/src/runtime/standalone.ts +0 -429
- package/src/schema/validator.ts +0 -61
- package/src/server/body.ts +0 -112
- package/src/server/index.ts +0 -7
- package/src/server/routes/actions.ts +0 -262
- package/src/server/routes/common.ts +0 -126
- package/src/server/routes/config.ts +0 -147
- package/src/server/routes/doctor.ts +0 -29
- package/src/server/routes/health.ts +0 -40
- package/src/server/routes/index.ts +0 -9
- package/src/server/routes/info.ts +0 -221
- package/src/server/routes/playbooks.ts +0 -109
- package/src/server/routes/runs.ts +0 -301
- package/src/server/routes/state.ts +0 -133
- package/src/server/runtime-registry.ts +0 -115
- package/src/server/security.ts +0 -115
- package/src/server/server.ts +0 -251
- package/src/server/types.ts +0 -57
- package/src/storage/driver.ts +0 -126
- package/src/storage/index.ts +0 -81
- package/src/storage/mask.ts +0 -34
- package/src/storage/sqlite.ts +0 -714
- package/src/storage/types.ts +0 -139
- package/src/utils/index.ts +0 -62
package/src/filter/intent.ts
DELETED
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 从对象中提取待过滤字段的提取器函数类型。
|
|
3
|
-
*/
|
|
4
|
-
export type Extractor<T> = (item: T) => unknown;
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* 安全地将模式字符串、数组或现有正则编译为不区分大小写的 RegExp 正则表达式。
|
|
8
|
-
* 若正则语法不合法,自动对特殊字符进行转义并降级为字面量匹配正则,保证零 Crash。
|
|
9
|
-
*
|
|
10
|
-
* @param intent 意图关键词、正则或数组
|
|
11
|
-
*/
|
|
12
|
-
export function compileIntentRegex(
|
|
13
|
-
intent?: string | string[] | RegExp | null
|
|
14
|
-
): RegExp | null {
|
|
15
|
-
if (!intent) return null;
|
|
16
|
-
if (intent instanceof RegExp) return intent;
|
|
17
|
-
|
|
18
|
-
let patternStr: string;
|
|
19
|
-
if (Array.isArray(intent)) {
|
|
20
|
-
const valid = intent.map((s) => s.trim()).filter(Boolean);
|
|
21
|
-
if (valid.length === 0) return null;
|
|
22
|
-
patternStr = valid.join("|");
|
|
23
|
-
} else {
|
|
24
|
-
patternStr = intent.trim();
|
|
25
|
-
if (!patternStr) return null;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
try {
|
|
29
|
-
return new RegExp(patternStr, "i");
|
|
30
|
-
} catch {
|
|
31
|
-
const escaped = patternStr.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
32
|
-
return new RegExp(escaped, "i");
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* 递归检查某个值(包括嵌套的数组或对象结构)是否匹配给定的正则表达式。
|
|
38
|
-
*
|
|
39
|
-
* @param value 待检测的任意数据类型
|
|
40
|
-
* @param regex 正则表达式
|
|
41
|
-
*/
|
|
42
|
-
export function matchIntent(value: unknown, regex: RegExp): boolean {
|
|
43
|
-
if (value === undefined || value === null) return false;
|
|
44
|
-
|
|
45
|
-
if (typeof value === "string") {
|
|
46
|
-
return regex.test(value);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
if (typeof value === "number" || typeof value === "boolean") {
|
|
50
|
-
return regex.test(String(value));
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
if (Array.isArray(value)) {
|
|
54
|
-
for (const elem of value) {
|
|
55
|
-
if (matchIntent(elem, regex)) return true;
|
|
56
|
-
}
|
|
57
|
-
return false;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
if (typeof value === "object") {
|
|
61
|
-
try {
|
|
62
|
-
return regex.test(JSON.stringify(value));
|
|
63
|
-
} catch {
|
|
64
|
-
return false;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
return false;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
export interface FilterResult<T> {
|
|
72
|
-
items: T[];
|
|
73
|
-
isFallback: boolean;
|
|
74
|
-
matchedCount: number;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Filters a collection of items based on an intent pattern across specified extractor functions.
|
|
79
|
-
* Returns detailed result including whether a fallback was triggered when 0 items matched.
|
|
80
|
-
*/
|
|
81
|
-
export function filterWithFallbackInfo<T>(
|
|
82
|
-
items: T[],
|
|
83
|
-
intent?: string | string[] | RegExp | null,
|
|
84
|
-
extractors?: Extractor<T>[],
|
|
85
|
-
fallback = true
|
|
86
|
-
): FilterResult<T> {
|
|
87
|
-
if (!intent) {
|
|
88
|
-
return {
|
|
89
|
-
items,
|
|
90
|
-
isFallback: false,
|
|
91
|
-
matchedCount: items.length,
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
const regex = compileIntentRegex(intent);
|
|
96
|
-
if (!regex) {
|
|
97
|
-
return {
|
|
98
|
-
items,
|
|
99
|
-
isFallback: false,
|
|
100
|
-
matchedCount: items.length,
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
const defaultExtractors: Extractor<T>[] = [
|
|
105
|
-
(item: any) =>
|
|
106
|
-
typeof item === "string"
|
|
107
|
-
? item
|
|
108
|
-
: item?.id || item?.name || item?.key || String(item),
|
|
109
|
-
];
|
|
110
|
-
|
|
111
|
-
const effectiveExtractors =
|
|
112
|
-
extractors && extractors.length > 0 ? extractors : defaultExtractors;
|
|
113
|
-
|
|
114
|
-
const matched = items.filter((item) => {
|
|
115
|
-
for (const extractor of effectiveExtractors) {
|
|
116
|
-
try {
|
|
117
|
-
const val = extractor(item);
|
|
118
|
-
if (matchIntent(val, regex)) {
|
|
119
|
-
return true;
|
|
120
|
-
}
|
|
121
|
-
} catch {
|
|
122
|
-
// Ignore extraction error
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
return false;
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
if (matched.length === 0 && fallback) {
|
|
129
|
-
return {
|
|
130
|
-
items,
|
|
131
|
-
isFallback: true,
|
|
132
|
-
matchedCount: 0,
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
return {
|
|
137
|
-
items: matched,
|
|
138
|
-
isFallback: false,
|
|
139
|
-
matchedCount: matched.length,
|
|
140
|
-
};
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* Filters a collection of items based on an intent pattern across specified extractor functions.
|
|
145
|
-
* When fallback is enabled (default), returns the full list if no items match the intent.
|
|
146
|
-
*/
|
|
147
|
-
export function filterByIntent<T>(
|
|
148
|
-
items: T[],
|
|
149
|
-
intent?: string | string[] | RegExp | null,
|
|
150
|
-
extractors?: Extractor<T>[],
|
|
151
|
-
fallback = true
|
|
152
|
-
): T[] {
|
|
153
|
-
return filterWithFallbackInfo(items, intent, extractors, fallback).items;
|
|
154
|
-
}
|
package/src/index.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
export * from "./build";
|
|
2
|
-
export * from "./catalog";
|
|
3
|
-
export * from "./doctor";
|
|
4
|
-
export * from "./execution";
|
|
5
|
-
export * from "./export";
|
|
6
|
-
export * from "./filter";
|
|
7
|
-
export * from "./profile";
|
|
8
|
-
export * from "./project";
|
|
9
|
-
export * from "./registry";
|
|
10
|
-
export * from "./runtime";
|
|
11
|
-
export * from "./schema/validator";
|
|
12
|
-
export * from "./server";
|
|
13
|
-
export * from "./storage";
|
|
14
|
-
export * from "./utils";
|
|
15
|
-
export type { ModuleLoader } from "./runtime";
|
|
16
|
-
|
package/src/profile/client.ts
DELETED
|
@@ -1,552 +0,0 @@
|
|
|
1
|
-
import { randomUUID } from "node:crypto";
|
|
2
|
-
import type { ExecutionResult, RuntimeError, RunRecord } from "@actiondock/sdk";
|
|
3
|
-
import { normalizeServerUrl } from "./manager";
|
|
4
|
-
import type { RemoteHealthResult } from "./types";
|
|
5
|
-
|
|
6
|
-
function buildHeaders(token?: string): Record<string, string> {
|
|
7
|
-
const headers: Record<string, string> = {
|
|
8
|
-
Accept: "application/json",
|
|
9
|
-
};
|
|
10
|
-
if (token && token.trim()) {
|
|
11
|
-
headers.Authorization = `Bearer ${token.trim()}`;
|
|
12
|
-
}
|
|
13
|
-
return headers;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* 调用远端 ActionDock 服务端执行 Action 时的选项参数。
|
|
18
|
-
*/
|
|
19
|
-
export interface RemoteExecuteOptions {
|
|
20
|
-
/** 动态配置覆盖 */
|
|
21
|
-
configOverrides?: Record<string, unknown>;
|
|
22
|
-
/** 鉴权 Bearer Token */
|
|
23
|
-
token?: string;
|
|
24
|
-
/** 超时毫秒数 */
|
|
25
|
-
timeoutMs?: number;
|
|
26
|
-
/** 中断信号 */
|
|
27
|
-
signal?: AbortSignal;
|
|
28
|
-
/** 是否异步触发(202 Accepted 立即返回 runId) */
|
|
29
|
-
async?: boolean;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* 远端 Action 执行结果信封对象。
|
|
34
|
-
*/
|
|
35
|
-
export type RemoteExecutionResult<T = unknown> = ExecutionResult<T> & {
|
|
36
|
-
status?: string;
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* 探测指定远端 ActionDock 服务的健康状态与网络延迟。
|
|
41
|
-
*
|
|
42
|
-
* @param serverUrl 目标服务端地址
|
|
43
|
-
* @param token 鉴权 Token(可选)
|
|
44
|
-
* @param timeoutMs 探测超时时间(默认 5000ms)
|
|
45
|
-
*/
|
|
46
|
-
export async function checkRemoteHealth(
|
|
47
|
-
serverUrl: string,
|
|
48
|
-
token?: string,
|
|
49
|
-
timeoutMs: number = 5000
|
|
50
|
-
): Promise<RemoteHealthResult> {
|
|
51
|
-
const base = normalizeServerUrl(serverUrl);
|
|
52
|
-
const url = `${base}/api/v1/health`;
|
|
53
|
-
const startTime = Date.now();
|
|
54
|
-
|
|
55
|
-
try {
|
|
56
|
-
const controller = new AbortController();
|
|
57
|
-
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
58
|
-
|
|
59
|
-
const res = await fetch(url, {
|
|
60
|
-
method: "GET",
|
|
61
|
-
headers: buildHeaders(token),
|
|
62
|
-
signal: controller.signal,
|
|
63
|
-
});
|
|
64
|
-
clearTimeout(timer);
|
|
65
|
-
|
|
66
|
-
const latencyMs = Date.now() - startTime;
|
|
67
|
-
|
|
68
|
-
if (!res.ok) {
|
|
69
|
-
const text = await res.text().catch(() => "");
|
|
70
|
-
return {
|
|
71
|
-
ok: false,
|
|
72
|
-
latencyMs,
|
|
73
|
-
error: `Server responded with status ${res.status}: ${text || res.statusText}`,
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
const data = (await res.json().catch(() => ({}))) as any;
|
|
78
|
-
return {
|
|
79
|
-
ok: true,
|
|
80
|
-
status: data.status || "ok",
|
|
81
|
-
version: data.version,
|
|
82
|
-
uptime: data.uptime,
|
|
83
|
-
latencyMs,
|
|
84
|
-
};
|
|
85
|
-
} catch (err: any) {
|
|
86
|
-
const latencyMs = Date.now() - startTime;
|
|
87
|
-
return {
|
|
88
|
-
ok: false,
|
|
89
|
-
latencyMs,
|
|
90
|
-
error: err.name === "AbortError" ? "Connection timed out" : err.message,
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
export async function executeRemoteAction<T = unknown>(
|
|
96
|
-
serverUrl: string,
|
|
97
|
-
actionId: string,
|
|
98
|
-
input: unknown = {},
|
|
99
|
-
configOverridesOrOptions?: Record<string, unknown> | RemoteExecuteOptions,
|
|
100
|
-
tokenArg?: string
|
|
101
|
-
): Promise<RemoteExecutionResult<T>> {
|
|
102
|
-
const base = normalizeServerUrl(serverUrl);
|
|
103
|
-
const url = `${base}/api/v1/actions/${encodeURIComponent(actionId)}/run`;
|
|
104
|
-
|
|
105
|
-
// Parse options / backwards compatibility
|
|
106
|
-
let configOverrides: Record<string, unknown> | undefined;
|
|
107
|
-
let token: string | undefined = tokenArg;
|
|
108
|
-
let timeoutMs: number | undefined;
|
|
109
|
-
let signal: AbortSignal | undefined;
|
|
110
|
-
let isAsync = false;
|
|
111
|
-
|
|
112
|
-
if (configOverridesOrOptions && typeof configOverridesOrOptions === "object") {
|
|
113
|
-
if (
|
|
114
|
-
"token" in configOverridesOrOptions ||
|
|
115
|
-
"timeoutMs" in configOverridesOrOptions ||
|
|
116
|
-
"signal" in configOverridesOrOptions ||
|
|
117
|
-
"async" in configOverridesOrOptions ||
|
|
118
|
-
"configOverrides" in configOverridesOrOptions
|
|
119
|
-
) {
|
|
120
|
-
const opts = configOverridesOrOptions as RemoteExecuteOptions;
|
|
121
|
-
configOverrides = opts.configOverrides;
|
|
122
|
-
token = opts.token ?? tokenArg;
|
|
123
|
-
timeoutMs = opts.timeoutMs;
|
|
124
|
-
signal = opts.signal;
|
|
125
|
-
isAsync = Boolean(opts.async);
|
|
126
|
-
} else {
|
|
127
|
-
configOverrides = configOverridesOrOptions as Record<string, unknown>;
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
const executionPayload: Record<string, unknown> = {};
|
|
132
|
-
if (isAsync) {
|
|
133
|
-
executionPayload.mode = "async";
|
|
134
|
-
}
|
|
135
|
-
if (typeof timeoutMs === "number" && timeoutMs > 0) {
|
|
136
|
-
executionPayload.timeoutMs = timeoutMs;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
try {
|
|
140
|
-
const headers = {
|
|
141
|
-
...buildHeaders(token),
|
|
142
|
-
"Content-Type": "application/json",
|
|
143
|
-
};
|
|
144
|
-
|
|
145
|
-
const res = await fetch(url, {
|
|
146
|
-
method: "POST",
|
|
147
|
-
headers,
|
|
148
|
-
body: JSON.stringify({
|
|
149
|
-
input,
|
|
150
|
-
config: configOverrides,
|
|
151
|
-
execution: Object.keys(executionPayload).length > 0 ? executionPayload : undefined,
|
|
152
|
-
}),
|
|
153
|
-
signal,
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
const data = (await res.json().catch(() => null)) as any;
|
|
157
|
-
|
|
158
|
-
if (data && typeof data === "object" && typeof data.ok === "boolean") {
|
|
159
|
-
return data;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
if (!res.ok) {
|
|
163
|
-
return {
|
|
164
|
-
ok: false,
|
|
165
|
-
runId: randomUUID(),
|
|
166
|
-
error: {
|
|
167
|
-
code: res.status === 401 ? "UNAUTHORIZED" : "REMOTE_EXECUTION_FAILED",
|
|
168
|
-
message: `Remote server HTTP ${res.status}: ${res.statusText}`,
|
|
169
|
-
details: data,
|
|
170
|
-
},
|
|
171
|
-
};
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
return {
|
|
175
|
-
ok: true,
|
|
176
|
-
runId: randomUUID(),
|
|
177
|
-
data,
|
|
178
|
-
};
|
|
179
|
-
} catch (err: any) {
|
|
180
|
-
if (err.name === "AbortError" || signal?.aborted) {
|
|
181
|
-
return {
|
|
182
|
-
ok: false,
|
|
183
|
-
runId: randomUUID(),
|
|
184
|
-
error: {
|
|
185
|
-
code: "ACTION_CANCELLED",
|
|
186
|
-
message: "Action execution was cancelled",
|
|
187
|
-
},
|
|
188
|
-
};
|
|
189
|
-
}
|
|
190
|
-
return {
|
|
191
|
-
ok: false,
|
|
192
|
-
runId: randomUUID(),
|
|
193
|
-
error: {
|
|
194
|
-
code: "NETWORK_ERROR",
|
|
195
|
-
message: `Failed to connect to remote ActionDock server at ${serverUrl}: ${err.message}`,
|
|
196
|
-
},
|
|
197
|
-
};
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
async function fetchRemoteJson<T = any>(
|
|
202
|
-
serverUrl: string,
|
|
203
|
-
path: string,
|
|
204
|
-
token?: string,
|
|
205
|
-
options: { method?: string; body?: unknown; errorPrefix?: string } = {}
|
|
206
|
-
): Promise<T> {
|
|
207
|
-
const base = normalizeServerUrl(serverUrl);
|
|
208
|
-
const url = `${base}${path.startsWith("/") ? path : `/${path}`}`;
|
|
209
|
-
const method = options.method || "GET";
|
|
210
|
-
const headers: Record<string, string> = {
|
|
211
|
-
...buildHeaders(token),
|
|
212
|
-
};
|
|
213
|
-
if (options.body !== undefined) {
|
|
214
|
-
headers["Content-Type"] = "application/json";
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
const res = await fetch(url, {
|
|
218
|
-
method,
|
|
219
|
-
headers,
|
|
220
|
-
body: options.body !== undefined ? JSON.stringify(options.body) : undefined,
|
|
221
|
-
});
|
|
222
|
-
|
|
223
|
-
const data = (await res.json().catch(() => ({}))) as any;
|
|
224
|
-
|
|
225
|
-
if (!res.ok || (options.method === "POST" && data && data.ok === false)) {
|
|
226
|
-
const errorPrefix = options.errorPrefix || "Remote request failed";
|
|
227
|
-
const msg = data?.error?.message || `${errorPrefix} (${res.status}): ${res.statusText}`;
|
|
228
|
-
throw new Error(msg);
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
return data as T;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
export async function fetchRemoteRun(
|
|
235
|
-
serverUrl: string,
|
|
236
|
-
runId: string,
|
|
237
|
-
token?: string
|
|
238
|
-
): Promise<RunRecord> {
|
|
239
|
-
return fetchRemoteJson<RunRecord>(
|
|
240
|
-
serverUrl,
|
|
241
|
-
`/api/v1/runs/${encodeURIComponent(runId)}`,
|
|
242
|
-
token,
|
|
243
|
-
{ errorPrefix: `Failed to fetch remote run '${runId}'` }
|
|
244
|
-
);
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
export async function cancelRemoteRun(
|
|
248
|
-
serverUrl: string,
|
|
249
|
-
runId: string,
|
|
250
|
-
token?: string,
|
|
251
|
-
reason?: string
|
|
252
|
-
): Promise<{ ok: boolean; runId: string; status: string }> {
|
|
253
|
-
return fetchRemoteJson(
|
|
254
|
-
serverUrl,
|
|
255
|
-
`/api/v1/runs/${encodeURIComponent(runId)}/cancel`,
|
|
256
|
-
token,
|
|
257
|
-
{
|
|
258
|
-
method: "POST",
|
|
259
|
-
body: { reason },
|
|
260
|
-
errorPrefix: `Failed to cancel remote run '${runId}'`,
|
|
261
|
-
}
|
|
262
|
-
);
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
export async function fetchRemoteActions(
|
|
266
|
-
serverUrl: string,
|
|
267
|
-
token?: string,
|
|
268
|
-
intent?: string
|
|
269
|
-
): Promise<Array<{ id: string; description: string; packageId?: string }>> {
|
|
270
|
-
const query = intent ? `?intent=${encodeURIComponent(intent)}` : "";
|
|
271
|
-
return fetchRemoteJson(
|
|
272
|
-
serverUrl,
|
|
273
|
-
`/api/v1/actions${query}`,
|
|
274
|
-
token,
|
|
275
|
-
{ errorPrefix: "Failed to fetch remote actions" }
|
|
276
|
-
);
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
export async function fetchRemoteActionShow(
|
|
280
|
-
serverUrl: string,
|
|
281
|
-
actionId: string,
|
|
282
|
-
token?: string
|
|
283
|
-
): Promise<any> {
|
|
284
|
-
return fetchRemoteJson(
|
|
285
|
-
serverUrl,
|
|
286
|
-
`/api/v1/actions/${encodeURIComponent(actionId)}`,
|
|
287
|
-
token,
|
|
288
|
-
{ errorPrefix: `Failed to fetch remote action '${actionId}'` }
|
|
289
|
-
);
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
export async function fetchRemoteInfo(
|
|
293
|
-
serverUrl: string,
|
|
294
|
-
token?: string,
|
|
295
|
-
options?: { intent?: string; package?: string; tree?: boolean }
|
|
296
|
-
): Promise<any> {
|
|
297
|
-
const params = new URLSearchParams();
|
|
298
|
-
if (options?.intent) params.set("intent", options.intent);
|
|
299
|
-
if (options?.package) params.set("package", options.package);
|
|
300
|
-
if (options?.tree) params.set("tree", "true");
|
|
301
|
-
const qs = params.toString() ? `?${params.toString()}` : "";
|
|
302
|
-
return fetchRemoteJson(
|
|
303
|
-
serverUrl,
|
|
304
|
-
`/api/v1/info${qs}`,
|
|
305
|
-
token,
|
|
306
|
-
{ errorPrefix: "Failed to fetch remote info" }
|
|
307
|
-
);
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
export async function fetchRemoteDoctor(
|
|
311
|
-
serverUrl: string,
|
|
312
|
-
token?: string,
|
|
313
|
-
targetPackage?: string
|
|
314
|
-
): Promise<any> {
|
|
315
|
-
const query = targetPackage ? `?package=${encodeURIComponent(targetPackage)}` : "";
|
|
316
|
-
return fetchRemoteJson(
|
|
317
|
-
serverUrl,
|
|
318
|
-
`/api/v1/doctor${query}`,
|
|
319
|
-
token,
|
|
320
|
-
{ errorPrefix: "Failed to fetch remote doctor report" }
|
|
321
|
-
);
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
export async function fetchRemotePlaybooks(
|
|
325
|
-
serverUrl: string,
|
|
326
|
-
token?: string,
|
|
327
|
-
options?: { intent?: string; package?: string }
|
|
328
|
-
): Promise<Array<{ id: string; description: string; actions: string[]; packageId: string; filePath: string }>> {
|
|
329
|
-
const params = new URLSearchParams();
|
|
330
|
-
if (options?.intent) params.set("intent", options.intent);
|
|
331
|
-
if (options?.package) params.set("package", options.package);
|
|
332
|
-
const qs = params.toString() ? `?${params.toString()}` : "";
|
|
333
|
-
return fetchRemoteJson(
|
|
334
|
-
serverUrl,
|
|
335
|
-
`/api/v1/playbooks${qs}`,
|
|
336
|
-
token,
|
|
337
|
-
{ errorPrefix: "Failed to fetch remote playbooks" }
|
|
338
|
-
);
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
export async function fetchRemotePlaybookShow(
|
|
342
|
-
serverUrl: string,
|
|
343
|
-
playbookId: string,
|
|
344
|
-
token?: string
|
|
345
|
-
): Promise<any> {
|
|
346
|
-
return fetchRemoteJson(
|
|
347
|
-
serverUrl,
|
|
348
|
-
`/api/v1/playbooks/${encodeURIComponent(playbookId)}`,
|
|
349
|
-
token,
|
|
350
|
-
{ errorPrefix: `Failed to fetch remote playbook '${playbookId}'` }
|
|
351
|
-
);
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
export async function fetchRemoteRuns(
|
|
355
|
-
serverUrl: string,
|
|
356
|
-
token?: string,
|
|
357
|
-
options?: { status?: string; actionId?: string; packageId?: string; intent?: string; limit?: number }
|
|
358
|
-
): Promise<{ ok: boolean; total: number; items: RunRecord[] }> {
|
|
359
|
-
const params = new URLSearchParams();
|
|
360
|
-
if (options?.status) params.set("status", options.status);
|
|
361
|
-
if (options?.actionId) params.set("actionId", options.actionId);
|
|
362
|
-
if (options?.packageId) params.set("packageId", options.packageId);
|
|
363
|
-
if (options?.intent) params.set("intent", options.intent);
|
|
364
|
-
if (options?.limit) params.set("limit", String(options.limit));
|
|
365
|
-
const qs = params.toString() ? `?${params.toString()}` : "";
|
|
366
|
-
return fetchRemoteJson(
|
|
367
|
-
serverUrl,
|
|
368
|
-
`/api/v1/runs${qs}`,
|
|
369
|
-
token,
|
|
370
|
-
{ errorPrefix: "Failed to fetch remote runs" }
|
|
371
|
-
);
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
export async function clearRemoteRuns(
|
|
375
|
-
serverUrl: string,
|
|
376
|
-
token?: string,
|
|
377
|
-
options?: { packageId?: string; actionId?: string; status?: string }
|
|
378
|
-
): Promise<{ ok: boolean; clearedCount: number }> {
|
|
379
|
-
return fetchRemoteJson(
|
|
380
|
-
serverUrl,
|
|
381
|
-
"/api/v1/runs/clear",
|
|
382
|
-
token,
|
|
383
|
-
{
|
|
384
|
-
method: "POST",
|
|
385
|
-
body: options || {},
|
|
386
|
-
errorPrefix: "Failed to clear remote runs",
|
|
387
|
-
}
|
|
388
|
-
);
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
export async function fetchRemoteStateList(
|
|
392
|
-
serverUrl: string,
|
|
393
|
-
token?: string,
|
|
394
|
-
options?: { package?: string; namespace?: string; prefix?: string }
|
|
395
|
-
): Promise<{ ok: boolean; packageId: string; keys: string[] }> {
|
|
396
|
-
const params = new URLSearchParams();
|
|
397
|
-
if (options?.package) params.set("package", options.package);
|
|
398
|
-
if (options?.namespace !== undefined) params.set("namespace", options.namespace);
|
|
399
|
-
if (options?.prefix) params.set("prefix", options.prefix);
|
|
400
|
-
const qs = params.toString() ? `?${params.toString()}` : "";
|
|
401
|
-
return fetchRemoteJson(
|
|
402
|
-
serverUrl,
|
|
403
|
-
`/api/v1/state${qs}`,
|
|
404
|
-
token,
|
|
405
|
-
{ errorPrefix: "Failed to list remote state keys" }
|
|
406
|
-
);
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
export async function getRemoteStateKey(
|
|
410
|
-
serverUrl: string,
|
|
411
|
-
key: string,
|
|
412
|
-
token?: string,
|
|
413
|
-
options?: { package?: string; namespace?: string }
|
|
414
|
-
): Promise<any> {
|
|
415
|
-
const params = new URLSearchParams();
|
|
416
|
-
if (options?.package) params.set("package", options.package);
|
|
417
|
-
if (options?.namespace !== undefined) params.set("namespace", options.namespace);
|
|
418
|
-
const qs = params.toString() ? `?${params.toString()}` : "";
|
|
419
|
-
return fetchRemoteJson(
|
|
420
|
-
serverUrl,
|
|
421
|
-
`/api/v1/state/${encodeURIComponent(key)}${qs}`,
|
|
422
|
-
token,
|
|
423
|
-
{ errorPrefix: `Failed to fetch remote state key '${key}'` }
|
|
424
|
-
);
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
export async function setRemoteStateKey(
|
|
428
|
-
serverUrl: string,
|
|
429
|
-
key: string,
|
|
430
|
-
value: unknown,
|
|
431
|
-
token?: string,
|
|
432
|
-
options?: { package?: string; namespace?: string; ttl?: number }
|
|
433
|
-
): Promise<any> {
|
|
434
|
-
return fetchRemoteJson(
|
|
435
|
-
serverUrl,
|
|
436
|
-
`/api/v1/state/${encodeURIComponent(key)}`,
|
|
437
|
-
token,
|
|
438
|
-
{
|
|
439
|
-
method: "PUT",
|
|
440
|
-
body: {
|
|
441
|
-
value,
|
|
442
|
-
package: options?.package,
|
|
443
|
-
namespace: options?.namespace,
|
|
444
|
-
ttl: options?.ttl,
|
|
445
|
-
},
|
|
446
|
-
errorPrefix: `Failed to set remote state key '${key}'`,
|
|
447
|
-
}
|
|
448
|
-
);
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
export async function deleteRemoteStateKey(
|
|
452
|
-
serverUrl: string,
|
|
453
|
-
key: string,
|
|
454
|
-
token?: string,
|
|
455
|
-
options?: { package?: string; namespace?: string }
|
|
456
|
-
): Promise<any> {
|
|
457
|
-
const params = new URLSearchParams();
|
|
458
|
-
if (options?.package) params.set("package", options.package);
|
|
459
|
-
if (options?.namespace !== undefined) params.set("namespace", options.namespace);
|
|
460
|
-
const qs = params.toString() ? `?${params.toString()}` : "";
|
|
461
|
-
return fetchRemoteJson(
|
|
462
|
-
serverUrl,
|
|
463
|
-
`/api/v1/state/${encodeURIComponent(key)}${qs}`,
|
|
464
|
-
token,
|
|
465
|
-
{
|
|
466
|
-
method: "DELETE",
|
|
467
|
-
errorPrefix: `Failed to delete remote state key '${key}'`,
|
|
468
|
-
}
|
|
469
|
-
);
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
export async function clearRemoteState(
|
|
473
|
-
serverUrl: string,
|
|
474
|
-
token?: string,
|
|
475
|
-
options?: { package?: string; namespace?: string; prefix?: string; all?: boolean }
|
|
476
|
-
): Promise<{ ok: boolean; packageId: string; clearedCount: number }> {
|
|
477
|
-
return fetchRemoteJson(
|
|
478
|
-
serverUrl,
|
|
479
|
-
"/api/v1/state/clear",
|
|
480
|
-
token,
|
|
481
|
-
{
|
|
482
|
-
method: "POST",
|
|
483
|
-
body: options || {},
|
|
484
|
-
errorPrefix: "Failed to clear remote state",
|
|
485
|
-
}
|
|
486
|
-
);
|
|
487
|
-
}
|
|
488
|
-
|
|
489
|
-
export async function fetchRemoteConfig(
|
|
490
|
-
serverUrl: string,
|
|
491
|
-
token?: string,
|
|
492
|
-
packageId?: string
|
|
493
|
-
): Promise<any> {
|
|
494
|
-
const query = packageId ? `?package=${encodeURIComponent(packageId)}` : "";
|
|
495
|
-
return fetchRemoteJson(
|
|
496
|
-
serverUrl,
|
|
497
|
-
`/api/v1/config${query}`,
|
|
498
|
-
token,
|
|
499
|
-
{ errorPrefix: "Failed to fetch remote config" }
|
|
500
|
-
);
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
export async function setRemoteConfig(
|
|
504
|
-
serverUrl: string,
|
|
505
|
-
key: string,
|
|
506
|
-
value: unknown,
|
|
507
|
-
token?: string,
|
|
508
|
-
packageId?: string
|
|
509
|
-
): Promise<any> {
|
|
510
|
-
return fetchRemoteJson(
|
|
511
|
-
serverUrl,
|
|
512
|
-
"/api/v1/config",
|
|
513
|
-
token,
|
|
514
|
-
{
|
|
515
|
-
method: "PUT",
|
|
516
|
-
body: { key, value, package: packageId },
|
|
517
|
-
errorPrefix: `Failed to set remote config '${key}'`,
|
|
518
|
-
}
|
|
519
|
-
);
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
export async function deleteRemoteConfig(
|
|
523
|
-
serverUrl: string,
|
|
524
|
-
key: string,
|
|
525
|
-
token?: string,
|
|
526
|
-
packageId?: string
|
|
527
|
-
): Promise<any> {
|
|
528
|
-
const query = packageId ? `?package=${encodeURIComponent(packageId)}` : "";
|
|
529
|
-
return fetchRemoteJson(
|
|
530
|
-
serverUrl,
|
|
531
|
-
`/api/v1/config/${encodeURIComponent(key)}${query}`,
|
|
532
|
-
token,
|
|
533
|
-
{
|
|
534
|
-
method: "DELETE",
|
|
535
|
-
errorPrefix: `Failed to delete remote config '${key}'`,
|
|
536
|
-
}
|
|
537
|
-
);
|
|
538
|
-
}
|
|
539
|
-
|
|
540
|
-
export async function fetchRemoteConfigEnv(
|
|
541
|
-
serverUrl: string,
|
|
542
|
-
token?: string,
|
|
543
|
-
packageId?: string
|
|
544
|
-
): Promise<any> {
|
|
545
|
-
const query = packageId ? `?package=${encodeURIComponent(packageId)}` : "";
|
|
546
|
-
return fetchRemoteJson(
|
|
547
|
-
serverUrl,
|
|
548
|
-
`/api/v1/config/env${query}`,
|
|
549
|
-
token,
|
|
550
|
-
{ errorPrefix: "Failed to fetch remote config env checks" }
|
|
551
|
-
);
|
|
552
|
-
}
|