opentool 0.8.29 → 0.10.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 +11 -31
- package/dist/adapters/hyperliquid/index.d.ts +19 -1
- package/dist/adapters/hyperliquid/index.js +86 -103
- package/dist/adapters/hyperliquid/index.js.map +1 -1
- package/dist/ai/index.js +9 -22
- package/dist/ai/index.js.map +1 -1
- package/dist/cli/index.d.ts +0 -10
- package/dist/cli/index.js +52 -297
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +14 -2
- package/dist/index.js +196 -242
- package/dist/index.js.map +1 -1
- package/dist/store/index.js +7 -21
- package/dist/store/index.js.map +1 -1
- package/dist/viem/index.d.ts +1 -0
- package/dist/viem/index.js +3 -0
- package/dist/viem/index.js.map +1 -0
- package/dist/wallet/index.js +7 -37
- package/dist/wallet/index.js.map +1 -1
- package/dist/x402/index.js +12 -4
- package/dist/x402/index.js.map +1 -1
- package/package.json +26 -38
- package/templates/base/package.json +3 -3
package/dist/cli/index.js
CHANGED
|
@@ -128,10 +128,7 @@ var X402PaymentSchema = z.object({
|
|
|
128
128
|
}),
|
|
129
129
|
metadata: z.record(z.string(), z.unknown()).optional()
|
|
130
130
|
}).passthrough();
|
|
131
|
-
var PaymentConfigSchema = z.union([
|
|
132
|
-
X402PaymentSchema,
|
|
133
|
-
z.record(z.string(), z.unknown())
|
|
134
|
-
]);
|
|
131
|
+
var PaymentConfigSchema = z.union([X402PaymentSchema, z.record(z.string(), z.unknown())]);
|
|
135
132
|
var DiscoveryMetadataSchema = z.object({
|
|
136
133
|
keywords: z.array(z.string()).optional(),
|
|
137
134
|
category: z.string().optional(),
|
|
@@ -460,7 +457,7 @@ function buildDiscovery(authored) {
|
|
|
460
457
|
}
|
|
461
458
|
const merged = {
|
|
462
459
|
...legacyDiscovery,
|
|
463
|
-
...authored.discovery
|
|
460
|
+
...authored.discovery
|
|
464
461
|
};
|
|
465
462
|
return Object.keys(merged).length > 0 ? merged : void 0;
|
|
466
463
|
}
|
|
@@ -592,7 +589,10 @@ async function verifyX402Payment(attempt, definition, options = {}) {
|
|
|
592
589
|
console.log("[x402] Facilitator /verify response", { status: verifyResponse.status });
|
|
593
590
|
if (!verifyResponse.ok) {
|
|
594
591
|
const errorText = await verifyResponse.text().catch(() => "");
|
|
595
|
-
console.error("[x402] Facilitator /verify error", {
|
|
592
|
+
console.error("[x402] Facilitator /verify error", {
|
|
593
|
+
status: verifyResponse.status,
|
|
594
|
+
body: errorText
|
|
595
|
+
});
|
|
596
596
|
return {
|
|
597
597
|
success: false,
|
|
598
598
|
failure: {
|
|
@@ -640,7 +640,10 @@ async function verifyX402Payment(attempt, definition, options = {}) {
|
|
|
640
640
|
console.log("[x402] Facilitator /settle response", { status: settleResponse.status });
|
|
641
641
|
if (!settleResponse.ok) {
|
|
642
642
|
const errorText = await settleResponse.text().catch(() => "");
|
|
643
|
-
console.error("[x402] Facilitator /settle error", {
|
|
643
|
+
console.error("[x402] Facilitator /settle error", {
|
|
644
|
+
status: settleResponse.status,
|
|
645
|
+
body: errorText
|
|
646
|
+
});
|
|
644
647
|
return {
|
|
645
648
|
success: false,
|
|
646
649
|
failure: {
|
|
@@ -658,7 +661,9 @@ async function verifyX402Payment(attempt, definition, options = {}) {
|
|
|
658
661
|
});
|
|
659
662
|
}
|
|
660
663
|
} catch (error) {
|
|
661
|
-
console.error("[x402] Settlement exception", {
|
|
664
|
+
console.error("[x402] Settlement exception", {
|
|
665
|
+
error: error instanceof Error ? error.message : String(error)
|
|
666
|
+
});
|
|
662
667
|
return {
|
|
663
668
|
success: false,
|
|
664
669
|
failure: {
|
|
@@ -747,7 +752,7 @@ function ensureTrailingSlash(url) {
|
|
|
747
752
|
}
|
|
748
753
|
|
|
749
754
|
// src/x402/index.ts
|
|
750
|
-
var PAYMENT_CONTEXT_SYMBOL = Symbol.for("opentool.x402.context");
|
|
755
|
+
var PAYMENT_CONTEXT_SYMBOL = /* @__PURE__ */ Symbol.for("opentool.x402.context");
|
|
751
756
|
var X402PaymentRequiredError = class extends Error {
|
|
752
757
|
constructor(response, verification) {
|
|
753
758
|
super("X402 Payment required");
|
|
@@ -838,9 +843,7 @@ function createMcpAdapter(options) {
|
|
|
838
843
|
const defaultMethod = resolveDefaultMethod(options);
|
|
839
844
|
const httpHandler = options.httpHandlers[defaultMethod];
|
|
840
845
|
if (!httpHandler) {
|
|
841
|
-
throw new Error(
|
|
842
|
-
`Tool "${options.name}" does not export an HTTP handler for ${defaultMethod}`
|
|
843
|
-
);
|
|
846
|
+
throw new Error(`Tool "${options.name}" does not export an HTTP handler for ${defaultMethod}`);
|
|
844
847
|
}
|
|
845
848
|
return async function invoke(rawArguments) {
|
|
846
849
|
const validated = normalizedSchema ? normalizedSchema.parse(rawArguments ?? {}) : rawArguments;
|
|
@@ -948,15 +951,7 @@ async function responseToToolResponse(response) {
|
|
|
948
951
|
}
|
|
949
952
|
|
|
950
953
|
// src/types/index.ts
|
|
951
|
-
var HTTP_METHODS = [
|
|
952
|
-
"GET",
|
|
953
|
-
"HEAD",
|
|
954
|
-
"POST",
|
|
955
|
-
"PUT",
|
|
956
|
-
"DELETE",
|
|
957
|
-
"PATCH",
|
|
958
|
-
"OPTIONS"
|
|
959
|
-
];
|
|
954
|
+
var HTTP_METHODS = ["GET", "HEAD", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"];
|
|
960
955
|
|
|
961
956
|
// src/utils/schedule.ts
|
|
962
957
|
var CRON_WRAPPED_REGEX = /^cron\((.*)\)$/i;
|
|
@@ -969,7 +964,9 @@ function normalizeScheduleExpression(raw, context) {
|
|
|
969
964
|
const cronBody = extractCronBody(value);
|
|
970
965
|
const cronFields = cronBody.trim().split(/\s+/).filter(Boolean);
|
|
971
966
|
if (cronFields.length !== 5 && cronFields.length !== 6) {
|
|
972
|
-
throw new Error(
|
|
967
|
+
throw new Error(
|
|
968
|
+
`${context}: cron expression must have 5 or 6 fields (got ${cronFields.length})`
|
|
969
|
+
);
|
|
973
970
|
}
|
|
974
971
|
validateCronTokens(cronFields, context);
|
|
975
972
|
return {
|
|
@@ -993,14 +990,7 @@ function validateCronTokens(fields, context) {
|
|
|
993
990
|
}
|
|
994
991
|
|
|
995
992
|
// src/cli/validate.ts
|
|
996
|
-
var SUPPORTED_EXTENSIONS = [
|
|
997
|
-
".ts",
|
|
998
|
-
".tsx",
|
|
999
|
-
".js",
|
|
1000
|
-
".jsx",
|
|
1001
|
-
".mjs",
|
|
1002
|
-
".cjs"
|
|
1003
|
-
];
|
|
993
|
+
var SUPPORTED_EXTENSIONS = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
|
|
1004
994
|
var MIN_TEMPLATE_CONFIG_VERSION = 2;
|
|
1005
995
|
var TEMPLATE_PREVIEW_TITLE_MAX = 80;
|
|
1006
996
|
var TEMPLATE_PREVIEW_SUBTITLE_MAX = 120;
|
|
@@ -1070,14 +1060,10 @@ function normalizeTemplatePreview(value, file, toolName, requirePreview) {
|
|
|
1070
1060
|
required: true,
|
|
1071
1061
|
max: TEMPLATE_PREVIEW_SUBTITLE_MAX
|
|
1072
1062
|
});
|
|
1073
|
-
const description = parseNonEmptyString(
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
required: true,
|
|
1078
|
-
max: TEMPLATE_PREVIEW_DESCRIPTION_MAX
|
|
1079
|
-
}
|
|
1080
|
-
);
|
|
1063
|
+
const description = parseNonEmptyString(record.description, `${pathPrefix}.description`, {
|
|
1064
|
+
required: true,
|
|
1065
|
+
max: TEMPLATE_PREVIEW_DESCRIPTION_MAX
|
|
1066
|
+
});
|
|
1081
1067
|
const descriptionLineCount = description.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0).length;
|
|
1082
1068
|
if (descriptionLineCount < TEMPLATE_PREVIEW_MIN_LINES || descriptionLineCount > TEMPLATE_PREVIEW_MAX_LINES) {
|
|
1083
1069
|
throw new Error(
|
|
@@ -1204,15 +1190,13 @@ async function loadAndValidateTools(toolsDir, options = {}) {
|
|
|
1204
1190
|
const profileRaw = toolModule?.profile && typeof toolModule.profile === "object" ? toolModule.profile : null;
|
|
1205
1191
|
const schedule = profileRaw?.schedule ?? null;
|
|
1206
1192
|
const profileNotifyEmail = typeof profileRaw?.notifyEmail === "boolean" ? profileRaw.notifyEmail : void 0;
|
|
1207
|
-
const allowedProfileCategories = [
|
|
1208
|
-
"strategy",
|
|
1209
|
-
"tracker",
|
|
1210
|
-
"orchestrator"
|
|
1211
|
-
];
|
|
1193
|
+
const allowedProfileCategories = ["strategy", "tracker", "orchestrator"];
|
|
1212
1194
|
const profileCategoryCandidate = typeof profileRaw?.category === "string" ? profileRaw.category : void 0;
|
|
1213
1195
|
let profileCategoryRaw;
|
|
1214
1196
|
if (profileCategoryCandidate !== void 0) {
|
|
1215
|
-
const isAllowed = allowedProfileCategories.includes(
|
|
1197
|
+
const isAllowed = allowedProfileCategories.includes(
|
|
1198
|
+
profileCategoryCandidate
|
|
1199
|
+
);
|
|
1216
1200
|
if (!isAllowed) {
|
|
1217
1201
|
throw new Error(
|
|
1218
1202
|
`${file}: profile.category must be one of ${allowedProfileCategories.join(", ")}`
|
|
@@ -1227,22 +1211,16 @@ async function loadAndValidateTools(toolsDir, options = {}) {
|
|
|
1227
1211
|
}
|
|
1228
1212
|
profileAssetsRaw.forEach((entry, index) => {
|
|
1229
1213
|
if (!entry || typeof entry !== "object") {
|
|
1230
|
-
throw new Error(
|
|
1231
|
-
`${file}: profile.assets[${index}] must be an object.`
|
|
1232
|
-
);
|
|
1214
|
+
throw new Error(`${file}: profile.assets[${index}] must be an object.`);
|
|
1233
1215
|
}
|
|
1234
1216
|
const record = entry;
|
|
1235
1217
|
const venue = typeof record.venue === "string" ? record.venue.trim() : "";
|
|
1236
1218
|
if (!venue) {
|
|
1237
|
-
throw new Error(
|
|
1238
|
-
`${file}: profile.assets[${index}].venue must be a non-empty string.`
|
|
1239
|
-
);
|
|
1219
|
+
throw new Error(`${file}: profile.assets[${index}].venue must be a non-empty string.`);
|
|
1240
1220
|
}
|
|
1241
1221
|
const chain = record.chain;
|
|
1242
1222
|
if (typeof chain !== "string" && typeof chain !== "number") {
|
|
1243
|
-
throw new Error(
|
|
1244
|
-
`${file}: profile.assets[${index}].chain must be a string or number.`
|
|
1245
|
-
);
|
|
1223
|
+
throw new Error(`${file}: profile.assets[${index}].chain must be a string or number.`);
|
|
1246
1224
|
}
|
|
1247
1225
|
const symbols = record.assetSymbols;
|
|
1248
1226
|
if (!Array.isArray(symbols) || symbols.length === 0) {
|
|
@@ -1336,14 +1314,14 @@ async function loadAndValidateTools(toolsDir, options = {}) {
|
|
|
1336
1314
|
throw new Error(`${file}: POST tools must export a Zod schema as 'schema'`);
|
|
1337
1315
|
}
|
|
1338
1316
|
if (schedule && typeof schedule.cron === "string") {
|
|
1339
|
-
throw new Error(
|
|
1317
|
+
throw new Error(
|
|
1318
|
+
`${file}: POST tools must not define profile.schedule; use GET + cron for scheduled tasks.`
|
|
1319
|
+
);
|
|
1340
1320
|
}
|
|
1341
1321
|
}
|
|
1342
1322
|
const httpHandlers = [...httpHandlersRaw];
|
|
1343
1323
|
if (httpHandlers.length === 0) {
|
|
1344
|
-
throw new Error(
|
|
1345
|
-
`${file} must export at least one HTTP handler (e.g. POST)`
|
|
1346
|
-
);
|
|
1324
|
+
throw new Error(`${file} must export at least one HTTP handler (e.g. POST)`);
|
|
1347
1325
|
}
|
|
1348
1326
|
if (paymentExport) {
|
|
1349
1327
|
for (let index = 0; index < httpHandlers.length; index += 1) {
|
|
@@ -1369,7 +1347,7 @@ async function loadAndValidateTools(toolsDir, options = {}) {
|
|
|
1369
1347
|
...metadataOverrides,
|
|
1370
1348
|
payment: metadataOverrides.payment ?? paymentExport,
|
|
1371
1349
|
annotations: {
|
|
1372
|
-
...metadataOverrides.annotations
|
|
1350
|
+
...metadataOverrides.annotations,
|
|
1373
1351
|
requiresPayment: metadataOverrides.annotations?.requiresPayment ?? true
|
|
1374
1352
|
}
|
|
1375
1353
|
};
|
|
@@ -1625,10 +1603,6 @@ async function buildProject(options) {
|
|
|
1625
1603
|
compiledTools,
|
|
1626
1604
|
outputDir
|
|
1627
1605
|
});
|
|
1628
|
-
const workflowBundles = await buildWorkflowsIfPresent({
|
|
1629
|
-
projectRoot,
|
|
1630
|
-
outputDir
|
|
1631
|
-
});
|
|
1632
1606
|
const shouldBuildMcpServer = compiledTools.some((artifact) => artifact.mcpEnabled);
|
|
1633
1607
|
if (shouldBuildMcpServer) {
|
|
1634
1608
|
await writeMcpServer({
|
|
@@ -1647,7 +1621,6 @@ async function buildProject(options) {
|
|
|
1647
1621
|
defaultsApplied,
|
|
1648
1622
|
tools,
|
|
1649
1623
|
compiledTools,
|
|
1650
|
-
workflowBundles,
|
|
1651
1624
|
toolsManifestPath,
|
|
1652
1625
|
sharedModules
|
|
1653
1626
|
};
|
|
@@ -1836,19 +1809,12 @@ async function writeMcpServer(options) {
|
|
|
1836
1809
|
}
|
|
1837
1810
|
function writeToolsManifest(options) {
|
|
1838
1811
|
const manifestPath = path6.join(options.outputDir, "tools.json");
|
|
1839
|
-
const legacyManifestPath = path6.join(
|
|
1840
|
-
options.outputDir,
|
|
1841
|
-
".well-known",
|
|
1842
|
-
"opentool",
|
|
1843
|
-
"cron.json"
|
|
1844
|
-
);
|
|
1812
|
+
const legacyManifestPath = path6.join(options.outputDir, ".well-known", "opentool", "cron.json");
|
|
1845
1813
|
if (fs4.existsSync(legacyManifestPath)) {
|
|
1846
1814
|
fs4.rmSync(legacyManifestPath, { force: true });
|
|
1847
1815
|
}
|
|
1848
1816
|
const entries = options.tools.map((tool) => {
|
|
1849
|
-
const compiled = options.compiledTools.find(
|
|
1850
|
-
(artifact) => artifact.filename === tool.filename
|
|
1851
|
-
);
|
|
1817
|
+
const compiled = options.compiledTools.find((artifact) => artifact.filename === tool.filename);
|
|
1852
1818
|
if (!compiled) {
|
|
1853
1819
|
throw new Error(`Internal error: missing compiled artifact for ${tool.filename}`);
|
|
1854
1820
|
}
|
|
@@ -1898,18 +1864,6 @@ function logBuildSummary(artifacts, options) {
|
|
|
1898
1864
|
if (artifacts.toolsManifestPath) {
|
|
1899
1865
|
console.log(" \u2022 tools.json (runtime tool manifest)");
|
|
1900
1866
|
}
|
|
1901
|
-
if (artifacts.workflowBundles) {
|
|
1902
|
-
console.log(" \u2022 .well-known/workflow/v1/ (workflow bundles)");
|
|
1903
|
-
console.log(" - flow.js");
|
|
1904
|
-
console.log(" - step.js");
|
|
1905
|
-
console.log(" - webhook.js");
|
|
1906
|
-
if (artifacts.workflowBundles.clientBundlePath) {
|
|
1907
|
-
console.log(" - client.js");
|
|
1908
|
-
}
|
|
1909
|
-
if (artifacts.workflowBundles.manifestPath) {
|
|
1910
|
-
console.log(" - manifest.json");
|
|
1911
|
-
}
|
|
1912
|
-
}
|
|
1913
1867
|
if (artifacts.defaultsApplied.length > 0) {
|
|
1914
1868
|
console.log("\nDefaults applied during metadata synthesis:");
|
|
1915
1869
|
artifacts.defaultsApplied.forEach((entry) => console.log(` \u2022 ${entry}`));
|
|
@@ -1918,183 +1872,6 @@ function logBuildSummary(artifacts, options) {
|
|
|
1918
1872
|
console.log("\n\u2139\uFE0F MCP adapter skipped (no tools opted in)");
|
|
1919
1873
|
}
|
|
1920
1874
|
}
|
|
1921
|
-
async function buildWorkflowsIfPresent(options) {
|
|
1922
|
-
const workflowsDir = options.workflowsDir ?? path6.join(options.projectRoot, "workflows");
|
|
1923
|
-
if (!fs4.existsSync(workflowsDir)) {
|
|
1924
|
-
return null;
|
|
1925
|
-
}
|
|
1926
|
-
if (!hasWorkflowSourceFiles(workflowsDir)) {
|
|
1927
|
-
return null;
|
|
1928
|
-
}
|
|
1929
|
-
const nodeVersion = process.versions?.node ?? "0.0.0";
|
|
1930
|
-
const nodeMajor = Number(nodeVersion.split(".")[0] ?? 0);
|
|
1931
|
-
if (!Number.isFinite(nodeMajor) || nodeMajor < 22) {
|
|
1932
|
-
console.warn(
|
|
1933
|
-
`[${timestamp()}] Workflow bundles skipped (requires Node >= 22, current ${nodeVersion})`
|
|
1934
|
-
);
|
|
1935
|
-
return null;
|
|
1936
|
-
}
|
|
1937
|
-
let BaseBuilder;
|
|
1938
|
-
try {
|
|
1939
|
-
({ BaseBuilder } = await import('@workflow/cli/dist/lib/builders/base-builder.js'));
|
|
1940
|
-
} catch (error) {
|
|
1941
|
-
const details = error instanceof Error ? `
|
|
1942
|
-
Reason: ${error.message}` : "";
|
|
1943
|
-
throw new Error(
|
|
1944
|
-
`[${timestamp()}] Workflow sources detected, but optional dependency '@workflow/cli' is not installed. Install it with "npm install @workflow/cli" (or add it to devDependencies) and rerun the build.` + details
|
|
1945
|
-
);
|
|
1946
|
-
}
|
|
1947
|
-
class OpenToolWorkflowBuilder extends BaseBuilder {
|
|
1948
|
-
constructor(config) {
|
|
1949
|
-
super(config);
|
|
1950
|
-
}
|
|
1951
|
-
async build() {
|
|
1952
|
-
const inputFiles = await this.getInputFiles();
|
|
1953
|
-
const tsConfig = await this.getTsConfigOptions();
|
|
1954
|
-
const shared = {
|
|
1955
|
-
inputFiles,
|
|
1956
|
-
...tsConfig.baseUrl ? { tsBaseUrl: tsConfig.baseUrl } : {},
|
|
1957
|
-
...tsConfig.paths ? { tsPaths: tsConfig.paths } : {}
|
|
1958
|
-
};
|
|
1959
|
-
await this.buildStepsBundle(shared);
|
|
1960
|
-
await this.buildWorkflowsBundle(shared);
|
|
1961
|
-
await this.buildWebhookRoute();
|
|
1962
|
-
await this.buildClientLibrary();
|
|
1963
|
-
}
|
|
1964
|
-
async buildStepsBundle(options2) {
|
|
1965
|
-
console.log(
|
|
1966
|
-
"Creating OpenTool workflow steps bundle at",
|
|
1967
|
-
this.config.stepsBundlePath
|
|
1968
|
-
);
|
|
1969
|
-
const stepsBundlePath2 = path6.resolve(
|
|
1970
|
-
this.config.workingDir,
|
|
1971
|
-
this.config.stepsBundlePath
|
|
1972
|
-
);
|
|
1973
|
-
await fs4.promises.mkdir(path6.dirname(stepsBundlePath2), { recursive: true });
|
|
1974
|
-
await this.createStepsBundle({
|
|
1975
|
-
outfile: stepsBundlePath2,
|
|
1976
|
-
...options2
|
|
1977
|
-
});
|
|
1978
|
-
}
|
|
1979
|
-
async buildWorkflowsBundle(options2) {
|
|
1980
|
-
console.log(
|
|
1981
|
-
"Creating OpenTool workflow bundle at",
|
|
1982
|
-
this.config.workflowsBundlePath
|
|
1983
|
-
);
|
|
1984
|
-
const workflowBundlePath = path6.resolve(
|
|
1985
|
-
this.config.workingDir,
|
|
1986
|
-
this.config.workflowsBundlePath
|
|
1987
|
-
);
|
|
1988
|
-
await fs4.promises.mkdir(path6.dirname(workflowBundlePath), {
|
|
1989
|
-
recursive: true
|
|
1990
|
-
});
|
|
1991
|
-
await this.createWorkflowsBundle({
|
|
1992
|
-
outfile: workflowBundlePath,
|
|
1993
|
-
bundleFinalOutput: false,
|
|
1994
|
-
...options2
|
|
1995
|
-
});
|
|
1996
|
-
}
|
|
1997
|
-
async buildWebhookRoute() {
|
|
1998
|
-
console.log(
|
|
1999
|
-
"Creating OpenTool workflow webhook bundle at",
|
|
2000
|
-
this.config.webhookBundlePath
|
|
2001
|
-
);
|
|
2002
|
-
const webhookBundlePath2 = path6.resolve(
|
|
2003
|
-
this.config.workingDir,
|
|
2004
|
-
this.config.webhookBundlePath
|
|
2005
|
-
);
|
|
2006
|
-
await fs4.promises.mkdir(path6.dirname(webhookBundlePath2), {
|
|
2007
|
-
recursive: true
|
|
2008
|
-
});
|
|
2009
|
-
await this.createWebhookBundle({ outfile: webhookBundlePath2 });
|
|
2010
|
-
}
|
|
2011
|
-
async buildClientLibrary() {
|
|
2012
|
-
if (!this.config?.clientBundlePath) {
|
|
2013
|
-
return;
|
|
2014
|
-
}
|
|
2015
|
-
const clientBundlePath2 = path6.resolve(
|
|
2016
|
-
this.config.workingDir,
|
|
2017
|
-
this.config.clientBundlePath
|
|
2018
|
-
);
|
|
2019
|
-
await fs4.promises.mkdir(path6.dirname(clientBundlePath2), {
|
|
2020
|
-
recursive: true
|
|
2021
|
-
});
|
|
2022
|
-
await this.createWorkflowsBundle({
|
|
2023
|
-
outfile: clientBundlePath2,
|
|
2024
|
-
bundleFinalOutput: true
|
|
2025
|
-
});
|
|
2026
|
-
}
|
|
2027
|
-
}
|
|
2028
|
-
const relativeSourceDir = path6.relative(options.projectRoot, workflowsDir) || ".";
|
|
2029
|
-
const outputBase = path6.join(
|
|
2030
|
-
options.outputDir,
|
|
2031
|
-
".well-known",
|
|
2032
|
-
"workflow",
|
|
2033
|
-
"v1"
|
|
2034
|
-
);
|
|
2035
|
-
const stepsBundlePath = path6.join(outputBase, "step.js");
|
|
2036
|
-
const workflowsBundlePath = path6.join(outputBase, "flow.js");
|
|
2037
|
-
const webhookBundlePath = path6.join(outputBase, "webhook.js");
|
|
2038
|
-
const manifestPath = path6.join(outputBase, "manifest.json");
|
|
2039
|
-
const builder = new OpenToolWorkflowBuilder({
|
|
2040
|
-
workingDir: options.projectRoot,
|
|
2041
|
-
dirs: [relativeSourceDir],
|
|
2042
|
-
buildTarget: "standalone",
|
|
2043
|
-
stepsBundlePath,
|
|
2044
|
-
workflowsBundlePath,
|
|
2045
|
-
webhookBundlePath,
|
|
2046
|
-
...{},
|
|
2047
|
-
workflowManifestPath: manifestPath,
|
|
2048
|
-
externalPackages: [
|
|
2049
|
-
"workflow",
|
|
2050
|
-
"workflow/internal/builtins",
|
|
2051
|
-
"workflow/internal/private",
|
|
2052
|
-
"workflow/runtime",
|
|
2053
|
-
"workflow/api"
|
|
2054
|
-
]
|
|
2055
|
-
});
|
|
2056
|
-
console.log(
|
|
2057
|
-
`[${timestamp()}] Building workflows from ${workflowsDir} -> ${outputBase}`
|
|
2058
|
-
);
|
|
2059
|
-
await builder.build();
|
|
2060
|
-
return {
|
|
2061
|
-
sourceDir: workflowsDir,
|
|
2062
|
-
outputDir: outputBase,
|
|
2063
|
-
stepsBundlePath,
|
|
2064
|
-
workflowsBundlePath,
|
|
2065
|
-
webhookBundlePath,
|
|
2066
|
-
...{},
|
|
2067
|
-
manifestPath
|
|
2068
|
-
};
|
|
2069
|
-
}
|
|
2070
|
-
function hasWorkflowSourceFiles(directory) {
|
|
2071
|
-
const entries = fs4.readdirSync(directory, { withFileTypes: true });
|
|
2072
|
-
for (const entry of entries) {
|
|
2073
|
-
if (entry.isDirectory()) {
|
|
2074
|
-
if (hasWorkflowSourceFiles(path6.join(directory, entry.name))) {
|
|
2075
|
-
return true;
|
|
2076
|
-
}
|
|
2077
|
-
continue;
|
|
2078
|
-
}
|
|
2079
|
-
if (entry.isFile()) {
|
|
2080
|
-
const extension = path6.extname(entry.name).toLowerCase();
|
|
2081
|
-
if (WORKFLOW_SOURCE_EXTENSIONS.has(extension)) {
|
|
2082
|
-
return true;
|
|
2083
|
-
}
|
|
2084
|
-
}
|
|
2085
|
-
}
|
|
2086
|
-
return false;
|
|
2087
|
-
}
|
|
2088
|
-
var WORKFLOW_SOURCE_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
2089
|
-
".ts",
|
|
2090
|
-
".tsx",
|
|
2091
|
-
".js",
|
|
2092
|
-
".jsx",
|
|
2093
|
-
".mjs",
|
|
2094
|
-
".cjs",
|
|
2095
|
-
".mts",
|
|
2096
|
-
".cts"
|
|
2097
|
-
]);
|
|
2098
1875
|
function timestamp() {
|
|
2099
1876
|
return (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19);
|
|
2100
1877
|
}
|
|
@@ -2141,10 +1918,8 @@ async function devCommand(options) {
|
|
|
2141
1918
|
return;
|
|
2142
1919
|
}
|
|
2143
1920
|
reloading = true;
|
|
2144
|
-
log(
|
|
2145
|
-
|
|
2146
|
-
Detected change in ${changedPath ?? "tools directory"}, reloading...${reset}`
|
|
2147
|
-
);
|
|
1921
|
+
log(`${dim}
|
|
1922
|
+
Detected change in ${changedPath ?? "tools directory"}, reloading...${reset}`);
|
|
2148
1923
|
try {
|
|
2149
1924
|
toolDefinitions = await loadToolDefinitions(toolsDir, projectRoot);
|
|
2150
1925
|
routes = expandRoutes(toolDefinitions);
|
|
@@ -2177,9 +1952,7 @@ Detected change in ${changedPath ?? "tools directory"}, reloading...${reset}`
|
|
|
2177
1952
|
log(`${dim}[request] ${method} ${routePath}${reset}`);
|
|
2178
1953
|
try {
|
|
2179
1954
|
await handleRequest({ req, res, port, routes });
|
|
2180
|
-
log(
|
|
2181
|
-
`${dim}[response] ${method} ${routePath} ${res.statusCode}${reset}`
|
|
2182
|
-
);
|
|
1955
|
+
log(`${dim}[response] ${method} ${routePath} ${res.statusCode}${reset}`);
|
|
2183
1956
|
} catch (error) {
|
|
2184
1957
|
console.error("Error handling request:", error);
|
|
2185
1958
|
res.writeHead(500, { "Content-Type": "application/json" });
|
|
@@ -2189,9 +1962,7 @@ Detected change in ${changedPath ?? "tools directory"}, reloading...${reset}`
|
|
|
2189
1962
|
});
|
|
2190
1963
|
server.listen(port, () => {
|
|
2191
1964
|
log(`${bold}${dim}> dev opentool${reset}`);
|
|
2192
|
-
log(
|
|
2193
|
-
` * ${bold}opentool${reset} ${cyan}v${packageJson.version}${reset}`
|
|
2194
|
-
);
|
|
1965
|
+
log(` * ${bold}opentool${reset} ${cyan}v${packageJson.version}${reset}`);
|
|
2195
1966
|
log(` * ${bold}HTTP:${reset} http://localhost:${port}`);
|
|
2196
1967
|
logStartup(toolDefinitions, enableStdio, log);
|
|
2197
1968
|
});
|
|
@@ -2244,9 +2015,7 @@ async function startMcpServer(getTools) {
|
|
|
2244
2015
|
throw new Error(`Tool ${request.params.name} not found`);
|
|
2245
2016
|
}
|
|
2246
2017
|
try {
|
|
2247
|
-
const validatedParams = tool.schema.parse(
|
|
2248
|
-
request.params.arguments
|
|
2249
|
-
);
|
|
2018
|
+
const validatedParams = tool.schema.parse(request.params.arguments);
|
|
2250
2019
|
const handler = tool.handler ?? createMcpAdapter({
|
|
2251
2020
|
name: tool.metadata?.name ?? tool.filename,
|
|
2252
2021
|
httpHandlers: toHttpHandlerMap2(tool.httpHandlers),
|
|
@@ -2330,10 +2099,7 @@ function printToolList(tools, log) {
|
|
|
2330
2099
|
async function handleRequest(params) {
|
|
2331
2100
|
const { req, res, port, routes } = params;
|
|
2332
2101
|
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
2333
|
-
res.setHeader(
|
|
2334
|
-
"Access-Control-Allow-Methods",
|
|
2335
|
-
HTTP_METHODS.join(", ") + ", OPTIONS"
|
|
2336
|
-
);
|
|
2102
|
+
res.setHeader("Access-Control-Allow-Methods", HTTP_METHODS.join(", ") + ", OPTIONS");
|
|
2337
2103
|
res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
|
|
2338
2104
|
if (req.method === "OPTIONS") {
|
|
2339
2105
|
res.writeHead(200);
|
|
@@ -2386,9 +2152,7 @@ function findRoute(toolName, method, routes) {
|
|
|
2386
2152
|
return direct;
|
|
2387
2153
|
}
|
|
2388
2154
|
if (method === "HEAD") {
|
|
2389
|
-
return routes.find(
|
|
2390
|
-
(route) => routeName(route.tool) === toolName && route.method === "GET"
|
|
2391
|
-
);
|
|
2155
|
+
return routes.find((route) => routeName(route.tool) === toolName && route.method === "GET");
|
|
2392
2156
|
}
|
|
2393
2157
|
return void 0;
|
|
2394
2158
|
}
|
|
@@ -2435,13 +2199,10 @@ function createWebRequest(params) {
|
|
|
2435
2199
|
return new Request(url, init);
|
|
2436
2200
|
}
|
|
2437
2201
|
function toHttpHandlerMap2(handlers) {
|
|
2438
|
-
return handlers.reduce(
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
},
|
|
2443
|
-
{}
|
|
2444
|
-
);
|
|
2202
|
+
return handlers.reduce((acc, handler) => {
|
|
2203
|
+
acc[handler.method.toUpperCase()] = handler.handler;
|
|
2204
|
+
return acc;
|
|
2205
|
+
}, {});
|
|
2445
2206
|
}
|
|
2446
2207
|
function isMcpEnabled(tool) {
|
|
2447
2208
|
return Boolean(tool.mcpConfig?.enabled);
|
|
@@ -2541,7 +2302,7 @@ async function updateMetadata(targetDir, name, description) {
|
|
|
2541
2302
|
const raw = await promises.readFile(filePath, "utf-8");
|
|
2542
2303
|
const displayName = toDisplayName(name);
|
|
2543
2304
|
const resolvedDescription = description || "OpenTool project";
|
|
2544
|
-
const updated = raw.replace(/name:\s
|
|
2305
|
+
const updated = raw.replace(/name:\s*".*?"/, `name: "${toPackageName(name)}"`).replace(/displayName:\s*".*?"/, `displayName: "${displayName}"`).replace(/description:\s*".*?"/, `description: "${resolvedDescription}"`);
|
|
2545
2306
|
await promises.writeFile(filePath, updated, "utf-8");
|
|
2546
2307
|
}
|
|
2547
2308
|
async function initCommand(options) {
|
|
@@ -2549,9 +2310,7 @@ async function initCommand(options) {
|
|
|
2549
2310
|
const templateDir = resolveTemplateDir();
|
|
2550
2311
|
const empty = await directoryIsEmpty(targetDir);
|
|
2551
2312
|
if (!empty && !options.force) {
|
|
2552
|
-
throw new Error(
|
|
2553
|
-
`Directory not empty: ${targetDir}. Use --force to overwrite.`
|
|
2554
|
-
);
|
|
2313
|
+
throw new Error(`Directory not empty: ${targetDir}. Use --force to overwrite.`);
|
|
2555
2314
|
}
|
|
2556
2315
|
await copyDir(templateDir, targetDir);
|
|
2557
2316
|
const projectName = options.name || path6__default.basename(targetDir);
|
|
@@ -2573,11 +2332,7 @@ program.command("dev").description("Start HTTP dev server (optional MCP stdio)")
|
|
|
2573
2332
|
program.command("build").description("Build tools for deployment").option("-i, --input <dir>", "Input directory containing tools", "tools").option("-o, --output <dir>", "Output directory for built tools", "dist").option("--name <name>", "Server name", "opentool-server").option("--version <version>", "Server version", "1.0.0").action(buildCommand);
|
|
2574
2333
|
program.command("validate").description("Validate metadata for registry submission").option("-i, --input <dir>", "Input directory containing tools", "tools").action(validateCommand);
|
|
2575
2334
|
program.command("validate-full").description("Full validation of tools and metadata").option("-i, --input <dir>", "Input directory containing tools", "tools").action(validateFullCommand);
|
|
2576
|
-
program.command("metadata").description("Generate OpenTool metadata JSON without building").option("-i, --input <dir>", "Input directory containing tools", "tools").option(
|
|
2577
|
-
"-o, --output <file>",
|
|
2578
|
-
"Output file path for metadata.json",
|
|
2579
|
-
"metadata.json"
|
|
2580
|
-
).option("--name <name>", "Server name", "opentool-server").option("--version <version>", "Server version", "1.0.0").action(generateMetadataCommand);
|
|
2335
|
+
program.command("metadata").description("Generate OpenTool metadata JSON without building").option("-i, --input <dir>", "Input directory containing tools", "tools").option("-o, --output <file>", "Output file path for metadata.json", "metadata.json").option("--name <name>", "Server name", "opentool-server").option("--version <version>", "Server version", "1.0.0").action(generateMetadataCommand);
|
|
2581
2336
|
program.command("init").description("Create a new OpenTool project in the target directory").option("-d, --dir <dir>", "Target directory", ".").option("-n, --name <name>", "Project name").option("--description <description>", "Project description").option("--force", "Overwrite existing files", false).action(async (cmdOptions) => {
|
|
2582
2337
|
await initCommand({
|
|
2583
2338
|
dir: cmdOptions.dir,
|