opentool 0.8.27 → 0.8.28
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 +14 -0
- package/dist/cli/index.d.ts +2 -2
- package/dist/cli/index.js +95 -12
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +95 -12
- package/dist/index.js.map +1 -1
- package/dist/{validate-C4a9tmrQ.d.ts → validate-3WEA0Ezt.d.ts} +7 -1
- package/package.json +2 -2
- package/templates/base/package.json +1 -1
package/README.md
CHANGED
|
@@ -74,6 +74,10 @@ For private tools, say for internal trading apps:
|
|
|
74
74
|
- GET-only (scheduled default profile)
|
|
75
75
|
- POST-only (one-off, parameterized with Zod)
|
|
76
76
|
- `profile.category` defaults to `tracker` if omitted; set to `strategy` or `orchestrator` for PnL/automation tools.
|
|
77
|
+
- Strategy tools must define `profile.templatePreview` with:
|
|
78
|
+
- `subtitle` (required short line)
|
|
79
|
+
- `description` (required multi-line summary, 3-8 non-empty lines; target ~5)
|
|
80
|
+
- `title` is optional and defaults to the tool name when omitted.
|
|
77
81
|
|
|
78
82
|
GET-only (scheduled default)
|
|
79
83
|
|
|
@@ -83,6 +87,16 @@ export const profile = {
|
|
|
83
87
|
description: "Stake 100 USDC daily at 12:00 UTC",
|
|
84
88
|
category: "strategy",
|
|
85
89
|
schedule: { cron: "0 12 * * *", enabled: false },
|
|
90
|
+
templatePreview: {
|
|
91
|
+
subtitle: "Automated daily staking strategy",
|
|
92
|
+
description: [
|
|
93
|
+
"Runs once per day on your configured schedule.",
|
|
94
|
+
"Uses fixed, explicit sizing controls from template config.",
|
|
95
|
+
"Designed for long-running automated execution.",
|
|
96
|
+
"Keeps logic deterministic and easy to audit.",
|
|
97
|
+
"Best for hands-off recurring onchain actions.",
|
|
98
|
+
].join("\\n"),
|
|
99
|
+
},
|
|
86
100
|
};
|
|
87
101
|
|
|
88
102
|
export async function GET(_req: Request) {
|
package/dist/cli/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { M as Metadata, I as InternalToolDefinition } from '../validate-
|
|
3
|
-
export { G as GenerateMetadataOptions, a as GenerateMetadataResult, V as ValidateOptions, b as generateMetadata, g as generateMetadataCommand, l as loadAndValidateTools, v as validateCommand, c as validateFullCommand } from '../validate-
|
|
2
|
+
import { M as Metadata, I as InternalToolDefinition } from '../validate-3WEA0Ezt.js';
|
|
3
|
+
export { G as GenerateMetadataOptions, a as GenerateMetadataResult, V as ValidateOptions, b as generateMetadata, g as generateMetadataCommand, l as loadAndValidateTools, v as validateCommand, c as validateFullCommand } from '../validate-3WEA0Ezt.js';
|
|
4
4
|
import 'zod';
|
|
5
5
|
import '../x402/index.js';
|
|
6
6
|
import 'viem';
|
package/dist/cli/index.js
CHANGED
|
@@ -1002,6 +1002,11 @@ var SUPPORTED_EXTENSIONS = [
|
|
|
1002
1002
|
".cjs"
|
|
1003
1003
|
];
|
|
1004
1004
|
var MIN_TEMPLATE_CONFIG_VERSION = 2;
|
|
1005
|
+
var TEMPLATE_PREVIEW_TITLE_MAX = 80;
|
|
1006
|
+
var TEMPLATE_PREVIEW_SUBTITLE_MAX = 120;
|
|
1007
|
+
var TEMPLATE_PREVIEW_DESCRIPTION_MAX = 1200;
|
|
1008
|
+
var TEMPLATE_PREVIEW_MIN_LINES = 3;
|
|
1009
|
+
var TEMPLATE_PREVIEW_MAX_LINES = 8;
|
|
1005
1010
|
function normalizeTemplateConfigVersion(value) {
|
|
1006
1011
|
if (typeof value === "number" && Number.isFinite(value)) {
|
|
1007
1012
|
return value;
|
|
@@ -1024,6 +1029,67 @@ function normalizeTemplateConfigVersion(value) {
|
|
|
1024
1029
|
const major = Number.parseInt(majorMatch[1], 10);
|
|
1025
1030
|
return Number.isFinite(major) ? major : null;
|
|
1026
1031
|
}
|
|
1032
|
+
function parseNonEmptyString(value, fieldPath, opts = {}) {
|
|
1033
|
+
const { max, required = false } = opts;
|
|
1034
|
+
if (value == null) {
|
|
1035
|
+
if (required) {
|
|
1036
|
+
throw new Error(`${fieldPath} is required and must be a non-empty string.`);
|
|
1037
|
+
}
|
|
1038
|
+
return null;
|
|
1039
|
+
}
|
|
1040
|
+
if (typeof value !== "string") {
|
|
1041
|
+
throw new Error(`${fieldPath} must be a string.`);
|
|
1042
|
+
}
|
|
1043
|
+
const trimmed = value.trim();
|
|
1044
|
+
if (!trimmed) {
|
|
1045
|
+
throw new Error(`${fieldPath} must be a non-empty string.`);
|
|
1046
|
+
}
|
|
1047
|
+
if (typeof max === "number" && trimmed.length > max) {
|
|
1048
|
+
throw new Error(`${fieldPath} must be <= ${max} characters.`);
|
|
1049
|
+
}
|
|
1050
|
+
return trimmed;
|
|
1051
|
+
}
|
|
1052
|
+
function normalizeTemplatePreview(value, file, toolName, requirePreview) {
|
|
1053
|
+
const pathPrefix = `${file}: profile.templatePreview`;
|
|
1054
|
+
if (value == null) {
|
|
1055
|
+
if (requirePreview) {
|
|
1056
|
+
throw new Error(
|
|
1057
|
+
`${pathPrefix} is required for strategy tools and must define subtitle + description.`
|
|
1058
|
+
);
|
|
1059
|
+
}
|
|
1060
|
+
return null;
|
|
1061
|
+
}
|
|
1062
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
1063
|
+
throw new Error(`${pathPrefix} must be an object.`);
|
|
1064
|
+
}
|
|
1065
|
+
const record = value;
|
|
1066
|
+
const title = parseNonEmptyString(record.title, `${pathPrefix}.title`, {
|
|
1067
|
+
max: TEMPLATE_PREVIEW_TITLE_MAX
|
|
1068
|
+
}) ?? toolName;
|
|
1069
|
+
const subtitle = parseNonEmptyString(record.subtitle, `${pathPrefix}.subtitle`, {
|
|
1070
|
+
required: true,
|
|
1071
|
+
max: TEMPLATE_PREVIEW_SUBTITLE_MAX
|
|
1072
|
+
});
|
|
1073
|
+
const description = parseNonEmptyString(
|
|
1074
|
+
record.description,
|
|
1075
|
+
`${pathPrefix}.description`,
|
|
1076
|
+
{
|
|
1077
|
+
required: true,
|
|
1078
|
+
max: TEMPLATE_PREVIEW_DESCRIPTION_MAX
|
|
1079
|
+
}
|
|
1080
|
+
);
|
|
1081
|
+
const descriptionLineCount = description.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0).length;
|
|
1082
|
+
if (descriptionLineCount < TEMPLATE_PREVIEW_MIN_LINES || descriptionLineCount > TEMPLATE_PREVIEW_MAX_LINES) {
|
|
1083
|
+
throw new Error(
|
|
1084
|
+
`${pathPrefix}.description must contain ${TEMPLATE_PREVIEW_MIN_LINES}-${TEMPLATE_PREVIEW_MAX_LINES} non-empty lines (target ~5 lines).`
|
|
1085
|
+
);
|
|
1086
|
+
}
|
|
1087
|
+
return {
|
|
1088
|
+
title,
|
|
1089
|
+
subtitle,
|
|
1090
|
+
description
|
|
1091
|
+
};
|
|
1092
|
+
}
|
|
1027
1093
|
async function validateCommand(options) {
|
|
1028
1094
|
console.log("\u{1F50D} Validating OpenTool metadata...");
|
|
1029
1095
|
try {
|
|
@@ -1135,16 +1201,26 @@ async function loadAndValidateTools(toolsDir, options = {}) {
|
|
|
1135
1201
|
throw new Error(`${file}: export exactly one of GET or POST`);
|
|
1136
1202
|
}
|
|
1137
1203
|
let normalizedSchedule = null;
|
|
1138
|
-
const
|
|
1139
|
-
const
|
|
1140
|
-
const
|
|
1141
|
-
const allowedProfileCategories =
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1204
|
+
const profileRaw = toolModule?.profile && typeof toolModule.profile === "object" ? toolModule.profile : null;
|
|
1205
|
+
const schedule = profileRaw?.schedule ?? null;
|
|
1206
|
+
const profileNotifyEmail = typeof profileRaw?.notifyEmail === "boolean" ? profileRaw.notifyEmail : void 0;
|
|
1207
|
+
const allowedProfileCategories = [
|
|
1208
|
+
"strategy",
|
|
1209
|
+
"tracker",
|
|
1210
|
+
"orchestrator"
|
|
1211
|
+
];
|
|
1212
|
+
const profileCategoryCandidate = typeof profileRaw?.category === "string" ? profileRaw.category : void 0;
|
|
1213
|
+
let profileCategoryRaw;
|
|
1214
|
+
if (profileCategoryCandidate !== void 0) {
|
|
1215
|
+
const isAllowed = allowedProfileCategories.includes(profileCategoryCandidate);
|
|
1216
|
+
if (!isAllowed) {
|
|
1217
|
+
throw new Error(
|
|
1218
|
+
`${file}: profile.category must be one of ${allowedProfileCategories.join(", ")}`
|
|
1219
|
+
);
|
|
1220
|
+
}
|
|
1221
|
+
profileCategoryRaw = profileCategoryCandidate;
|
|
1146
1222
|
}
|
|
1147
|
-
const profileAssetsRaw =
|
|
1223
|
+
const profileAssetsRaw = profileRaw?.assets;
|
|
1148
1224
|
if (profileAssetsRaw !== void 0) {
|
|
1149
1225
|
if (!Array.isArray(profileAssetsRaw)) {
|
|
1150
1226
|
throw new Error(`${file}: profile.assets must be an array.`);
|
|
@@ -1202,7 +1278,7 @@ async function loadAndValidateTools(toolsDir, options = {}) {
|
|
|
1202
1278
|
}
|
|
1203
1279
|
});
|
|
1204
1280
|
}
|
|
1205
|
-
const templateConfigRaw =
|
|
1281
|
+
const templateConfigRaw = profileRaw?.templateConfig;
|
|
1206
1282
|
if (templateConfigRaw !== void 0) {
|
|
1207
1283
|
if (!templateConfigRaw || typeof templateConfigRaw !== "object") {
|
|
1208
1284
|
throw new Error(`${file}: profile.templateConfig must be an object.`);
|
|
@@ -1239,6 +1315,13 @@ async function loadAndValidateTools(toolsDir, options = {}) {
|
|
|
1239
1315
|
);
|
|
1240
1316
|
}
|
|
1241
1317
|
}
|
|
1318
|
+
const normalizedTemplatePreview = normalizeTemplatePreview(
|
|
1319
|
+
profileRaw?.templatePreview,
|
|
1320
|
+
file,
|
|
1321
|
+
toolName,
|
|
1322
|
+
profileCategoryRaw === "strategy"
|
|
1323
|
+
);
|
|
1324
|
+
const normalizedProfile = profileRaw && normalizedTemplatePreview ? { ...profileRaw, templatePreview: normalizedTemplatePreview } : profileRaw;
|
|
1242
1325
|
if (hasGET && schedule && typeof schedule.cron === "string" && schedule.cron.trim().length > 0) {
|
|
1243
1326
|
normalizedSchedule = normalizeScheduleExpression(schedule.cron, file);
|
|
1244
1327
|
if (typeof schedule.enabled === "boolean") {
|
|
@@ -1308,9 +1391,9 @@ async function loadAndValidateTools(toolsDir, options = {}) {
|
|
|
1308
1391
|
handler: async (params) => adapter(params),
|
|
1309
1392
|
payment: paymentExport ?? null,
|
|
1310
1393
|
schedule: normalizedSchedule,
|
|
1311
|
-
profile:
|
|
1394
|
+
profile: normalizedProfile,
|
|
1312
1395
|
...profileNotifyEmail !== void 0 ? { notifyEmail: profileNotifyEmail } : {},
|
|
1313
|
-
profileDescription: typeof
|
|
1396
|
+
profileDescription: typeof profileRaw?.description === "string" ? profileRaw.description : null,
|
|
1314
1397
|
...profileCategoryRaw ? { profileCategory: profileCategoryRaw } : {}
|
|
1315
1398
|
};
|
|
1316
1399
|
tools.push(tool);
|