@workclaw/openclaw-workclaw 1.0.20 → 1.0.25

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 (153) hide show
  1. package/README.md +0 -1
  2. package/api.ts +3 -0
  3. package/index.ts +325 -0
  4. package/package.json +3 -11
  5. package/setup-entry.ts +13 -0
  6. package/src/accounts.ts +360 -0
  7. package/src/api/accounts-api.ts +156 -0
  8. package/src/api/prompts-api.ts +122 -0
  9. package/src/api/session-api.ts +246 -0
  10. package/src/api/skills-api.ts +74 -0
  11. package/src/api/workspace.ts +45 -0
  12. package/src/channel.ts +226 -0
  13. package/{dist/src/config-schema.js → src/config-schema.ts} +60 -56
  14. package/src/connection/workclaw-client.ts +618 -0
  15. package/src/gateway/agent-handlers.ts +551 -0
  16. package/src/gateway/config-writer.ts +378 -0
  17. package/src/gateway/cron-tasks-handler.ts +230 -0
  18. package/src/gateway/message-context.ts +645 -0
  19. package/src/gateway/message-dispatcher.ts +688 -0
  20. package/src/gateway/reconnect.ts +260 -0
  21. package/src/gateway/skills-handler.ts +805 -0
  22. package/src/gateway/skills-list-handler.ts +332 -0
  23. package/src/gateway/tools-list-handler.ts +161 -0
  24. package/src/gateway/workclaw-gateway.ts +304 -0
  25. package/src/media/upload.ts +168 -0
  26. package/src/outbound/index.ts +191 -0
  27. package/src/outbound/workclaw-sender.ts +161 -0
  28. package/src/runtime.ts +520 -0
  29. package/src/secret-contract-api.ts +4 -0
  30. package/src/send.ts +1 -0
  31. package/src/setup-api.ts +3 -0
  32. package/src/setup-core.ts +25 -0
  33. package/src/setup-surface.ts +498 -0
  34. package/src/tools/openclaw-workclaw-cron/api/index.ts +326 -0
  35. package/{dist/src/tools/openclaw-workclaw-cron/index.js → src/tools/openclaw-workclaw-cron/index.ts} +39 -33
  36. package/src/tools/openclaw-workclaw-cron/src/add/params.ts +177 -0
  37. package/src/tools/openclaw-workclaw-cron/src/add/sync.ts +188 -0
  38. package/src/tools/openclaw-workclaw-cron/src/disable/params.ts +100 -0
  39. package/src/tools/openclaw-workclaw-cron/src/disable/sync.ts +127 -0
  40. package/src/tools/openclaw-workclaw-cron/src/enable/params.ts +100 -0
  41. package/src/tools/openclaw-workclaw-cron/src/enable/sync.ts +127 -0
  42. package/src/tools/openclaw-workclaw-cron/src/notify/sync.ts +148 -0
  43. package/src/tools/openclaw-workclaw-cron/src/remove/params.ts +109 -0
  44. package/src/tools/openclaw-workclaw-cron/src/remove/sync.ts +127 -0
  45. package/src/tools/openclaw-workclaw-cron/src/update/params.ts +195 -0
  46. package/src/tools/openclaw-workclaw-cron/src/update/sync.ts +161 -0
  47. package/src/tools/openclaw-workclaw-cron/types/index.ts +55 -0
  48. package/src/tools/openclaw-workclaw-cron/utils/index.ts +141 -0
  49. package/{dist/src/tools/openclaw-workclaw-system/index.js → src/tools/openclaw-workclaw-system/index.ts} +17 -15
  50. package/src/tools/openclaw-workclaw-system/src/get/index.ts +77 -0
  51. package/src/tools/openclaw-workclaw-system/src/token/index.ts +93 -0
  52. package/src/types.ts +50 -0
  53. package/src/utils/content.ts +40 -0
  54. package/tsconfig.json +34 -0
  55. package/dist/api.d.ts +0 -3
  56. package/dist/api.js +0 -3
  57. package/dist/index.d.ts +0 -11
  58. package/dist/index.js +0 -264
  59. package/dist/setup-entry.d.ts +0 -2
  60. package/dist/setup-entry.js +0 -12
  61. package/dist/src/accounts.d.ts +0 -66
  62. package/dist/src/accounts.js +0 -279
  63. package/dist/src/api/accounts-api.d.ts +0 -2
  64. package/dist/src/api/accounts-api.js +0 -130
  65. package/dist/src/api/prompts-api.d.ts +0 -2
  66. package/dist/src/api/prompts-api.js +0 -103
  67. package/dist/src/api/session-api.d.ts +0 -2
  68. package/dist/src/api/session-api.js +0 -207
  69. package/dist/src/api/skills-api.d.ts +0 -2
  70. package/dist/src/api/skills-api.js +0 -64
  71. package/dist/src/api/workspace.d.ts +0 -3
  72. package/dist/src/api/workspace.js +0 -30
  73. package/dist/src/channel.d.ts +0 -11
  74. package/dist/src/channel.js +0 -199
  75. package/dist/src/config-schema.d.ts +0 -93
  76. package/dist/src/connection/workclaw-client.d.ts +0 -147
  77. package/dist/src/connection/workclaw-client.js +0 -351
  78. package/dist/src/gateway/agent-handlers.d.ts +0 -12
  79. package/dist/src/gateway/agent-handlers.js +0 -433
  80. package/dist/src/gateway/config-writer.d.ts +0 -71
  81. package/dist/src/gateway/config-writer.js +0 -302
  82. package/dist/src/gateway/cron-tasks-handler.d.ts +0 -19
  83. package/dist/src/gateway/cron-tasks-handler.js +0 -188
  84. package/dist/src/gateway/message-context.d.ts +0 -80
  85. package/dist/src/gateway/message-context.js +0 -509
  86. package/dist/src/gateway/message-dispatcher.d.ts +0 -18
  87. package/dist/src/gateway/message-dispatcher.js +0 -572
  88. package/dist/src/gateway/reconnect.d.ts +0 -27
  89. package/dist/src/gateway/reconnect.js +0 -210
  90. package/dist/src/gateway/skills-handler.d.ts +0 -29
  91. package/dist/src/gateway/skills-handler.js +0 -615
  92. package/dist/src/gateway/skills-list-handler.d.ts +0 -27
  93. package/dist/src/gateway/skills-list-handler.js +0 -233
  94. package/dist/src/gateway/tools-list-handler.d.ts +0 -30
  95. package/dist/src/gateway/tools-list-handler.js +0 -101
  96. package/dist/src/gateway/workclaw-gateway.d.ts +0 -14
  97. package/dist/src/gateway/workclaw-gateway.js +0 -237
  98. package/dist/src/media/upload.d.ts +0 -13
  99. package/dist/src/media/upload.js +0 -125
  100. package/dist/src/outbound/index.d.ts +0 -36
  101. package/dist/src/outbound/index.js +0 -123
  102. package/dist/src/outbound/workclaw-sender.d.ts +0 -36
  103. package/dist/src/outbound/workclaw-sender.js +0 -95
  104. package/dist/src/runtime.d.ts +0 -116
  105. package/dist/src/runtime.js +0 -374
  106. package/dist/src/secret-contract-api.d.ts +0 -4
  107. package/dist/src/secret-contract-api.js +0 -4
  108. package/dist/src/send.d.ts +0 -1
  109. package/dist/src/send.js +0 -1
  110. package/dist/src/setup-api.d.ts +0 -3
  111. package/dist/src/setup-api.js +0 -3
  112. package/dist/src/setup-core.d.ts +0 -3
  113. package/dist/src/setup-core.js +0 -13
  114. package/dist/src/setup-surface.d.ts +0 -7
  115. package/dist/src/setup-surface.js +0 -363
  116. package/dist/src/tools/openclaw-workclaw-cron/api/index.d.ts +0 -93
  117. package/dist/src/tools/openclaw-workclaw-cron/api/index.js +0 -209
  118. package/dist/src/tools/openclaw-workclaw-cron/index.d.ts +0 -10
  119. package/dist/src/tools/openclaw-workclaw-cron/src/add/params.d.ts +0 -16
  120. package/dist/src/tools/openclaw-workclaw-cron/src/add/params.js +0 -152
  121. package/dist/src/tools/openclaw-workclaw-cron/src/add/sync.d.ts +0 -18
  122. package/dist/src/tools/openclaw-workclaw-cron/src/add/sync.js +0 -162
  123. package/dist/src/tools/openclaw-workclaw-cron/src/disable/params.d.ts +0 -14
  124. package/dist/src/tools/openclaw-workclaw-cron/src/disable/params.js +0 -80
  125. package/dist/src/tools/openclaw-workclaw-cron/src/disable/sync.d.ts +0 -14
  126. package/dist/src/tools/openclaw-workclaw-cron/src/disable/sync.js +0 -107
  127. package/dist/src/tools/openclaw-workclaw-cron/src/enable/params.d.ts +0 -14
  128. package/dist/src/tools/openclaw-workclaw-cron/src/enable/params.js +0 -80
  129. package/dist/src/tools/openclaw-workclaw-cron/src/enable/sync.d.ts +0 -14
  130. package/dist/src/tools/openclaw-workclaw-cron/src/enable/sync.js +0 -107
  131. package/dist/src/tools/openclaw-workclaw-cron/src/notify/sync.d.ts +0 -17
  132. package/dist/src/tools/openclaw-workclaw-cron/src/notify/sync.js +0 -127
  133. package/dist/src/tools/openclaw-workclaw-cron/src/remove/params.d.ts +0 -14
  134. package/dist/src/tools/openclaw-workclaw-cron/src/remove/params.js +0 -87
  135. package/dist/src/tools/openclaw-workclaw-cron/src/remove/sync.d.ts +0 -14
  136. package/dist/src/tools/openclaw-workclaw-cron/src/remove/sync.js +0 -107
  137. package/dist/src/tools/openclaw-workclaw-cron/src/update/params.d.ts +0 -17
  138. package/dist/src/tools/openclaw-workclaw-cron/src/update/params.js +0 -164
  139. package/dist/src/tools/openclaw-workclaw-cron/src/update/sync.d.ts +0 -18
  140. package/dist/src/tools/openclaw-workclaw-cron/src/update/sync.js +0 -135
  141. package/dist/src/tools/openclaw-workclaw-cron/types/index.d.ts +0 -52
  142. package/dist/src/tools/openclaw-workclaw-cron/types/index.js +0 -4
  143. package/dist/src/tools/openclaw-workclaw-cron/utils/index.d.ts +0 -40
  144. package/dist/src/tools/openclaw-workclaw-cron/utils/index.js +0 -122
  145. package/dist/src/tools/openclaw-workclaw-system/index.d.ts +0 -10
  146. package/dist/src/tools/openclaw-workclaw-system/src/get/index.d.ts +0 -8
  147. package/dist/src/tools/openclaw-workclaw-system/src/get/index.js +0 -64
  148. package/dist/src/tools/openclaw-workclaw-system/src/token/index.d.ts +0 -8
  149. package/dist/src/tools/openclaw-workclaw-system/src/token/index.js +0 -78
  150. package/dist/src/types.d.ts +0 -39
  151. package/dist/src/types.js +0 -1
  152. package/dist/src/utils/content.d.ts +0 -15
  153. package/dist/src/utils/content.js +0 -38
