@chrysb/alphaclaw 0.9.30 → 0.9.31
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.
|
@@ -14,6 +14,7 @@ const { registerWebhookRoutes } = require("../routes/webhooks");
|
|
|
14
14
|
const { registerWatchdogRoutes } = require("../routes/watchdog");
|
|
15
15
|
const { registerUsageRoutes } = require("../routes/usage");
|
|
16
16
|
const { registerGmailRoutes } = require("../routes/gmail");
|
|
17
|
+
const { ensureWebhookMappingIds } = require("../webhooks");
|
|
17
18
|
const { registerDoctorRoutes } = require("../routes/doctor");
|
|
18
19
|
const { registerAgentRoutes } = require("../routes/agents");
|
|
19
20
|
const { registerCronRoutes } = require("../routes/cron");
|
|
@@ -178,6 +179,7 @@ const registerServerRoutes = ({
|
|
|
178
179
|
runOnboardedBootSequence({
|
|
179
180
|
ensureManagedExecDefaults,
|
|
180
181
|
ensureUsageTrackerPluginConfig,
|
|
182
|
+
ensureWebhookMappingIds: () => ensureWebhookMappingIds({ fs, constants }),
|
|
181
183
|
doSyncPromptFiles,
|
|
182
184
|
reloadEnv,
|
|
183
185
|
syncChannelConfig,
|
package/lib/server/startup.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const runOnboardedBootSequence = ({
|
|
2
2
|
ensureManagedExecDefaults,
|
|
3
3
|
ensureUsageTrackerPluginConfig,
|
|
4
|
+
ensureWebhookMappingIds,
|
|
4
5
|
doSyncPromptFiles,
|
|
5
6
|
reloadEnv,
|
|
6
7
|
syncChannelConfig,
|
|
@@ -25,6 +26,18 @@ const runOnboardedBootSequence = ({
|
|
|
25
26
|
`[alphaclaw] Failed to ensure usage-tracker plugin config on boot: ${error.message}`,
|
|
26
27
|
);
|
|
27
28
|
}
|
|
29
|
+
try {
|
|
30
|
+
const result = ensureWebhookMappingIds();
|
|
31
|
+
if (result?.changed) {
|
|
32
|
+
console.log(
|
|
33
|
+
`[alphaclaw] Added IDs to webhook mappings: ${result.updatedIds.join(", ")}`,
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
} catch (error) {
|
|
37
|
+
console.error(
|
|
38
|
+
`[alphaclaw] Failed to ensure webhook mapping IDs on boot: ${error.message}`,
|
|
39
|
+
);
|
|
40
|
+
}
|
|
28
41
|
doSyncPromptFiles();
|
|
29
42
|
reloadEnv();
|
|
30
43
|
syncChannelConfig(readEnvFile());
|
package/lib/server/webhooks.js
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
const path = require("path");
|
|
2
|
+
const {
|
|
3
|
+
readOpenclawConfig,
|
|
4
|
+
resolveOpenclawConfigPath,
|
|
5
|
+
} = require("./openclaw-config");
|
|
2
6
|
|
|
3
7
|
const kNamePattern = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
4
8
|
const kTransformsDir = "hooks/transforms";
|
|
@@ -12,11 +16,16 @@ const kManagedWebhookConfigs = [
|
|
|
12
16
|
];
|
|
13
17
|
|
|
14
18
|
const getConfigPath = ({ OPENCLAW_DIR }) =>
|
|
15
|
-
|
|
19
|
+
resolveOpenclawConfigPath({ openclawDir: OPENCLAW_DIR });
|
|
16
20
|
|
|
17
21
|
const readConfig = ({ fs, constants }) => {
|
|
18
22
|
const configPath = getConfigPath(constants);
|
|
19
|
-
const cfg =
|
|
23
|
+
const cfg = readOpenclawConfig({
|
|
24
|
+
fsModule: fs,
|
|
25
|
+
openclawDir: constants.OPENCLAW_DIR,
|
|
26
|
+
fallback: null,
|
|
27
|
+
});
|
|
28
|
+
if (!cfg) throw new Error("Could not read openclaw.json");
|
|
20
29
|
return { cfg, configPath };
|
|
21
30
|
};
|
|
22
31
|
|
|
@@ -78,6 +87,32 @@ const ensureHooksRoot = (cfg) => {
|
|
|
78
87
|
|
|
79
88
|
const getMappingHookName = (mapping) =>
|
|
80
89
|
String(mapping?.match?.path || "").trim();
|
|
90
|
+
const normalizeMappingIdPart = (value) =>
|
|
91
|
+
String(value || "")
|
|
92
|
+
.trim()
|
|
93
|
+
.toLowerCase()
|
|
94
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
95
|
+
.replace(/-+/g, "-")
|
|
96
|
+
.replace(/^-|-$/g, "");
|
|
97
|
+
const getMappingIdBase = (mapping, index) => {
|
|
98
|
+
const hookPath = normalizeMappingIdPart(getMappingHookName(mapping));
|
|
99
|
+
if (hookPath) return hookPath;
|
|
100
|
+
const name = normalizeMappingIdPart(mapping?.name);
|
|
101
|
+
if (name) return name;
|
|
102
|
+
const source = normalizeMappingIdPart(mapping?.match?.source);
|
|
103
|
+
if (source) return `source-${source}`;
|
|
104
|
+
return `mapping-${index + 1}`;
|
|
105
|
+
};
|
|
106
|
+
const reserveUniqueMappingId = (baseId, usedIds) => {
|
|
107
|
+
let candidate = baseId;
|
|
108
|
+
let suffix = 2;
|
|
109
|
+
while (usedIds.has(candidate)) {
|
|
110
|
+
candidate = `${baseId}-${suffix}`;
|
|
111
|
+
suffix += 1;
|
|
112
|
+
}
|
|
113
|
+
usedIds.add(candidate);
|
|
114
|
+
return candidate;
|
|
115
|
+
};
|
|
81
116
|
const isWebhookMapping = (mapping) => !!getMappingHookName(mapping);
|
|
82
117
|
const findMappingIndexByName = (mappings, name) =>
|
|
83
118
|
mappings.findIndex((mapping) => getMappingHookName(mapping) === name);
|
|
@@ -142,6 +177,35 @@ const normalizeMappingTransformModules = (mappings) => {
|
|
|
142
177
|
return changed;
|
|
143
178
|
};
|
|
144
179
|
|
|
180
|
+
const ensureWebhookMappingIds = ({ fs, constants }) => {
|
|
181
|
+
const { cfg, configPath } = readConfig({ fs, constants });
|
|
182
|
+
const mappings = Array.isArray(cfg?.hooks?.mappings)
|
|
183
|
+
? cfg.hooks.mappings
|
|
184
|
+
: [];
|
|
185
|
+
const usedIds = new Set(
|
|
186
|
+
mappings
|
|
187
|
+
.map((mapping) => String(mapping?.id || "").trim())
|
|
188
|
+
.filter(Boolean),
|
|
189
|
+
);
|
|
190
|
+
const updatedIds = [];
|
|
191
|
+
for (const [index, mapping] of mappings.entries()) {
|
|
192
|
+
if (!mapping || typeof mapping !== "object" || Array.isArray(mapping)) {
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
if (String(mapping?.id || "").trim()) continue;
|
|
196
|
+
const id = reserveUniqueMappingId(
|
|
197
|
+
getMappingIdBase(mapping, index),
|
|
198
|
+
usedIds,
|
|
199
|
+
);
|
|
200
|
+
mapping.id = id;
|
|
201
|
+
updatedIds.push(id);
|
|
202
|
+
}
|
|
203
|
+
if (updatedIds.length > 0) {
|
|
204
|
+
writeConfig({ fs, configPath, cfg });
|
|
205
|
+
}
|
|
206
|
+
return { changed: updatedIds.length > 0, updatedIds };
|
|
207
|
+
};
|
|
208
|
+
|
|
145
209
|
const buildDefaultTransformSource = (name) => {
|
|
146
210
|
return [
|
|
147
211
|
"export default async function transform(payload, context) {",
|
|
@@ -188,6 +252,7 @@ const ensureWebhookMapping = ({ cfg, name, mapping = {} }) => {
|
|
|
188
252
|
const normalizedModulesChanged = normalizeMappingTransformModules(mappings);
|
|
189
253
|
const index = findMappingIndexByName(mappings, webhookName);
|
|
190
254
|
const defaults = {
|
|
255
|
+
id: webhookName,
|
|
191
256
|
match: { path: webhookName },
|
|
192
257
|
action: "agent",
|
|
193
258
|
name: webhookName,
|
|
@@ -198,6 +263,7 @@ const ensureWebhookMapping = ({ cfg, name, mapping = {} }) => {
|
|
|
198
263
|
mappings.push({
|
|
199
264
|
...defaults,
|
|
200
265
|
...mapping,
|
|
266
|
+
id: webhookName,
|
|
201
267
|
match: { ...defaults.match, ...(mapping.match || {}) },
|
|
202
268
|
transform: { ...defaults.transform, ...(mapping.transform || {}) },
|
|
203
269
|
});
|
|
@@ -207,6 +273,7 @@ const ensureWebhookMapping = ({ cfg, name, mapping = {} }) => {
|
|
|
207
273
|
const next = {
|
|
208
274
|
...current,
|
|
209
275
|
...mapping,
|
|
276
|
+
id: webhookName,
|
|
210
277
|
match: {
|
|
211
278
|
...(current.match || {}),
|
|
212
279
|
...(mapping.match || {}),
|
|
@@ -436,6 +503,7 @@ const updateWebhookDestination = ({ fs, constants, name, destination = null }) =
|
|
|
436
503
|
});
|
|
437
504
|
const next = {
|
|
438
505
|
...current,
|
|
506
|
+
id: webhookName,
|
|
439
507
|
deliver: true,
|
|
440
508
|
channel:
|
|
441
509
|
String(normalizedDestination?.channel || "").trim() ||
|
|
@@ -499,6 +567,7 @@ const deleteWebhook = ({ fs, constants, name, deleteTransformDir = false }) => {
|
|
|
499
567
|
};
|
|
500
568
|
|
|
501
569
|
module.exports = {
|
|
570
|
+
ensureWebhookMappingIds,
|
|
502
571
|
listWebhooks,
|
|
503
572
|
getWebhookDetail,
|
|
504
573
|
createWebhook,
|