@actiondock/core 2.0.9 → 2.0.11-beta.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/package.json +2 -2
- package/src/build/index.ts +0 -1
- package/src/build/templates.ts +1 -1
- package/src/catalog/types.ts +1 -9
- package/src/doctor/doctor.ts +99 -38
- package/src/execution/service.ts +47 -7
- package/src/export/index.ts +0 -1
- package/src/export/templates.ts +348 -59
- package/src/index.ts +1 -0
- package/src/project/init.ts +3 -2
- package/src/project/loader.ts +46 -7
- package/src/project/manifest.ts +205 -2
- package/src/project/types.ts +49 -0
- package/src/registry/registry.ts +271 -34
- package/src/runtime/context.ts +8 -3
- package/src/runtime/index.ts +1 -0
- package/src/runtime/module-loader.ts +67 -0
- package/src/runtime/process.ts +12 -11
- package/src/runtime/runner.ts +193 -68
- package/src/server/index.ts +1 -0
- package/src/server/routes/actions.ts +262 -0
- package/src/server/routes/common.ts +126 -0
- package/src/server/routes/config.ts +147 -0
- package/src/server/routes/doctor.ts +29 -0
- package/src/server/routes/health.ts +40 -0
- package/src/server/routes/index.ts +9 -0
- package/src/server/routes/info.ts +221 -0
- package/src/server/routes/playbooks.ts +109 -0
- package/src/server/routes/runs.ts +301 -0
- package/src/server/routes/state.ts +133 -0
- package/src/server/server.ts +82 -1323
- package/src/storage/index.ts +20 -4
- package/src/storage/sqlite.ts +60 -31
- package/src/storage/types.ts +8 -0
- package/src/utils/index.ts +2 -0
- package/src/build/builder.ts +0 -218
- package/src/export/skill.ts +0 -350
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { readJsonBody } from "../body";
|
|
2
|
+
import { type RouteContext, jsonResponse, resolveStorageForPackage } from "./common";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 处理状态键名列表、读取、写入、删除及清空接口。
|
|
6
|
+
*/
|
|
7
|
+
export async function handleStateRoutes(ctx: RouteContext): Promise<Response | null> {
|
|
8
|
+
const { req, url, pathname, corsHeaders, projectRoot, customHome, runtimeRegistry, options } = ctx;
|
|
9
|
+
|
|
10
|
+
// 1. State List: GET /api/v1/state
|
|
11
|
+
if (pathname === "/api/v1/state" && req.method === "GET") {
|
|
12
|
+
try {
|
|
13
|
+
const pkgParam = url.searchParams.get("package") || undefined;
|
|
14
|
+
const nsParam = url.searchParams.get("namespace") ?? undefined;
|
|
15
|
+
const prefix = url.searchParams.get("prefix") || "";
|
|
16
|
+
|
|
17
|
+
const { packageId, storage } = resolveStorageForPackage(
|
|
18
|
+
pkgParam,
|
|
19
|
+
runtimeRegistry,
|
|
20
|
+
projectRoot,
|
|
21
|
+
customHome
|
|
22
|
+
);
|
|
23
|
+
const keys = await storage.listStateKeys(nsParam !== undefined ? nsParam : null, prefix);
|
|
24
|
+
return jsonResponse({ ok: true, packageId, keys }, 200, corsHeaders);
|
|
25
|
+
} catch (err: any) {
|
|
26
|
+
return jsonResponse(
|
|
27
|
+
{ ok: false, error: { code: "STATE_LIST_ERROR", message: err.message } },
|
|
28
|
+
500,
|
|
29
|
+
corsHeaders
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// 2. State Clear: POST /api/v1/state/clear
|
|
35
|
+
if (pathname === "/api/v1/state/clear" && req.method === "POST") {
|
|
36
|
+
try {
|
|
37
|
+
const body = await readJsonBody(req, { maxBytes: options.maxBodyBytes }).catch(() => ({}));
|
|
38
|
+
const pkgParam = url.searchParams.get("package") || body.package || undefined;
|
|
39
|
+
const { packageId, storage } = resolveStorageForPackage(
|
|
40
|
+
pkgParam,
|
|
41
|
+
runtimeRegistry,
|
|
42
|
+
projectRoot,
|
|
43
|
+
customHome
|
|
44
|
+
);
|
|
45
|
+
const clearedCount = await storage.clearState({
|
|
46
|
+
namespace: body.namespace ?? (url.searchParams.get("namespace") || undefined),
|
|
47
|
+
all: Boolean(body.all ?? url.searchParams.get("all") === "true"),
|
|
48
|
+
prefix: body.prefix ?? (url.searchParams.get("prefix") || undefined),
|
|
49
|
+
});
|
|
50
|
+
return jsonResponse({ ok: true, packageId, clearedCount }, 200, corsHeaders);
|
|
51
|
+
} catch (err: any) {
|
|
52
|
+
return jsonResponse(
|
|
53
|
+
{ ok: false, error: { code: "STATE_CLEAR_ERROR", message: err.message } },
|
|
54
|
+
500,
|
|
55
|
+
corsHeaders
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// 3. State Key CRUD: GET / PUT / POST / DELETE /api/v1/state/:key
|
|
61
|
+
const stateKeyMatch = pathname.match(/^\/api\/v1\/state\/([^/]+)$/);
|
|
62
|
+
if (stateKeyMatch) {
|
|
63
|
+
const key = decodeURIComponent(stateKeyMatch[1]);
|
|
64
|
+
const pkgParam = url.searchParams.get("package") || undefined;
|
|
65
|
+
const nsParam = url.searchParams.get("namespace") || undefined;
|
|
66
|
+
|
|
67
|
+
const { packageId, storage } = resolveStorageForPackage(
|
|
68
|
+
pkgParam,
|
|
69
|
+
runtimeRegistry,
|
|
70
|
+
projectRoot,
|
|
71
|
+
customHome
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
if (req.method === "GET") {
|
|
75
|
+
const entry = await storage.findState(key, nsParam);
|
|
76
|
+
if (!entry || entry.value === undefined) {
|
|
77
|
+
return jsonResponse(
|
|
78
|
+
{ ok: false, error: { code: "STATE_KEY_NOT_FOUND", message: `State key '${key}' not found` } },
|
|
79
|
+
404,
|
|
80
|
+
corsHeaders
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
return jsonResponse(
|
|
84
|
+
{
|
|
85
|
+
ok: true,
|
|
86
|
+
packageId,
|
|
87
|
+
key: entry.key,
|
|
88
|
+
namespace: entry.namespace,
|
|
89
|
+
value: entry.value,
|
|
90
|
+
expiresAt: entry.expiresAt,
|
|
91
|
+
},
|
|
92
|
+
200,
|
|
93
|
+
corsHeaders
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (req.method === "PUT" || req.method === "POST") {
|
|
98
|
+
const body = await readJsonBody(req, { maxBytes: options.maxBodyBytes });
|
|
99
|
+
const val = body.value !== undefined ? body.value : body;
|
|
100
|
+
const ttl = typeof body.ttl === "number" ? body.ttl : undefined;
|
|
101
|
+
const namespace = body.namespace || nsParam || "";
|
|
102
|
+
|
|
103
|
+
let actualKey = key;
|
|
104
|
+
let ns = namespace;
|
|
105
|
+
if (!ns && key.includes(":")) {
|
|
106
|
+
const idx = key.indexOf(":");
|
|
107
|
+
ns = key.slice(0, idx);
|
|
108
|
+
actualKey = key.slice(idx + 1);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
await storage.setState(ns, actualKey, val, ttl);
|
|
112
|
+
return jsonResponse(
|
|
113
|
+
{ ok: true, packageId, key: actualKey, namespace: ns, message: "updated" },
|
|
114
|
+
200,
|
|
115
|
+
corsHeaders
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (req.method === "DELETE") {
|
|
120
|
+
const deleted = await storage.deleteStateSmart(key, nsParam);
|
|
121
|
+
if (!deleted) {
|
|
122
|
+
return jsonResponse(
|
|
123
|
+
{ ok: false, error: { code: "STATE_KEY_NOT_FOUND", message: `State key '${key}' not found` } },
|
|
124
|
+
404,
|
|
125
|
+
corsHeaders
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
return jsonResponse({ ok: true, packageId, key, deleted: true }, 200, corsHeaders);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return null;
|
|
133
|
+
}
|