@@ -1,130 +0,0 @@
1
- import { normalizeAccountId } from "../accounts.js";
2
- function sendJson(res, statusCode, payload) {
3
- res.statusCode = statusCode;
4
- res.setHeader("Content-Type", "application/json");
5
- res.end(JSON.stringify(payload));
6
- }
7
- async function readRequestBody(req) {
8
- const chunks = [];
9
- await new Promise((resolve, reject) => {
10
- req.on("data", (chunk) => {
11
- chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
12
- });
13
- req.on("end", () => resolve());
14
- req.on("error", (err) => reject(err));
15
- });
16
- return Buffer.concat(chunks).toString("utf-8");
17
- }
18
- async function loadRuntimeConfig(api) {
19
- const runtimeConfig = api.runtime?.config;
20
- if (runtimeConfig?.loadConfig) {
21
- return runtimeConfig.loadConfig();
22
- }
23
- return api.config;
24
- }
25
- async function writeRuntimeConfig(api, config) {
26
- const runtimeConfig = api.runtime?.config;
27
- if (runtimeConfig?.writeConfigFile) {
28
- await runtimeConfig.writeConfigFile(config);
29
- return;
30
- }
31
- throw new Error("Config write not supported");
32
- }
33
- function getAccountMap(config) {
34
- const channels = config?.channels && typeof config.channels === "object" ? config.channels : {};
35
- const openclawWorkclaw = channels['openclaw-workclaw'] && typeof channels['openclaw-workclaw'] === "object" ? channels['openclaw-workclaw'] : {};
36
- const accounts = openclawWorkclaw.accounts && typeof openclawWorkclaw.accounts === "object" ? openclawWorkclaw.accounts : {};
37
- return { ...accounts };
38
- }
39
- function withAccounts(config, accounts) {
40
- const channels = config?.channels && typeof config.channels === "object" ? config.channels : {};
41
- const openclawWorkclaw = channels['openclaw-workclaw'] && typeof channels['openclaw-workclaw'] === "object" ? channels['openclaw-workclaw'] : {};
42
- return {
43
- ...config,
44
- channels: {
45
- ...channels,
46
- 'openclaw-workclaw': {
47
- ...openclawWorkclaw,
48
- accounts,
49
- },
50
- },
51
- };
52
- }
53
- export function createAccountsApiHandler(api) {
54
- return async (req, res) => {
55
- const method = String(req.method ?? "GET").toUpperCase();
56
- const url = new URL(req.url ?? "", "http://localhost");
57
- const idRaw = url.searchParams.get("id") ?? url.searchParams.get("accountId");
58
- const accountId = idRaw ? normalizeAccountId(idRaw) : null;
59
- if (method === "GET") {
60
- const cfg = await loadRuntimeConfig(api);
61
- const accounts = getAccountMap(cfg);
62
- if (accountId) {
63
- const account = accounts[accountId];
64
- if (!account) {
65
- sendJson(res, 404, { ok: false, error: "Not Found" });
66
- return;
67
- }
68
- sendJson(res, 200, { ok: true, accountId, config: account });
69
- return;
70
- }
71
- const entries = Object.entries(accounts).map(([id, config]) => ({
72
- accountId: id,
73
- config,
74
- }));
75
- sendJson(res, 200, { ok: true, accounts: entries });
76
- return;
77
- }
78
- if (method === "POST" || method === "PUT") {
79
- const raw = await readRequestBody(req);
80
- let input = {};
81
- try {
82
- input = raw ? JSON.parse(raw) : {};
83
- }
84
- catch {
85
- sendJson(res, 400, { ok: false, error: "Invalid JSON" });
86
- return;
87
- }
88
- const inputId = input?.accountId ?? input?.id;
89
- const normalizedId = inputId ? normalizeAccountId(String(inputId)) : "";
90
- const patch = input?.config;
91
- if (!normalizedId || !patch || typeof patch !== "object") {
92
- sendJson(res, 400, { ok: false, error: "Missing accountId or config" });
93
- return;
94
- }
95
- const cfg = await loadRuntimeConfig(api);
96
- const accounts = getAccountMap(cfg);
97
- if (method === "POST" && accounts[normalizedId]) {
98
- sendJson(res, 409, { ok: false, error: "Account already exists" });
99
- return;
100
- }
101
- if (method === "PUT" && !accounts[normalizedId]) {
102
- sendJson(res, 404, { ok: false, error: "Not Found" });
103
- return;
104
- }
105
- const next = method === "PUT" ? { ...accounts[normalizedId], ...patch } : patch;
106
- const updated = withAccounts(cfg, { ...accounts, [normalizedId]: next });
107
- await writeRuntimeConfig(api, updated);
108
- sendJson(res, 200, { ok: true, accountId: normalizedId });
109
- return;
110
- }
111
- if (method === "DELETE") {
112
- if (!accountId) {
113
- sendJson(res, 400, { ok: false, error: "Missing accountId" });
114
- return;
115
- }
116
- const cfg = await loadRuntimeConfig(api);
117
- const accounts = getAccountMap(cfg);
118
- if (!accounts[accountId]) {
119
- sendJson(res, 404, { ok: false, error: "Not Found" });
120
- return;
121
- }
122
- const { [accountId]: _ignored, ...rest } = accounts;
123
- const updated = withAccounts(cfg, rest);
124
- await writeRuntimeConfig(api, updated);
125
- sendJson(res, 200, { ok: true, accountId, deleted: true });
126
- return;
127
- }
128
- sendJson(res, 405, { ok: false, error: "Method Not Allowed" });
129
- };
130
- }
@@ -1,2 +0,0 @@
1
- import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
2
- export declare function createPromptsApiHandler(api: OpenClawPluginApi): (req: any, res: any) => Promise<void>;
@@ -1,103 +0,0 @@
1
- import { mkdir, readFile, stat, unlink, writeFile } from "node:fs/promises";
2
- import { resolveWorkspaceDir } from "./workspace.js";
3
- const promptNames = ["SOUL.md", "USER.md"];
4
- function normalizePromptName(raw) {
5
- const name = String(raw ?? "").trim().toUpperCase();
6
- if (name === "SOUL" || name === "SOUL.MD")
7
- return "SOUL.md";
8
- if (name === "USER" || name === "USER.MD")
9
- return "USER.md";
10
- return null;
11
- }
12
- import path from "node:path";
13
- function resolvePromptPath(api, name) {
14
- return path.join(resolveWorkspaceDir(api), name);
15
- }
16
- function sendJson(res, statusCode, payload) {
17
- res.statusCode = statusCode;
18
- res.setHeader("Content-Type", "application/json");
19
- res.end(JSON.stringify(payload));
20
- }
21
- export function createPromptsApiHandler(api) {
22
- return async (req, res) => {
23
- const method = String(req.method ?? "GET").toUpperCase();
24
- const url = new URL(req.url ?? "", "http://localhost");
25
- const name = normalizePromptName(url.searchParams.get("name"));
26
- if (method === "GET") {
27
- if (name) {
28
- const filePath = resolvePromptPath(api, name);
29
- try {
30
- const content = await readFile(filePath, "utf-8");
31
- sendJson(res, 200, { ok: true, name, content });
32
- return;
33
- }
34
- catch (error) {
35
- sendJson(res, 404, { ok: false, error: "Not Found" });
36
- return;
37
- }
38
- }
39
- const entries = await Promise.all(promptNames.map(async (promptName) => {
40
- const filePath = resolvePromptPath(api, promptName);
41
- try {
42
- const info = await stat(filePath);
43
- return { name: promptName, exists: true, bytes: info.size };
44
- }
45
- catch {
46
- return { name: promptName, exists: false, bytes: 0 };
47
- }
48
- }));
49
- sendJson(res, 200, { ok: true, entries });
50
- return;
51
- }
52
- if (method === "PUT" || method === "POST") {
53
- const raw = await readRequestBody(req);
54
- let input = {};
55
- try {
56
- input = raw ? JSON.parse(raw) : {};
57
- }
58
- catch {
59
- sendJson(res, 400, { ok: false, error: "Invalid JSON" });
60
- return;
61
- }
62
- const targetName = normalizePromptName(input?.name);
63
- const content = typeof input?.content === "string" ? input.content : null;
64
- if (!targetName || content === null) {
65
- sendJson(res, 400, { ok: false, error: "Missing name or content" });
66
- return;
67
- }
68
- const workspaceDir = resolveWorkspaceDir(api);
69
- await mkdir(workspaceDir, { recursive: true });
70
- await writeFile(resolvePromptPath(api, targetName), content, { encoding: "utf-8" });
71
- sendJson(res, 200, { ok: true, name: targetName });
72
- return;
73
- }
74
- if (method === "DELETE") {
75
- if (!name) {
76
- sendJson(res, 400, { ok: false, error: "Missing name" });
77
- return;
78
- }
79
- const filePath = resolvePromptPath(api, name);
80
- try {
81
- await unlink(filePath);
82
- sendJson(res, 200, { ok: true, name, deleted: true });
83
- return;
84
- }
85
- catch {
86
- sendJson(res, 200, { ok: true, name, deleted: false });
87
- return;
88
- }
89
- }
90
- sendJson(res, 405, { ok: false, error: "Method Not Allowed" });
91
- };
92
- }
93
- async function readRequestBody(req) {
94
- const chunks = [];
95
- await new Promise((resolve, reject) => {
96
- req.on("data", (chunk) => {
97
- chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
98
- });
99
- req.on("end", () => resolve());
100
- req.on("error", (err) => reject(err));
101
- });
102
- return Buffer.concat(chunks).toString("utf-8");
103
- }
@@ -1,2 +0,0 @@
1
- import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
2
- export declare function createSessionApiHandler(api: OpenClawPluginApi): (req: any, res: any) => Promise<void>;
@@ -1,207 +0,0 @@
1
- import { getWorkclawRuntime } from "../runtime.js";
2
- function sendJson(res, statusCode, payload) {
3
- res.statusCode = statusCode;
4
- res.setHeader("Content-Type", "application/json");
5
- res.end(JSON.stringify(payload));
6
- }
7
- async function readRequestBody(req) {
8
- const chunks = [];
9
- await new Promise((resolve, reject) => {
10
- req.on("data", (chunk) => {
11
- chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
12
- });
13
- req.on("end", () => resolve());
14
- req.on("error", (err) => reject(err));
15
- });
16
- return Buffer.concat(chunks).toString("utf-8");
17
- }
18
- /**
19
- * 构建会话 key
20
- * 格式: openclaw-workclaw:{accountId}:{userId}
21
- */
22
- function buildSessionKey(accountId, userId) {
23
- return `openclaw-workclaw:${accountId}:${userId}`;
24
- }
25
- /**
26
- * 解析会话 key
27
- */
28
- function parseSessionKey(sessionKey) {
29
- const parts = sessionKey.split(":");
30
- if (parts.length !== 3 || parts[0] !== "openclaw-workclaw") {
31
- return null;
32
- }
33
- return {
34
- channel: parts[0],
35
- accountId: parts[1],
36
- userId: parts[2],
37
- };
38
- }
39
- /**
40
- * 重置/开启新会话
41
- * 通过发送系统事件 /new 到指定会话
42
- */
43
- async function resetSession(sessionKey, log) {
44
- try {
45
- const runtime = getWorkclawRuntime();
46
- // 使用 system.enqueueSystemEvent 发送 /new 命令
47
- runtime.system.enqueueSystemEvent("/new", {
48
- sessionKey,
49
- contextKey: null,
50
- });
51
- log?.info?.(`[SessionAPI] Sent /new command to session: ${sessionKey}`);
52
- return {
53
- success: true,
54
- message: `Session reset command sent to ${sessionKey}`,
55
- };
56
- }
57
- catch (err) {
58
- const errorMsg = `Failed to reset session: ${String(err)}`;
59
- log?.error?.(`[SessionAPI] ${errorMsg}`);
60
- return { success: false, message: errorMsg };
61
- }
62
- }
63
- /**
64
- * 获取会话存储路径
65
- */
66
- function getSessionStorePath(agentId, log) {
67
- try {
68
- const runtime = getWorkclawRuntime();
69
- const storePath = runtime.channel.session.resolveStorePath(undefined, {
70
- agentId,
71
- });
72
- return storePath;
73
- }
74
- catch (err) {
75
- log?.error?.(`[SessionAPI] Failed to resolve store path: ${String(err)}`);
76
- return null;
77
- }
78
- }
79
- /**
80
- * 读取会话最后更新时间
81
- */
82
- async function getSessionLastUpdated(sessionKey, log) {
83
- try {
84
- const runtime = getWorkclawRuntime();
85
- const storePath = runtime.channel.session.resolveStorePath();
86
- const updatedAt = runtime.channel.session.readSessionUpdatedAt({
87
- storePath,
88
- sessionKey,
89
- });
90
- return updatedAt ?? null;
91
- }
92
- catch (err) {
93
- log?.error?.(`[SessionAPI] Failed to read session updated at: ${String(err)}`);
94
- return null;
95
- }
96
- }
97
- export function createSessionApiHandler(api) {
98
- return async (req, res) => {
99
- const method = String(req.method ?? "GET").toUpperCase();
100
- const url = new URL(req.url ?? "", "http://localhost");
101
- // 移除尾部斜杠并获取路径部分
102
- const fullPath = url.pathname.replace(/\/+$/, "");
103
- // 提取子路径(去掉 /openclaw-workclaw/sessions 前缀)
104
- const subPath = fullPath.replace(/^\/openclaw-workclaw\/sessions/, "").replace(/^\//, "") || "/";
105
- const log = {
106
- info: (msg) => api.logger?.info?.(`[SessionAPI] ${msg}`),
107
- error: (msg) => api.logger?.error?.(`[SessionAPI] ${msg}`),
108
- };
109
- log?.info?.(`[SessionAPI] ${method} ${fullPath} (subPath: ${subPath})`);
110
- // GET /sessions 或 /sessions/ - 列出会话信息
111
- if (method === "GET" && (subPath === "/" || subPath === "")) {
112
- const sessionKey = url.searchParams.get("sessionKey");
113
- if (sessionKey) {
114
- // 获取特定会话信息
115
- const parsed = parseSessionKey(sessionKey);
116
- const updatedAt = await getSessionLastUpdated(sessionKey, log);
117
- sendJson(res, 200, {
118
- ok: true,
119
- session: {
120
- sessionKey,
121
- parsed,
122
- lastUpdatedAt: updatedAt,
123
- lastUpdatedAtFormatted: updatedAt
124
- ? new Date(updatedAt).toISOString()
125
- : null,
126
- },
127
- });
128
- return;
129
- }
130
- // 返回 API 信息
131
- sendJson(res, 200, {
132
- ok: true,
133
- message: "Session Management API",
134
- endpoints: {
135
- "GET /sessions": "获取会话信息 (可选参数: sessionKey)",
136
- "POST /sessions/reset": "重置/开启新会话 (参数: accountId + userId 或直接提供 sessionKey)",
137
- "GET /sessions/store-path": "获取会话存储路径 (可选参数: agentId)",
138
- },
139
- });
140
- return;
141
- }
142
- // POST /sessions/reset - 重置会话
143
- if (method === "POST" && subPath === "reset") {
144
- const raw = await readRequestBody(req);
145
- let input = {};
146
- try {
147
- input = raw ? JSON.parse(raw) : {};
148
- }
149
- catch {
150
- sendJson(res, 400, { ok: false, error: "Invalid JSON" });
151
- return;
152
- }
153
- const { accountId, userId, sessionKey: directSessionKey } = input;
154
- let sessionKey;
155
- if (directSessionKey) {
156
- sessionKey = directSessionKey;
157
- }
158
- else if (accountId && userId) {
159
- sessionKey = buildSessionKey(accountId, userId);
160
- }
161
- else {
162
- sendJson(res, 400, {
163
- ok: false,
164
- error: "Missing required fields: either provide 'sessionKey' or both 'accountId' and 'userId'",
165
- });
166
- return;
167
- }
168
- const result = await resetSession(sessionKey, log);
169
- if (result.success) {
170
- sendJson(res, 200, {
171
- ok: true,
172
- message: result.message,
173
- sessionKey,
174
- });
175
- }
176
- else {
177
- sendJson(res, 500, {
178
- ok: false,
179
- error: result.message,
180
- sessionKey,
181
- });
182
- }
183
- return;
184
- }
185
- // GET /sessions/store-path - 获取会话存储路径
186
- if (method === "GET" && subPath === "store-path") {
187
- const agentId = url.searchParams.get("agentId") ?? undefined;
188
- const storePath = getSessionStorePath(agentId, log);
189
- if (storePath) {
190
- sendJson(res, 200, {
191
- ok: true,
192
- storePath,
193
- agentId: agentId ?? "default",
194
- });
195
- }
196
- else {
197
- sendJson(res, 500, {
198
- ok: false,
199
- error: "Failed to resolve session store path",
200
- });
201
- }
202
- return;
203
- }
204
- // 404
205
- sendJson(res, 404, { ok: false, error: "Not Found" });
206
- };
207
- }
@@ -1,2 +0,0 @@
1
- import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
2
- export declare function createSkillsApiHandler(api: OpenClawPluginApi): (req: any, res: any) => Promise<void>;
@@ -1,64 +0,0 @@
1
- import { exec } from "node:child_process";
2
- import { promisify } from "node:util";
3
- const execAsync = promisify(exec);
4
- function sendJson(res, statusCode, payload) {
5
- res.statusCode = statusCode;
6
- res.setHeader("Content-Type", "application/json");
7
- res.end(JSON.stringify(payload));
8
- }
9
- export function createSkillsApiHandler(api) {
10
- return async (req, res) => {
11
- const method = String(req.method ?? "GET").toUpperCase();
12
- if (method === "GET") {
13
- try {
14
- // 调用 openclaw skills list 命令
15
- const { stdout, stderr } = await execAsync("openclaw skills list --json", {
16
- timeout: 10000, // 10秒超时
17
- });
18
- if (stderr && !stdout) {
19
- api.logger.error(`Skills list error: ${stderr}`);
20
- sendJson(res, 500, { ok: false, error: "Failed to list skills" });
21
- return;
22
- }
23
- // 尝试解析JSON输出
24
- let skillsData;
25
- try {
26
- skillsData = JSON.parse(stdout);
27
- }
28
- catch {
29
- // 如果不支持--json输出,尝试解析文本输出
30
- const lines = stdout.split('\n');
31
- const skills = lines
32
- .filter((line) => line.trim() && !line.includes('Skills'))
33
- .map((line) => {
34
- const parts = line.split(/\s{2,}/).map((p) => p.trim());
35
- if (parts.length >= 3) {
36
- return {
37
- status: parts[0]?.includes('✓') ? 'ready' : 'missing',
38
- name: parts[1],
39
- description: parts[2],
40
- source: parts[3] || 'openclaw-bundled'
41
- };
42
- }
43
- return null;
44
- })
45
- .filter((s) => s !== null);
46
- skillsData = {
47
- total: skills.length,
48
- ready: skills.filter((s) => s.status === 'ready').length,
49
- missing: skills.filter((s) => s.status === 'missing').length,
50
- skills
51
- };
52
- }
53
- sendJson(res, 200, { ok: true, ...skillsData });
54
- return;
55
- }
56
- catch (error) {
57
- api.logger.error(`Skills API error: ${error.message}`);
58
- sendJson(res, 500, { ok: false, error: error.message });
59
- return;
60
- }
61
- }
62
- sendJson(res, 405, { ok: false, error: "Method Not Allowed" });
63
- };
64
- }
@@ -1,3 +0,0 @@
1
- import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
2
- export declare function resolveWorkspaceDir(api: OpenClawPluginApi): string;
3
- export declare function isDefaultWorkspace(api: OpenClawPluginApi): boolean;
@@ -1,30 +0,0 @@
1
- import os from "node:os";
2
- import path from "node:path";
3
- import { getWorkclawLogger } from "../runtime.js";
4
- export function resolveWorkspaceDir(api) {
5
- const agents = api.config.agents?.list ?? [];
6
- const defaultAgent = agents.find((agent) => agent?.default === true) ??
7
- agents.find((agent) => String(agent?.id ?? "").toLowerCase() === "main");
8
- const workspaceRaw = (typeof defaultAgent?.workspace === "string" && defaultAgent.workspace.trim()) ||
9
- (typeof api.config.agents?.defaults?.workspace === "string" &&
10
- api.config.agents.defaults.workspace.trim());
11
- getWorkclawLogger().info(`workspaceRaw: ${workspaceRaw}`);
12
- if (workspaceRaw) {
13
- return api.resolvePath(workspaceRaw);
14
- }
15
- const profile = process.env.OPENCLAW_PROFILE?.trim();
16
- const suffix = profile && profile.toLowerCase() !== "default" ? `workspace-${profile}` : "workspace";
17
- return path.join(os.homedir(), ".openclaw", suffix);
18
- }
19
- export function isDefaultWorkspace(api) {
20
- const agents = api.config.agents?.list ?? [];
21
- const defaultAgent = agents.find((agent) => agent?.default === true) ??
22
- agents.find((agent) => String(agent?.id ?? "").toLowerCase() === "main");
23
- const workspaceRaw = (typeof defaultAgent?.workspace === "string" && defaultAgent.workspace.trim()) ||
24
- (typeof api.config.agents?.defaults?.workspace === "string" &&
25
- api.config.agents.defaults.workspace.trim());
26
- if (workspaceRaw)
27
- return false;
28
- const profile = process.env.OPENCLAW_PROFILE?.trim();
29
- return !profile || profile.toLowerCase() === "default";
30
- }
@@ -1,11 +0,0 @@
1
- import type { ChannelPlugin } from "openclaw/plugin-sdk";
2
- import type { ResolvedWorkclawAccount } from "./types.js";
3
- export declare const workclawDock: {
4
- id: string;
5
- capabilities: {
6
- chatTypes: string[];
7
- media: boolean;
8
- blockStreaming: boolean;
9
- };
10
- };
11
- export declare const workclawPlugin: ChannelPlugin<ResolvedWorkclawAccount>;