@rapidthoughtlabs/heku 0.2.0 → 0.3.1
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/CHANGELOG.md +14 -1
- package/README.md +361 -62
- package/dist/cli.js +431 -209
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -4601,7 +4601,7 @@ var require_schemes = __commonJS({
|
|
|
4601
4601
|
serialize: httpSerialize
|
|
4602
4602
|
}
|
|
4603
4603
|
);
|
|
4604
|
-
var
|
|
4604
|
+
var https = (
|
|
4605
4605
|
/** @type {SchemeHandler} */
|
|
4606
4606
|
{
|
|
4607
4607
|
scheme: "https",
|
|
@@ -4650,7 +4650,7 @@ var require_schemes = __commonJS({
|
|
|
4650
4650
|
/** @type {Record<SchemeName, SchemeHandler>} */
|
|
4651
4651
|
{
|
|
4652
4652
|
http: http2,
|
|
4653
|
-
https
|
|
4653
|
+
https,
|
|
4654
4654
|
ws,
|
|
4655
4655
|
wss,
|
|
4656
4656
|
urn,
|
|
@@ -8442,7 +8442,7 @@ var require_supports_color = __commonJS({
|
|
|
8442
8442
|
"node_modules/supports-color/index.js"(exports2, module2) {
|
|
8443
8443
|
"use strict";
|
|
8444
8444
|
init_esm_shims();
|
|
8445
|
-
var
|
|
8445
|
+
var os6 = __require("os");
|
|
8446
8446
|
var tty = __require("tty");
|
|
8447
8447
|
var hasFlag = require_has_flag();
|
|
8448
8448
|
var { env } = process;
|
|
@@ -8499,7 +8499,7 @@ var require_supports_color = __commonJS({
|
|
|
8499
8499
|
return min;
|
|
8500
8500
|
}
|
|
8501
8501
|
if (process.platform === "win32") {
|
|
8502
|
-
const osRelease =
|
|
8502
|
+
const osRelease = os6.release().split(".");
|
|
8503
8503
|
if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
|
|
8504
8504
|
return Number(osRelease[2]) >= 14931 ? 3 : 2;
|
|
8505
8505
|
}
|
|
@@ -26827,10 +26827,10 @@ var require_view = __commonJS({
|
|
|
26827
26827
|
var debug = require_src()("express:view");
|
|
26828
26828
|
var path24 = __require("path");
|
|
26829
26829
|
var fs23 = __require("fs");
|
|
26830
|
-
var
|
|
26830
|
+
var dirname4 = path24.dirname;
|
|
26831
26831
|
var basename3 = path24.basename;
|
|
26832
26832
|
var extname2 = path24.extname;
|
|
26833
|
-
var
|
|
26833
|
+
var join4 = path24.join;
|
|
26834
26834
|
var resolve3 = path24.resolve;
|
|
26835
26835
|
module2.exports = View;
|
|
26836
26836
|
function View(name, options) {
|
|
@@ -26866,7 +26866,7 @@ var require_view = __commonJS({
|
|
|
26866
26866
|
for (var i = 0; i < roots.length && !path25; i++) {
|
|
26867
26867
|
var root = roots[i];
|
|
26868
26868
|
var loc = resolve3(root, name);
|
|
26869
|
-
var dir =
|
|
26869
|
+
var dir = dirname4(loc);
|
|
26870
26870
|
var file2 = basename3(loc);
|
|
26871
26871
|
path25 = this.resolve(dir, file2);
|
|
26872
26872
|
}
|
|
@@ -26892,12 +26892,12 @@ var require_view = __commonJS({
|
|
|
26892
26892
|
};
|
|
26893
26893
|
View.prototype.resolve = function resolve4(dir, file2) {
|
|
26894
26894
|
var ext = this.ext;
|
|
26895
|
-
var path25 =
|
|
26895
|
+
var path25 = join4(dir, file2);
|
|
26896
26896
|
var stat4 = tryStat(path25);
|
|
26897
26897
|
if (stat4 && stat4.isFile()) {
|
|
26898
26898
|
return path25;
|
|
26899
26899
|
}
|
|
26900
|
-
path25 =
|
|
26900
|
+
path25 = join4(dir, basename3(file2, ext), "index" + ext);
|
|
26901
26901
|
stat4 = tryStat(path25);
|
|
26902
26902
|
if (stat4 && stat4.isFile()) {
|
|
26903
26903
|
return path25;
|
|
@@ -30573,7 +30573,7 @@ var require_send = __commonJS({
|
|
|
30573
30573
|
var Stream = __require("stream");
|
|
30574
30574
|
var util2 = __require("util");
|
|
30575
30575
|
var extname2 = path24.extname;
|
|
30576
|
-
var
|
|
30576
|
+
var join4 = path24.join;
|
|
30577
30577
|
var normalize2 = path24.normalize;
|
|
30578
30578
|
var resolve3 = path24.resolve;
|
|
30579
30579
|
var sep = path24.sep;
|
|
@@ -30745,7 +30745,7 @@ var require_send = __commonJS({
|
|
|
30745
30745
|
return res;
|
|
30746
30746
|
}
|
|
30747
30747
|
parts = path25.split(sep);
|
|
30748
|
-
path25 = normalize2(
|
|
30748
|
+
path25 = normalize2(join4(root, path25));
|
|
30749
30749
|
} else {
|
|
30750
30750
|
if (UP_PATH_REGEXP.test(path25)) {
|
|
30751
30751
|
debug('malicious path "%s"', path25);
|
|
@@ -30878,7 +30878,7 @@ var require_send = __commonJS({
|
|
|
30878
30878
|
if (err) return self2.onStatError(err);
|
|
30879
30879
|
return self2.error(404);
|
|
30880
30880
|
}
|
|
30881
|
-
var p =
|
|
30881
|
+
var p = join4(path25, self2._index[i]);
|
|
30882
30882
|
debug('stat "%s"', p);
|
|
30883
30883
|
fs23.stat(p, function(err2, stat4) {
|
|
30884
30884
|
if (err2) return next(err2);
|
|
@@ -32320,7 +32320,7 @@ var require_cross_spawn = __commonJS({
|
|
|
32320
32320
|
enoent.hookChildProcess(spawned, parsed);
|
|
32321
32321
|
return spawned;
|
|
32322
32322
|
}
|
|
32323
|
-
function
|
|
32323
|
+
function spawnSync(command2, args2, options) {
|
|
32324
32324
|
const parsed = parse3(command2, args2, options);
|
|
32325
32325
|
const result = cp.spawnSync(parsed.command, parsed.args, parsed.options);
|
|
32326
32326
|
result.error = result.error || enoent.verifyENOENTSync(result.status, parsed);
|
|
@@ -32328,7 +32328,7 @@ var require_cross_spawn = __commonJS({
|
|
|
32328
32328
|
}
|
|
32329
32329
|
module2.exports = spawn4;
|
|
32330
32330
|
module2.exports.spawn = spawn4;
|
|
32331
|
-
module2.exports.sync =
|
|
32331
|
+
module2.exports.sync = spawnSync;
|
|
32332
32332
|
module2.exports._parse = parse3;
|
|
32333
32333
|
module2.exports._enoent = enoent;
|
|
32334
32334
|
}
|
|
@@ -33933,7 +33933,7 @@ var require_service_config = __commonJS({
|
|
|
33933
33933
|
exports2.validateRetryThrottling = validateRetryThrottling;
|
|
33934
33934
|
exports2.validateServiceConfig = validateServiceConfig;
|
|
33935
33935
|
exports2.extractAndSelectServiceConfig = extractAndSelectServiceConfig;
|
|
33936
|
-
var
|
|
33936
|
+
var os6 = __require("os");
|
|
33937
33937
|
var constants_1 = require_constants();
|
|
33938
33938
|
var DURATION_REGEX = /^\d+(\.\d{1,9})?s$/;
|
|
33939
33939
|
var CLIENT_LANGUAGE_STRING = "node";
|
|
@@ -34232,7 +34232,7 @@ var require_service_config = __commonJS({
|
|
|
34232
34232
|
if (Array.isArray(validatedConfig.clientHostname)) {
|
|
34233
34233
|
let hostnameMatched = false;
|
|
34234
34234
|
for (const hostname3 of validatedConfig.clientHostname) {
|
|
34235
|
-
if (hostname3 ===
|
|
34235
|
+
if (hostname3 === os6.hostname()) {
|
|
34236
34236
|
hostnameMatched = true;
|
|
34237
34237
|
}
|
|
34238
34238
|
}
|
|
@@ -48781,7 +48781,7 @@ var require_subchannel_call = __commonJS({
|
|
|
48781
48781
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
48782
48782
|
exports2.Http2SubchannelCall = void 0;
|
|
48783
48783
|
var http2 = __require("http2");
|
|
48784
|
-
var
|
|
48784
|
+
var os6 = __require("os");
|
|
48785
48785
|
var constants_1 = require_constants();
|
|
48786
48786
|
var metadata_1 = require_metadata2();
|
|
48787
48787
|
var stream_decoder_1 = require_stream_decoder();
|
|
@@ -48789,7 +48789,7 @@ var require_subchannel_call = __commonJS({
|
|
|
48789
48789
|
var constants_2 = require_constants();
|
|
48790
48790
|
var TRACER_NAME = "subchannel_call";
|
|
48791
48791
|
function getSystemErrorName(errno) {
|
|
48792
|
-
for (const [name, num] of Object.entries(
|
|
48792
|
+
for (const [name, num] of Object.entries(os6.constants.errno)) {
|
|
48793
48793
|
if (num === errno) {
|
|
48794
48794
|
return name;
|
|
48795
48795
|
}
|
|
@@ -79142,7 +79142,7 @@ var require_named_placeholders = __commonJS({
|
|
|
79142
79142
|
}
|
|
79143
79143
|
return s;
|
|
79144
79144
|
}
|
|
79145
|
-
function
|
|
79145
|
+
function join4(tree) {
|
|
79146
79146
|
if (tree.length === 1) {
|
|
79147
79147
|
return tree;
|
|
79148
79148
|
}
|
|
@@ -79168,7 +79168,7 @@ var require_named_placeholders = __commonJS({
|
|
|
79168
79168
|
if (cache2 && (tree = cache2.get(query))) {
|
|
79169
79169
|
return toArrayParams(tree, paramsObj);
|
|
79170
79170
|
}
|
|
79171
|
-
tree =
|
|
79171
|
+
tree = join4(parse3(query));
|
|
79172
79172
|
if (cache2) {
|
|
79173
79173
|
cache2.set(query, tree);
|
|
79174
79174
|
}
|
|
@@ -81773,9 +81773,9 @@ var require_bindings = __commonJS({
|
|
|
81773
81773
|
init_esm_shims();
|
|
81774
81774
|
var fs23 = __require("fs");
|
|
81775
81775
|
var path24 = __require("path");
|
|
81776
|
-
var
|
|
81777
|
-
var
|
|
81778
|
-
var
|
|
81776
|
+
var fileURLToPath4 = require_file_uri_to_path();
|
|
81777
|
+
var join4 = path24.join;
|
|
81778
|
+
var dirname4 = path24.dirname;
|
|
81779
81779
|
var exists = fs23.accessSync && function(path25) {
|
|
81780
81780
|
try {
|
|
81781
81781
|
fs23.accessSync(path25);
|
|
@@ -81834,7 +81834,7 @@ var require_bindings = __commonJS({
|
|
|
81834
81834
|
var requireFunc = typeof __webpack_require__ === "function" ? __non_webpack_require__ : __require;
|
|
81835
81835
|
var tries = [], i = 0, l = opts.try.length, n, b, err;
|
|
81836
81836
|
for (; i < l; i++) {
|
|
81837
|
-
n =
|
|
81837
|
+
n = join4.apply(
|
|
81838
81838
|
null,
|
|
81839
81839
|
opts.try[i].map(function(p) {
|
|
81840
81840
|
return opts[p] || p;
|
|
@@ -81885,17 +81885,17 @@ var require_bindings = __commonJS({
|
|
|
81885
81885
|
Error.stackTraceLimit = origSTL;
|
|
81886
81886
|
var fileSchema = "file://";
|
|
81887
81887
|
if (fileName.indexOf(fileSchema) === 0) {
|
|
81888
|
-
fileName =
|
|
81888
|
+
fileName = fileURLToPath4(fileName);
|
|
81889
81889
|
}
|
|
81890
81890
|
return fileName;
|
|
81891
81891
|
};
|
|
81892
81892
|
exports2.getRoot = function getRoot(file2) {
|
|
81893
|
-
var dir =
|
|
81893
|
+
var dir = dirname4(file2), prev;
|
|
81894
81894
|
while (true) {
|
|
81895
81895
|
if (dir === ".") {
|
|
81896
81896
|
dir = process.cwd();
|
|
81897
81897
|
}
|
|
81898
|
-
if (exists(
|
|
81898
|
+
if (exists(join4(dir, "package.json")) || exists(join4(dir, "node_modules"))) {
|
|
81899
81899
|
return dir;
|
|
81900
81900
|
}
|
|
81901
81901
|
if (prev === dir) {
|
|
@@ -81904,7 +81904,7 @@ var require_bindings = __commonJS({
|
|
|
81904
81904
|
);
|
|
81905
81905
|
}
|
|
81906
81906
|
prev = dir;
|
|
81907
|
-
dir =
|
|
81907
|
+
dir = join4(dir, "..");
|
|
81908
81908
|
}
|
|
81909
81909
|
};
|
|
81910
81910
|
}
|
|
@@ -93824,7 +93824,7 @@ var require_client_metadata = __commonJS({
|
|
|
93824
93824
|
exports2.makeClientMetadata = makeClientMetadata;
|
|
93825
93825
|
exports2.addContainerMetadata = addContainerMetadata;
|
|
93826
93826
|
exports2.getFAASEnv = getFAASEnv;
|
|
93827
|
-
var
|
|
93827
|
+
var os6 = __require("os");
|
|
93828
93828
|
var process5 = __require("process");
|
|
93829
93829
|
var bson_1 = require_bson2();
|
|
93830
93830
|
var error_1 = require_error2();
|
|
@@ -93894,7 +93894,7 @@ var require_client_metadata = __commonJS({
|
|
|
93894
93894
|
if (!metadataDocument.ifItFitsItSits("platform", runtimeInfo)) {
|
|
93895
93895
|
throw new error_1.MongoInvalidArgumentError("Unable to include driverInfo platform, metadata cannot exceed 512 bytes");
|
|
93896
93896
|
}
|
|
93897
|
-
const osInfo = (/* @__PURE__ */ new Map()).set("name", process5.platform).set("architecture", process5.arch).set("version",
|
|
93897
|
+
const osInfo = (/* @__PURE__ */ new Map()).set("name", process5.platform).set("architecture", process5.arch).set("version", os6.release()).set("type", os6.type());
|
|
93898
93898
|
if (!metadataDocument.ifItFitsItSits("os", osInfo)) {
|
|
93899
93899
|
for (const key of osInfo.keys()) {
|
|
93900
93900
|
osInfo.delete(key);
|
|
@@ -93997,13 +93997,13 @@ var require_client_metadata = __commonJS({
|
|
|
93997
93997
|
function getRuntimeInfo() {
|
|
93998
93998
|
if ("Deno" in globalThis) {
|
|
93999
93999
|
const version2 = typeof Deno?.version?.deno === "string" ? Deno?.version?.deno : "0.0.0-unknown";
|
|
94000
|
-
return `Deno v${version2}, ${
|
|
94000
|
+
return `Deno v${version2}, ${os6.endianness()}`;
|
|
94001
94001
|
}
|
|
94002
94002
|
if ("Bun" in globalThis) {
|
|
94003
94003
|
const version2 = typeof Bun?.version === "string" ? Bun?.version : "0.0.0-unknown";
|
|
94004
|
-
return `Bun v${version2}, ${
|
|
94004
|
+
return `Bun v${version2}, ${os6.endianness()}`;
|
|
94005
94005
|
}
|
|
94006
|
-
return `Node.js ${process5.version}, ${
|
|
94006
|
+
return `Node.js ${process5.version}, ${os6.endianness()}`;
|
|
94007
94007
|
}
|
|
94008
94008
|
}
|
|
94009
94009
|
});
|
|
@@ -130795,7 +130795,7 @@ function isConnectorType(value) {
|
|
|
130795
130795
|
// src/lib/config-rules.ts
|
|
130796
130796
|
init_esm_shims();
|
|
130797
130797
|
init_env_store();
|
|
130798
|
-
var RESERVED_IDS = ["
|
|
130798
|
+
var RESERVED_IDS = ["heku"];
|
|
130799
130799
|
function validateBaseId(id) {
|
|
130800
130800
|
if (!id || typeof id !== "string" || id.trim() === "") {
|
|
130801
130801
|
return "id must be a non-empty string";
|
|
@@ -131059,8 +131059,10 @@ function getInstalledEntry(slug, registry2 = "default") {
|
|
|
131059
131059
|
|
|
131060
131060
|
// src/lib/version.ts
|
|
131061
131061
|
init_esm_shims();
|
|
131062
|
-
|
|
131063
|
-
|
|
131062
|
+
import { readFileSync } from "fs";
|
|
131063
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
131064
|
+
import { join, dirname } from "path";
|
|
131065
|
+
var VERSION = true ? "0.3.1" : readPkgVersion();
|
|
131064
131066
|
|
|
131065
131067
|
// src/connectors/mcp.ts
|
|
131066
131068
|
init_esm_shims();
|
|
@@ -133924,8 +133926,40 @@ var serverSettings = {
|
|
|
133924
133926
|
function getServerSettings() {
|
|
133925
133927
|
return { ...serverSettings };
|
|
133926
133928
|
}
|
|
133929
|
+
var DISCOVERY_FLAT_SET = /* @__PURE__ */ new Set(["heku.search", "heku.list_tools", "heku.list_configs", "heku.invoke"]);
|
|
133930
|
+
var DISCOVERY_TRIO_SET = /* @__PURE__ */ new Set(["heku.search", "heku.list_tools", "heku.list_configs"]);
|
|
133927
133931
|
function createAdminRouter(ctx) {
|
|
133928
133932
|
const router = (0, import_express.Router)();
|
|
133933
|
+
router.get("/tools-manifest", (req, res) => {
|
|
133934
|
+
const styleParam = req.query.style;
|
|
133935
|
+
const style = styleParam === "namespaced" || styleParam === "flat" ? styleParam : serverSettings.manifestStyle;
|
|
133936
|
+
const tools = ctx.registry.list();
|
|
133937
|
+
if (style === "namespaced") {
|
|
133938
|
+
const visible2 = tools.filter(
|
|
133939
|
+
(rt) => DISCOVERY_TRIO_SET.has(`${rt.configId}.${rt.tool.name}`)
|
|
133940
|
+
);
|
|
133941
|
+
res.json(
|
|
133942
|
+
visible2.map((rt) => ({
|
|
133943
|
+
name: `${rt.configId}.${rt.tool.name}`,
|
|
133944
|
+
description: rt.tool.description,
|
|
133945
|
+
inputSchema: buildInputSchema2(rt.tool.params ?? []),
|
|
133946
|
+
configId: rt.configId
|
|
133947
|
+
}))
|
|
133948
|
+
);
|
|
133949
|
+
return;
|
|
133950
|
+
}
|
|
133951
|
+
const visible = tools.filter(
|
|
133952
|
+
(rt) => DISCOVERY_FLAT_SET.has(`${rt.configId}.${rt.tool.name}`)
|
|
133953
|
+
);
|
|
133954
|
+
res.json(
|
|
133955
|
+
visible.map((rt) => ({
|
|
133956
|
+
name: rt.tool.name,
|
|
133957
|
+
description: rt.tool.description,
|
|
133958
|
+
inputSchema: buildInputSchema2(rt.tool.params ?? []),
|
|
133959
|
+
configId: rt.configId
|
|
133960
|
+
}))
|
|
133961
|
+
);
|
|
133962
|
+
});
|
|
133929
133963
|
router.get("/server-settings", (_req, res) => {
|
|
133930
133964
|
res.json({
|
|
133931
133965
|
hotReload: ctx.watcher ? !ctx.watcher.isPaused() : serverSettings.hotReload,
|
|
@@ -134326,6 +134360,8 @@ var ToolRegistry = class {
|
|
|
134326
134360
|
}
|
|
134327
134361
|
this.tools.set(qualifiedName, {
|
|
134328
134362
|
configId: config2.id,
|
|
134363
|
+
configName: config2.name,
|
|
134364
|
+
configDescription: config2.description,
|
|
134329
134365
|
connectorConfig: config2.connector,
|
|
134330
134366
|
tool
|
|
134331
134367
|
});
|
|
@@ -134349,8 +134385,8 @@ var ToolRegistry = class {
|
|
|
134349
134385
|
return this.tools.size;
|
|
134350
134386
|
}
|
|
134351
134387
|
};
|
|
134352
|
-
var DISCOVERY_FLAT = /* @__PURE__ */ new Set(["
|
|
134353
|
-
var DISCOVERY_TRIO = /* @__PURE__ */ new Set(["
|
|
134388
|
+
var DISCOVERY_FLAT = /* @__PURE__ */ new Set(["heku.search", "heku.list_tools", "heku.list_configs", "heku.invoke"]);
|
|
134389
|
+
var DISCOVERY_TRIO = /* @__PURE__ */ new Set(["heku.search", "heku.list_tools", "heku.list_configs"]);
|
|
134354
134390
|
function buildManifestView(style, registry2) {
|
|
134355
134391
|
if (style === "namespaced") {
|
|
134356
134392
|
return {
|
|
@@ -134361,23 +134397,24 @@ function buildManifestView(style, registry2) {
|
|
|
134361
134397
|
}
|
|
134362
134398
|
return {
|
|
134363
134399
|
visible: registry2.list().filter((rt) => DISCOVERY_FLAT.has(`${rt.configId}.${rt.tool.name}`)),
|
|
134364
|
-
rewrite: (qualified) => qualified.replace(/^
|
|
134365
|
-
resolve: (incoming) => incoming.includes(".") ? incoming : `
|
|
134400
|
+
rewrite: (qualified) => qualified.replace(/^heku\./, ""),
|
|
134401
|
+
resolve: (incoming) => incoming.includes(".") ? incoming : `heku.${incoming}`
|
|
134366
134402
|
};
|
|
134367
134403
|
}
|
|
134368
134404
|
var BLOCKED_WHEN_LOCKED = /* @__PURE__ */ new Set([
|
|
134369
|
-
"
|
|
134370
|
-
"
|
|
134371
|
-
"
|
|
134372
|
-
"
|
|
134373
|
-
"
|
|
134374
|
-
"
|
|
134375
|
-
"
|
|
134376
|
-
"
|
|
134405
|
+
"heku.create_config",
|
|
134406
|
+
"heku.update_config",
|
|
134407
|
+
"heku.delete_config",
|
|
134408
|
+
"heku.add_tool",
|
|
134409
|
+
"heku.remove_tool",
|
|
134410
|
+
"heku.update_tool",
|
|
134411
|
+
"heku.registry_install",
|
|
134412
|
+
"heku.registry_update",
|
|
134413
|
+
"heku.auth_set"
|
|
134377
134414
|
]);
|
|
134378
134415
|
function blockedTool(qualifiedName, args2) {
|
|
134379
134416
|
if (BLOCKED_WHEN_LOCKED.has(qualifiedName)) return qualifiedName;
|
|
134380
|
-
if (qualifiedName === "
|
|
134417
|
+
if (qualifiedName === "heku.invoke") {
|
|
134381
134418
|
const target = args2["tool"];
|
|
134382
134419
|
if (typeof target === "string" && BLOCKED_WHEN_LOCKED.has(target)) return target;
|
|
134383
134420
|
}
|
|
@@ -134393,7 +134430,7 @@ function makeServer(registry2, transportCtx) {
|
|
|
134393
134430
|
const { visible, rewrite } = buildManifestView(manifestStyle, registry2);
|
|
134394
134431
|
const tools = visible.map((rt) => ({
|
|
134395
134432
|
name: rewrite(`${rt.configId}.${rt.tool.name}`),
|
|
134396
|
-
description: `[${rt.configId}] ${rt.tool.description}`,
|
|
134433
|
+
description: manifestStyle === "flat" ? rt.tool.description : `[${rt.configId}] ${rt.tool.description}`,
|
|
134397
134434
|
inputSchema: buildInputSchema(rt.tool.params)
|
|
134398
134435
|
}));
|
|
134399
134436
|
return { tools };
|
|
@@ -135371,9 +135408,9 @@ var NodeFsHandler = class {
|
|
|
135371
135408
|
if (this.fsw.closed) {
|
|
135372
135409
|
return;
|
|
135373
135410
|
}
|
|
135374
|
-
const
|
|
135411
|
+
const dirname4 = sp.dirname(file2);
|
|
135375
135412
|
const basename3 = sp.basename(file2);
|
|
135376
|
-
const parent = this.fsw._getWatchedDir(
|
|
135413
|
+
const parent = this.fsw._getWatchedDir(dirname4);
|
|
135377
135414
|
let prevStats = stats;
|
|
135378
135415
|
if (parent.has(basename3))
|
|
135379
135416
|
return;
|
|
@@ -135400,7 +135437,7 @@ var NodeFsHandler = class {
|
|
|
135400
135437
|
prevStats = newStats2;
|
|
135401
135438
|
}
|
|
135402
135439
|
} catch (error3) {
|
|
135403
|
-
this.fsw._remove(
|
|
135440
|
+
this.fsw._remove(dirname4, basename3);
|
|
135404
135441
|
}
|
|
135405
135442
|
} else if (parent.has(basename3)) {
|
|
135406
135443
|
const at = newStats.atimeMs;
|
|
@@ -136363,7 +136400,7 @@ init_loader();
|
|
|
136363
136400
|
var DEBOUNCE_MS = 300;
|
|
136364
136401
|
function isMcpConfigFile(filePath) {
|
|
136365
136402
|
const base2 = path11.basename(filePath);
|
|
136366
|
-
return base2.startsWith("mcp.") && base2.endsWith(".json") && base2 !== "mcp.
|
|
136403
|
+
return base2.startsWith("mcp.") && base2.endsWith(".json") && base2 !== "mcp.heku.json";
|
|
136367
136404
|
}
|
|
136368
136405
|
function isMcpEnvFile(filePath) {
|
|
136369
136406
|
const base2 = path11.basename(filePath);
|
|
@@ -136685,7 +136722,7 @@ function resolveConfigDir(cliOverride, systemConfig) {
|
|
|
136685
136722
|
init_esm_shims();
|
|
136686
136723
|
var import_express5 = __toESM(require_express2(), 1);
|
|
136687
136724
|
var import_cors = __toESM(require_lib3(), 1);
|
|
136688
|
-
import { fileURLToPath as
|
|
136725
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
136689
136726
|
|
|
136690
136727
|
// server/mcp-client.ts
|
|
136691
136728
|
init_esm_shims();
|
|
@@ -137612,7 +137649,21 @@ function createApiRouter(mcp) {
|
|
|
137612
137649
|
}
|
|
137613
137650
|
}
|
|
137614
137651
|
});
|
|
137615
|
-
router.get("/tools/manifest", (
|
|
137652
|
+
router.get("/tools/manifest", async (req, res) => {
|
|
137653
|
+
const style = req.query.style;
|
|
137654
|
+
if (style === "flat" || style === "namespaced") {
|
|
137655
|
+
try {
|
|
137656
|
+
const tools = await admin.get(`/tools-manifest?style=${style}`);
|
|
137657
|
+
res.json(tools);
|
|
137658
|
+
} catch (err) {
|
|
137659
|
+
if (err instanceof AdminUnavailableError) {
|
|
137660
|
+
res.json([]);
|
|
137661
|
+
return;
|
|
137662
|
+
}
|
|
137663
|
+
res.status(500).json({ error: err.message });
|
|
137664
|
+
}
|
|
137665
|
+
return;
|
|
137666
|
+
}
|
|
137616
137667
|
res.json(mcp.listTools());
|
|
137617
137668
|
});
|
|
137618
137669
|
router.post("/tools/call", async (req, res) => {
|
|
@@ -137822,6 +137873,9 @@ async function getConfigMeta(namespace, slug, connectorType, registryName = "def
|
|
|
137822
137873
|
const slugWithConnector = connectorType ? `${slug}:${connectorType}` : slug;
|
|
137823
137874
|
return jsonFetch(`/configs/${namespace}/${slugWithConnector}`, { registryName });
|
|
137824
137875
|
}
|
|
137876
|
+
async function listVersions(namespace, slug, registryName = "default") {
|
|
137877
|
+
return jsonFetch(`/configs/${namespace}/${slug}/versions`, { registryName });
|
|
137878
|
+
}
|
|
137825
137879
|
async function fetchVersionPayload(namespace, slug, connectorType, version2, registryName = "default") {
|
|
137826
137880
|
const slugWithConnector = connectorType ? `${slug}:${connectorType}` : slug;
|
|
137827
137881
|
const vPath = version2 ?? "latest";
|
|
@@ -137982,7 +138036,7 @@ function createRegistryRouter() {
|
|
|
137982
138036
|
const slug = colonIdx !== -1 ? rest.slice(0, colonIdx) : rest;
|
|
137983
138037
|
const connectorType = colonIdx !== -1 ? rest.slice(colonIdx + 1) : void 0;
|
|
137984
138038
|
const meta3 = await getConfigMeta(namespace, slug, connectorType, registry2);
|
|
137985
|
-
res.json({ category: meta3.category, tags: meta3.tags });
|
|
138039
|
+
res.json({ category: meta3.category, tags: meta3.tags, latest_version: meta3.latest_version ?? null });
|
|
137986
138040
|
}));
|
|
137987
138041
|
router.post("/check-updates", wrap(async (req, res) => {
|
|
137988
138042
|
const { installed, registry: registry2 = "default" } = req.body;
|
|
@@ -138094,6 +138148,12 @@ function createRegistryRouter() {
|
|
|
138094
138148
|
const { payload } = await fetchVersionPayload(namespace, slug, connector_type, void 0, registry2);
|
|
138095
138149
|
res.json(payload);
|
|
138096
138150
|
}));
|
|
138151
|
+
router.get("/versions/:namespace/:slug", wrap(async (req, res) => {
|
|
138152
|
+
const { namespace, slug } = req.params;
|
|
138153
|
+
const registry2 = req.query["registry"] ?? "default";
|
|
138154
|
+
const versions = await listVersions(namespace, slug, registry2);
|
|
138155
|
+
res.json(versions);
|
|
138156
|
+
}));
|
|
138097
138157
|
router.delete("/uninstall/:id", wrap(async (req, res) => {
|
|
138098
138158
|
const id = req.params["id"];
|
|
138099
138159
|
const registry2 = req.query["registry"] ?? "default";
|
|
@@ -138152,7 +138212,7 @@ async function startBridge(options) {
|
|
|
138152
138212
|
}
|
|
138153
138213
|
};
|
|
138154
138214
|
}
|
|
138155
|
-
var isMain = process.argv[1] ===
|
|
138215
|
+
var isMain = process.argv[1] === fileURLToPath3(import.meta.url);
|
|
138156
138216
|
if (isMain) {
|
|
138157
138217
|
const port = Number(process.env["PORT"] ?? 3456);
|
|
138158
138218
|
const bridge = await startBridge({ port });
|
|
@@ -138180,7 +138240,7 @@ init_env_store();
|
|
|
138180
138240
|
// src/internal-config.ts
|
|
138181
138241
|
init_esm_shims();
|
|
138182
138242
|
var INTERNAL_CONFIG = {
|
|
138183
|
-
id: "
|
|
138243
|
+
id: "heku",
|
|
138184
138244
|
name: "heku Self-Management",
|
|
138185
138245
|
description: "Create configs, add tools, install from registry, manage auth \u2014 heku's own management interface for LLM agents.",
|
|
138186
138246
|
connector: { type: "internal" },
|
|
@@ -138206,12 +138266,12 @@ var INTERNAL_CONFIG = {
|
|
|
138206
138266
|
},
|
|
138207
138267
|
{
|
|
138208
138268
|
name: "list_configs",
|
|
138209
|
-
description: "**Start here.** Returns
|
|
138269
|
+
description: "**Start here.** Returns all active configs as an array of objects with `id`, `name`, and `description`. Config IDs follow the pattern `<base>-<connector>` (e.g. `github-http`, `linear-graphql`). Use the description to pick the right config, then pass its `id` to `search` or `list_tools`.",
|
|
138210
138270
|
params: []
|
|
138211
138271
|
},
|
|
138212
138272
|
{
|
|
138213
138273
|
name: "search",
|
|
138214
|
-
description: "Find tools by name or intent across all configs (or within a specific one). Returns matching tools with full schemas grouped by
|
|
138274
|
+
description: "Find tools by name or intent across all configs (or within a specific one). Returns matching tools with full schemas grouped by quality: exact \u2192 partial \u2192 description \u2192 related. Covers both native `heku.*` self-management tools and all loaded service tools. Narrow by config: `github-http` returns only github-http tools; `github` matches github-http and github-cli. Once you have a tool name, call `invoke` with `config_id.tool_name` to execute it.",
|
|
138215
138275
|
params: [
|
|
138216
138276
|
{
|
|
138217
138277
|
name: "query",
|
|
@@ -138229,13 +138289,13 @@ var INTERNAL_CONFIG = {
|
|
|
138229
138289
|
},
|
|
138230
138290
|
{
|
|
138231
138291
|
name: "invoke",
|
|
138232
|
-
description: "Execute any registered tool by its qualified name (config_id.tool_name).
|
|
138292
|
+
description: "Execute any registered tool by its qualified name (`config_id.tool_name`). Workflow: (1) list_configs \u2192 pick a config id, (2) search or list_tools \u2192 get the tool name and required args, (3) invoke \u2192 run it. Examples: `github-http.create_issue`, `linear-graphql.create_issue`, `heku.server_status`.",
|
|
138233
138293
|
params: [
|
|
138234
138294
|
{
|
|
138235
138295
|
name: "tool",
|
|
138236
138296
|
type: "string",
|
|
138237
138297
|
required: true,
|
|
138238
|
-
description: "Qualified tool name in the format config_id.tool_name (e.g. 'open-meteo-http.get_forecast', 'github-http.create_issue', '
|
|
138298
|
+
description: "Qualified tool name in the format config_id.tool_name (e.g. 'open-meteo-http.get_forecast', 'github-http.create_issue', 'heku.server_status')"
|
|
138239
138299
|
},
|
|
138240
138300
|
{
|
|
138241
138301
|
name: "args",
|
|
@@ -138257,7 +138317,7 @@ var INTERNAL_CONFIG = {
|
|
|
138257
138317
|
},
|
|
138258
138318
|
{
|
|
138259
138319
|
name: "delete_config",
|
|
138260
|
-
description: "Delete a config file and unregister all its tools. Cannot delete the '
|
|
138320
|
+
description: "Delete a config file and unregister all its tools. Cannot delete the 'heku' self-management config \u2014 use self_config: false in heku.config.json instead.",
|
|
138261
138321
|
params: [
|
|
138262
138322
|
{ name: "config_id", type: "string", required: true, description: "Config ID to delete" }
|
|
138263
138323
|
]
|
|
@@ -138296,9 +138356,9 @@ var INTERNAL_CONFIG = {
|
|
|
138296
138356
|
},
|
|
138297
138357
|
{
|
|
138298
138358
|
name: "list_tools",
|
|
138299
|
-
description: "Returns tools with full schemas ready to call. No args: returns only the native `
|
|
138359
|
+
description: "Returns tools with full schemas ready to call. No args: returns only the native `heku.*` self-management surface. With config_id: returns all tools in that config. For targeted lookup by name or intent, use `heku.search` instead.",
|
|
138300
138360
|
params: [
|
|
138301
|
-
{ name: "config_id", type: "string", required: false, description: "Config ID to list tools for. Omit to list only native
|
|
138361
|
+
{ name: "config_id", type: "string", required: false, description: "Config ID to list tools for. Omit to list only native heku.* tools." }
|
|
138302
138362
|
]
|
|
138303
138363
|
},
|
|
138304
138364
|
{
|
|
@@ -138345,6 +138405,14 @@ var INTERNAL_CONFIG = {
|
|
|
138345
138405
|
{ name: "registry", type: "string", required: false, description: "Registry source name (default: 'default')" }
|
|
138346
138406
|
]
|
|
138347
138407
|
},
|
|
138408
|
+
{
|
|
138409
|
+
name: "registry_update",
|
|
138410
|
+
description: "Update registry-installed configs to the latest available version. Preserves local credentials (connector.env) and overlays. Pass config_id to update a single config, or omit to update all installed configs.",
|
|
138411
|
+
params: [
|
|
138412
|
+
{ name: "config_id", type: "string", required: false, description: "ID of the config to update (e.g. 'github-http'). Omit to update all installed configs." },
|
|
138413
|
+
{ name: "registry", type: "string", required: false, description: "Registry source name (default: 'default')" }
|
|
138414
|
+
]
|
|
138415
|
+
},
|
|
138348
138416
|
{
|
|
138349
138417
|
name: "auth_status",
|
|
138350
138418
|
description: "Check which configs have missing or misconfigured credentials. Returns per-config auth status and the specific env vars that are missing.",
|
|
@@ -141195,7 +141263,17 @@ async function handleGetConfig(ctx, args2) {
|
|
|
141195
141263
|
return { success: true, data: raw };
|
|
141196
141264
|
}
|
|
141197
141265
|
async function handleListConfigs(ctx, _args) {
|
|
141198
|
-
const
|
|
141266
|
+
const seen = /* @__PURE__ */ new Map();
|
|
141267
|
+
for (const rt of ctx.registry.list()) {
|
|
141268
|
+
if (!seen.has(rt.configId)) {
|
|
141269
|
+
seen.set(rt.configId, {
|
|
141270
|
+
id: rt.configId,
|
|
141271
|
+
...rt.configName && { name: rt.configName },
|
|
141272
|
+
...rt.configDescription && { description: rt.configDescription }
|
|
141273
|
+
});
|
|
141274
|
+
}
|
|
141275
|
+
}
|
|
141276
|
+
const configs = [...seen.values()].sort((a, b) => a.id.localeCompare(b.id));
|
|
141199
141277
|
return { success: true, data: { configs } };
|
|
141200
141278
|
}
|
|
141201
141279
|
async function handleUpdateConfig(ctx, args2) {
|
|
@@ -141412,7 +141490,7 @@ async function handleUpdateTool(ctx, args2) {
|
|
|
141412
141490
|
}
|
|
141413
141491
|
async function handleListTools(ctx, args2) {
|
|
141414
141492
|
const filterById = args2.config_id;
|
|
141415
|
-
const scopeId = filterById ?? "
|
|
141493
|
+
const scopeId = filterById ?? "heku";
|
|
141416
141494
|
const tools = ctx.registry.list().filter((rt) => rt.configId === scopeId).map((rt) => ({
|
|
141417
141495
|
qualified_name: `${rt.configId}.${rt.tool.name}`,
|
|
141418
141496
|
config_id: rt.configId,
|
|
@@ -141633,6 +141711,112 @@ async function handleRegistryInstall(ctx, args2) {
|
|
|
141633
141711
|
return { success: false, data: { error: err.message } };
|
|
141634
141712
|
}
|
|
141635
141713
|
}
|
|
141714
|
+
async function handleRegistryUpdate(ctx, args2) {
|
|
141715
|
+
const configId = args2.config_id;
|
|
141716
|
+
const registry2 = args2.registry ?? "default";
|
|
141717
|
+
const { installed } = loadManifest();
|
|
141718
|
+
const forRegistry = installed.filter((e) => e.registry === registry2);
|
|
141719
|
+
let toCheck;
|
|
141720
|
+
if (configId) {
|
|
141721
|
+
const entry = forRegistry.find((e) => {
|
|
141722
|
+
const withoutNs = e.slug.replace(/^@[^/]+\//, "");
|
|
141723
|
+
const colonIdx = withoutNs.indexOf(":");
|
|
141724
|
+
if (colonIdx === -1) return false;
|
|
141725
|
+
const base2 = withoutNs.slice(0, colonIdx);
|
|
141726
|
+
const ct = withoutNs.slice(colonIdx + 1);
|
|
141727
|
+
return `${base2}-${ct}` === configId;
|
|
141728
|
+
});
|
|
141729
|
+
if (!entry) {
|
|
141730
|
+
return {
|
|
141731
|
+
success: false,
|
|
141732
|
+
data: { error: `"${configId}" is not a registry-installed config or was not found in the manifest. Only configs installed from the registry can be updated this way.` }
|
|
141733
|
+
};
|
|
141734
|
+
}
|
|
141735
|
+
toCheck = [entry];
|
|
141736
|
+
} else {
|
|
141737
|
+
if (forRegistry.length === 0) {
|
|
141738
|
+
return { success: true, data: { message: "No registry-installed configs to update", updated: [], up_to_date: [] } };
|
|
141739
|
+
}
|
|
141740
|
+
toCheck = forRegistry;
|
|
141741
|
+
}
|
|
141742
|
+
let updateCheck;
|
|
141743
|
+
try {
|
|
141744
|
+
updateCheck = await checkUpdates(
|
|
141745
|
+
toCheck.map((e) => ({ slug: e.slug, version: e.version })),
|
|
141746
|
+
registry2
|
|
141747
|
+
);
|
|
141748
|
+
} catch (err) {
|
|
141749
|
+
if (err instanceof RegistryError) {
|
|
141750
|
+
return { success: false, data: { error: err.message, status: err.status } };
|
|
141751
|
+
}
|
|
141752
|
+
return { success: false, data: { error: err.message } };
|
|
141753
|
+
}
|
|
141754
|
+
if (updateCheck.updates.length === 0) {
|
|
141755
|
+
return {
|
|
141756
|
+
success: true,
|
|
141757
|
+
data: { message: "All configs are up to date", up_to_date: updateCheck.up_to_date }
|
|
141758
|
+
};
|
|
141759
|
+
}
|
|
141760
|
+
const updated = [];
|
|
141761
|
+
const errors2 = [];
|
|
141762
|
+
for (const info of updateCheck.updates) {
|
|
141763
|
+
const withoutAt = info.slug.startsWith("@") ? info.slug.slice(1) : info.slug;
|
|
141764
|
+
const slashIdx = withoutAt.indexOf("/");
|
|
141765
|
+
if (slashIdx === -1) continue;
|
|
141766
|
+
const namespace = withoutAt.slice(0, slashIdx);
|
|
141767
|
+
const rest = withoutAt.slice(slashIdx + 1);
|
|
141768
|
+
const colonIdx = rest.indexOf(":");
|
|
141769
|
+
const rawSlug = colonIdx !== -1 ? rest.slice(0, colonIdx) : rest;
|
|
141770
|
+
const connType = colonIdx !== -1 ? rest.slice(colonIdx + 1) : void 0;
|
|
141771
|
+
const installedId = `${rawSlug}-${connType ?? ""}`;
|
|
141772
|
+
const outFile = path17.join(ctx.configDir, `mcp.${installedId}.json`);
|
|
141773
|
+
try {
|
|
141774
|
+
const { payload, version: resolvedVersion } = await fetchVersionPayload(
|
|
141775
|
+
namespace,
|
|
141776
|
+
rawSlug,
|
|
141777
|
+
connType,
|
|
141778
|
+
info.latest_version,
|
|
141779
|
+
registry2
|
|
141780
|
+
);
|
|
141781
|
+
const payloadObj = payload;
|
|
141782
|
+
payloadObj.id = installedId;
|
|
141783
|
+
if (fs15.existsSync(outFile)) {
|
|
141784
|
+
try {
|
|
141785
|
+
const existing = JSON.parse(fs15.readFileSync(outFile, "utf-8"));
|
|
141786
|
+
const existingConnector = existing.connector;
|
|
141787
|
+
if (existingConnector?.env) {
|
|
141788
|
+
const newConnector = payloadObj.connector ?? {};
|
|
141789
|
+
newConnector.env = existingConnector.env;
|
|
141790
|
+
payloadObj.connector = newConnector;
|
|
141791
|
+
}
|
|
141792
|
+
const existingOverlays = existing.overlays ?? {};
|
|
141793
|
+
const newOverlays = payloadObj.overlays ?? {};
|
|
141794
|
+
payloadObj.overlays = { ...existingOverlays, ...newOverlays };
|
|
141795
|
+
} catch {
|
|
141796
|
+
}
|
|
141797
|
+
}
|
|
141798
|
+
fs15.mkdirSync(ctx.configDir, { recursive: true });
|
|
141799
|
+
fs15.writeFileSync(outFile, JSON.stringify(payloadObj, null, 2) + "\n", "utf-8");
|
|
141800
|
+
addToManifest(info.slug, resolvedVersion, connType ?? "", registry2);
|
|
141801
|
+
updated.push({ slug: info.slug, id: installedId, from: info.installed_version, to: resolvedVersion });
|
|
141802
|
+
} catch (err) {
|
|
141803
|
+
if (err instanceof RegistryError) {
|
|
141804
|
+
errors2.push({ slug: info.slug, error: err.message });
|
|
141805
|
+
} else {
|
|
141806
|
+
errors2.push({ slug: info.slug, error: err.message });
|
|
141807
|
+
}
|
|
141808
|
+
}
|
|
141809
|
+
}
|
|
141810
|
+
return {
|
|
141811
|
+
success: errors2.length === 0,
|
|
141812
|
+
data: {
|
|
141813
|
+
message: updated.length > 0 ? `Updated ${updated.length} config(s).${errors2.length > 0 ? ` ${errors2.length} failed.` : ""} Server will hot-reload automatically.` : `All configs are up to date.`,
|
|
141814
|
+
updated,
|
|
141815
|
+
up_to_date: updateCheck.up_to_date,
|
|
141816
|
+
...errors2.length > 0 && { errors: errors2 }
|
|
141817
|
+
}
|
|
141818
|
+
};
|
|
141819
|
+
}
|
|
141636
141820
|
async function handleRegistryCheckUpdates(_ctx, args2) {
|
|
141637
141821
|
const registry2 = args2.registry ?? "default";
|
|
141638
141822
|
try {
|
|
@@ -141874,7 +142058,7 @@ async function handleInvoke(ctx, args2) {
|
|
|
141874
142058
|
success: false,
|
|
141875
142059
|
data: {
|
|
141876
142060
|
error: `Tool "${toolName}" not found`,
|
|
141877
|
-
hint: "Use
|
|
142061
|
+
hint: "Use heku.search or heku.list_tools to find available tool names",
|
|
141878
142062
|
available_count: available.length
|
|
141879
142063
|
}
|
|
141880
142064
|
};
|
|
@@ -141927,6 +142111,7 @@ var HANDLERS = {
|
|
|
141927
142111
|
registry_browse: handleRegistryBrowse,
|
|
141928
142112
|
registry_install: handleRegistryInstall,
|
|
141929
142113
|
registry_check_updates: handleRegistryCheckUpdates,
|
|
142114
|
+
registry_update: handleRegistryUpdate,
|
|
141930
142115
|
// Auth
|
|
141931
142116
|
auth_status: handleAuthStatus,
|
|
141932
142117
|
auth_set: handleAuthSet,
|
|
@@ -142419,8 +142604,8 @@ async function run(args2) {
|
|
|
142419
142604
|
}
|
|
142420
142605
|
log.info("server", `Loading configs from: ${configDir}`);
|
|
142421
142606
|
const handAuthored = loadConfigs(configDir).filter((c) => {
|
|
142422
|
-
if (c.id === "
|
|
142423
|
-
log.warn("server", `mcp.
|
|
142607
|
+
if (c.id === "heku") {
|
|
142608
|
+
log.warn("server", `mcp.heku.json in ${configDir} is ignored \u2014 internal config is built-in`);
|
|
142424
142609
|
return false;
|
|
142425
142610
|
}
|
|
142426
142611
|
return true;
|
|
@@ -142430,7 +142615,7 @@ async function run(args2) {
|
|
|
142430
142615
|
...handAuthored
|
|
142431
142616
|
];
|
|
142432
142617
|
if (handAuthored.length === 0) {
|
|
142433
|
-
log.info("server", `No user configs yet \u2014 drop mcp.*.json files in ${configDir} or call
|
|
142618
|
+
log.info("server", `No user configs yet \u2014 drop mcp.*.json files in ${configDir} or call heku.registry_install`);
|
|
142434
142619
|
}
|
|
142435
142620
|
for (const config2 of allConfigs) {
|
|
142436
142621
|
if (config2.connector.type === "mcp") {
|
|
@@ -142563,13 +142748,13 @@ async function run(args2) {
|
|
|
142563
142748
|
}
|
|
142564
142749
|
if (systemConfig.self_config === false) {
|
|
142565
142750
|
const before = allConfigs.length;
|
|
142566
|
-
allConfigs.splice(0, allConfigs.length, ...allConfigs.filter((c) => c.id !== "
|
|
142751
|
+
allConfigs.splice(0, allConfigs.length, ...allConfigs.filter((c) => c.id !== "heku"));
|
|
142567
142752
|
if (allConfigs.length < before) {
|
|
142568
142753
|
log.info("server", "self_config: false \u2014 heku self-management disabled");
|
|
142569
142754
|
}
|
|
142570
142755
|
} else if (systemConfig.self_config && typeof systemConfig.self_config === "object") {
|
|
142571
142756
|
const sc = systemConfig.self_config;
|
|
142572
|
-
const oneConfig = allConfigs.find((c) => c.id === "
|
|
142757
|
+
const oneConfig = allConfigs.find((c) => c.id === "heku");
|
|
142573
142758
|
if (oneConfig) {
|
|
142574
142759
|
if (sc.allow) {
|
|
142575
142760
|
oneConfig.tools = oneConfig.tools.filter((t) => sc.allow.includes(t.name));
|
|
@@ -143358,7 +143543,7 @@ async function run5(args2) {
|
|
|
143358
143543
|
} else {
|
|
143359
143544
|
let candidates = [];
|
|
143360
143545
|
if (fs18.existsSync(configDir)) {
|
|
143361
|
-
candidates = fs18.readdirSync(configDir).filter((f) => f.startsWith("mcp.") && f.endsWith(".json") && f !== "mcp.
|
|
143546
|
+
candidates = fs18.readdirSync(configDir).filter((f) => f.startsWith("mcp.") && f.endsWith(".json") && f !== "mcp.heku.json").map((f) => path20.join(configDir, f));
|
|
143362
143547
|
}
|
|
143363
143548
|
if (candidates.length === 0) {
|
|
143364
143549
|
console.error(red("\u2717") + ` No config file found. Try: ${bold("heku publish <name>")}`);
|
|
@@ -144088,159 +144273,195 @@ async function run8(args2) {
|
|
|
144088
144273
|
|
|
144089
144274
|
// src/commands/update.ts
|
|
144090
144275
|
init_esm_shims();
|
|
144091
|
-
import { spawnSync } from "child_process";
|
|
144092
|
-
|
|
144093
|
-
// src/lib/update-check.ts
|
|
144094
|
-
init_esm_shims();
|
|
144095
|
-
import https from "https";
|
|
144096
144276
|
import fs22 from "fs";
|
|
144097
144277
|
import path23 from "path";
|
|
144098
|
-
|
|
144099
|
-
|
|
144100
|
-
|
|
144101
|
-
|
|
144102
|
-
|
|
144103
|
-
|
|
144104
|
-
|
|
144105
|
-
|
|
144106
|
-
|
|
144107
|
-
}
|
|
144108
|
-
|
|
144109
|
-
|
|
144110
|
-
|
|
144111
|
-
|
|
144112
|
-
|
|
144113
|
-
|
|
144114
|
-
|
|
144115
|
-
|
|
144116
|
-
|
|
144117
|
-
}
|
|
144118
|
-
}
|
|
144119
|
-
function fetchLatestVersion() {
|
|
144120
|
-
return new Promise((resolve3, reject) => {
|
|
144121
|
-
const req = https.get(
|
|
144122
|
-
`https://registry.npmjs.org/${PKG_NAME}/latest`,
|
|
144123
|
-
{ headers: { Accept: "application/json" } },
|
|
144124
|
-
(res) => {
|
|
144125
|
-
let data = "";
|
|
144126
|
-
res.on("data", (chunk) => {
|
|
144127
|
-
data += chunk;
|
|
144128
|
-
});
|
|
144129
|
-
res.on("end", () => {
|
|
144130
|
-
try {
|
|
144131
|
-
if (res.statusCode !== 200) {
|
|
144132
|
-
reject(new Error(`npm registry returned HTTP ${res.statusCode}`));
|
|
144133
|
-
return;
|
|
144134
|
-
}
|
|
144135
|
-
const json2 = JSON.parse(data);
|
|
144136
|
-
if (!json2.version) {
|
|
144137
|
-
reject(new Error("npm registry response missing version field"));
|
|
144138
|
-
return;
|
|
144139
|
-
}
|
|
144140
|
-
resolve3(json2.version);
|
|
144141
|
-
} catch (e) {
|
|
144142
|
-
reject(e);
|
|
144143
|
-
}
|
|
144144
|
-
});
|
|
144145
|
-
}
|
|
144146
|
-
);
|
|
144147
|
-
req.on("error", reject);
|
|
144148
|
-
req.setTimeout(5e3, () => {
|
|
144149
|
-
req.destroy();
|
|
144150
|
-
reject(new Error("timeout"));
|
|
144151
|
-
});
|
|
144152
|
-
});
|
|
144153
|
-
}
|
|
144154
|
-
function semverGt(a, b) {
|
|
144155
|
-
const parse3 = (v) => v.replace(/[^0-9.]/g, "").split(".").map(Number);
|
|
144156
|
-
const pa = parse3(a);
|
|
144157
|
-
const pb = parse3(b);
|
|
144158
|
-
for (let i = 0; i < 3; i++) {
|
|
144159
|
-
const na = pa[i] ?? 0;
|
|
144160
|
-
const nb = pb[i] ?? 0;
|
|
144161
|
-
if (na > nb) return true;
|
|
144162
|
-
if (na < nb) return false;
|
|
144163
|
-
}
|
|
144278
|
+
function compoundId2(entry) {
|
|
144279
|
+
const withoutNs = entry.slug.replace(/^@[^/]+\//, "");
|
|
144280
|
+
const colonIdx = withoutNs.indexOf(":");
|
|
144281
|
+
const rawSlug = colonIdx !== -1 ? withoutNs.slice(0, colonIdx) : withoutNs;
|
|
144282
|
+
const ct = colonIdx !== -1 ? withoutNs.slice(colonIdx + 1) : entry.connector_type;
|
|
144283
|
+
return `${rawSlug}-${ct}`;
|
|
144284
|
+
}
|
|
144285
|
+
function matchesTarget(entry, target) {
|
|
144286
|
+
const slug = entry.slug;
|
|
144287
|
+
if (slug === target || slug === `@${target}`) return true;
|
|
144288
|
+
const withoutNs = slug.replace(/^@[^/]+\//, "");
|
|
144289
|
+
const colonIdx = withoutNs.indexOf(":");
|
|
144290
|
+
const rawSlug = colonIdx !== -1 ? withoutNs.slice(0, colonIdx) : withoutNs;
|
|
144291
|
+
const ct = colonIdx !== -1 ? withoutNs.slice(colonIdx + 1) : "";
|
|
144292
|
+
if (`${rawSlug}-${ct}` === target) return true;
|
|
144293
|
+
if (withoutNs === target) return true;
|
|
144294
|
+
const withoutConnector = slug.replace(/:.*$/, "");
|
|
144295
|
+
if (withoutConnector === target || withoutConnector === `@${target}`) return true;
|
|
144296
|
+
if (!target.includes(":") && !target.includes("-") && rawSlug === target) return true;
|
|
144164
144297
|
return false;
|
|
144165
144298
|
}
|
|
144166
|
-
function
|
|
144167
|
-
const
|
|
144168
|
-
const
|
|
144169
|
-
const
|
|
144170
|
-
const
|
|
144171
|
-
|
|
144172
|
-
|
|
144173
|
-
|
|
144174
|
-
|
|
144175
|
-
|
|
144176
|
-
|
|
144177
|
-
|
|
144178
|
-
|
|
144299
|
+
async function downloadAndInstall(entry, latestVersion, configDir) {
|
|
144300
|
+
const withoutAt = entry.slug.startsWith("@") ? entry.slug.slice(1) : entry.slug;
|
|
144301
|
+
const slashIdx = withoutAt.indexOf("/");
|
|
144302
|
+
const namespace = withoutAt.slice(0, slashIdx);
|
|
144303
|
+
const rest = withoutAt.slice(slashIdx + 1);
|
|
144304
|
+
const colonIdx = rest.indexOf(":");
|
|
144305
|
+
const rawSlug = colonIdx !== -1 ? rest.slice(0, colonIdx) : rest;
|
|
144306
|
+
const connType = colonIdx !== -1 ? rest.slice(colonIdx + 1) : entry.connector_type;
|
|
144307
|
+
const id = `${rawSlug}-${connType}`;
|
|
144308
|
+
const outFile = path23.join(configDir, `mcp.${id}.json`);
|
|
144309
|
+
const { payload, version: resolvedVersion } = await fetchVersionPayload(
|
|
144310
|
+
namespace,
|
|
144311
|
+
rawSlug,
|
|
144312
|
+
connType,
|
|
144313
|
+
latestVersion,
|
|
144314
|
+
entry.registry
|
|
144179
144315
|
);
|
|
144180
|
-
|
|
144181
|
-
|
|
144182
|
-
|
|
144183
|
-
|
|
144184
|
-
|
|
144185
|
-
|
|
144316
|
+
const payloadObj = payload;
|
|
144317
|
+
payloadObj.id = id;
|
|
144318
|
+
if (fs22.existsSync(outFile)) {
|
|
144319
|
+
try {
|
|
144320
|
+
const existing = JSON.parse(fs22.readFileSync(outFile, "utf-8"));
|
|
144321
|
+
const existingConn = existing.connector;
|
|
144322
|
+
if (existingConn?.env) {
|
|
144323
|
+
const newConn = payloadObj.connector ?? {};
|
|
144324
|
+
newConn.env = existingConn.env;
|
|
144325
|
+
payloadObj.connector = newConn;
|
|
144326
|
+
}
|
|
144327
|
+
const existingOverlays = existing.overlays ?? {};
|
|
144328
|
+
const newOverlays = payloadObj.overlays ?? {};
|
|
144329
|
+
payloadObj.overlays = { ...existingOverlays, ...newOverlays };
|
|
144330
|
+
} catch {
|
|
144186
144331
|
}
|
|
144332
|
+
}
|
|
144333
|
+
fs22.mkdirSync(configDir, { recursive: true });
|
|
144334
|
+
fs22.writeFileSync(outFile, JSON.stringify(payloadObj, null, 2) + "\n", "utf-8");
|
|
144335
|
+
addToManifest(entry.slug, resolvedVersion, connType, entry.registry, entry.forked_from ?? null);
|
|
144336
|
+
return { id, from: entry.version, to: resolvedVersion };
|
|
144337
|
+
}
|
|
144338
|
+
async function run9(args2) {
|
|
144339
|
+
const registryIdx = args2.indexOf("--registry");
|
|
144340
|
+
const registry2 = registryIdx !== -1 ? args2[registryIdx + 1] ?? "default" : "default";
|
|
144341
|
+
const skipIndices = /* @__PURE__ */ new Set();
|
|
144342
|
+
if (registryIdx !== -1) {
|
|
144343
|
+
skipIndices.add(registryIdx);
|
|
144344
|
+
skipIndices.add(registryIdx + 1);
|
|
144345
|
+
}
|
|
144346
|
+
const target = args2.find((a, i) => !skipIndices.has(i) && !a.startsWith("--"));
|
|
144347
|
+
const systemConfig = loadSystemConfig(process.cwd());
|
|
144348
|
+
const configDir = resolveConfigDir(void 0, systemConfig);
|
|
144349
|
+
const { installed } = loadManifest();
|
|
144350
|
+
const forRegistry = installed.filter((e) => e.registry === registry2);
|
|
144351
|
+
if (forRegistry.length === 0) {
|
|
144352
|
+
console.log();
|
|
144353
|
+
console.log(dim(" No registry-installed configs found."));
|
|
144354
|
+
console.log(dim(` Install one with: ${bold("heku install @ns/slug")}`));
|
|
144355
|
+
console.log();
|
|
144187
144356
|
return;
|
|
144188
144357
|
}
|
|
144189
|
-
|
|
144190
|
-
|
|
144191
|
-
|
|
144192
|
-
|
|
144358
|
+
let toCheck;
|
|
144359
|
+
if (target) {
|
|
144360
|
+
toCheck = forRegistry.filter((e) => matchesTarget(e, target));
|
|
144361
|
+
if (toCheck.length === 0) {
|
|
144362
|
+
console.log();
|
|
144363
|
+
console.error(red("\u2717") + ` No installed config matches "${bold(target)}".`);
|
|
144364
|
+
console.error(dim(` Run ${bold("heku list")} to see installed configs.`));
|
|
144365
|
+
console.log();
|
|
144366
|
+
process.exit(1);
|
|
144193
144367
|
}
|
|
144194
|
-
}
|
|
144195
|
-
|
|
144196
|
-
}
|
|
144197
|
-
|
|
144198
|
-
|
|
144199
|
-
|
|
144200
|
-
|
|
144201
|
-
|
|
144202
|
-
|
|
144368
|
+
} else {
|
|
144369
|
+
toCheck = forRegistry;
|
|
144370
|
+
}
|
|
144371
|
+
console.log();
|
|
144372
|
+
if (target) {
|
|
144373
|
+
console.log(bold(` Checking ${cyan(target)}...`));
|
|
144374
|
+
} else {
|
|
144375
|
+
console.log(bold(" Checking for updates..."));
|
|
144376
|
+
}
|
|
144377
|
+
console.log();
|
|
144378
|
+
let updateResult;
|
|
144203
144379
|
try {
|
|
144204
|
-
|
|
144205
|
-
|
|
144206
|
-
|
|
144207
|
-
|
|
144380
|
+
updateResult = await checkUpdates(
|
|
144381
|
+
toCheck.map((e) => ({ slug: e.slug, version: e.version })),
|
|
144382
|
+
registry2
|
|
144383
|
+
);
|
|
144384
|
+
} catch (err) {
|
|
144385
|
+
console.error(
|
|
144386
|
+
red("\u2717") + ` ${err instanceof RegistryError ? err.message : err.message}`
|
|
144387
|
+
);
|
|
144208
144388
|
process.exit(1);
|
|
144209
144389
|
}
|
|
144210
|
-
|
|
144211
|
-
|
|
144212
|
-
|
|
144390
|
+
const { updates, up_to_date, deprecated } = updateResult;
|
|
144391
|
+
const colWidth = Math.max(
|
|
144392
|
+
...[...updates, ...up_to_date, ...deprecated].map((u) => {
|
|
144393
|
+
const entry = toCheck.find((e) => e.slug === u.slug);
|
|
144394
|
+
return entry ? compoundId2(entry).length : 0;
|
|
144395
|
+
}),
|
|
144396
|
+
12
|
|
144397
|
+
);
|
|
144398
|
+
for (const u of up_to_date) {
|
|
144399
|
+
const entry = toCheck.find((e) => e.slug === u.slug);
|
|
144400
|
+
const id = entry ? compoundId2(entry) : u.slug;
|
|
144401
|
+
console.log(` ${dim(id.padEnd(colWidth))} ${dim(`v${u.version}`)} ${dim("up to date")}`);
|
|
144402
|
+
}
|
|
144403
|
+
for (const u of updates) {
|
|
144404
|
+
const entry = toCheck.find((e) => e.slug === u.slug);
|
|
144405
|
+
const id = entry ? compoundId2(entry) : u.slug;
|
|
144406
|
+
const badge = u.breaking ? yellow(`${u.severity} \xB7 breaking`) : cyan(u.severity);
|
|
144407
|
+
console.log(
|
|
144408
|
+
` ${bold(id.padEnd(colWidth))} ${dim(`v${u.installed_version}`)} \u2192 ${green(`v${u.latest_version}`)} [${badge}]`
|
|
144409
|
+
);
|
|
144410
|
+
}
|
|
144411
|
+
for (const d of deprecated) {
|
|
144412
|
+
const entry = toCheck.find((e) => e.slug === d.slug);
|
|
144413
|
+
const id = entry ? compoundId2(entry) : d.slug;
|
|
144414
|
+
const note = d.replacement ? ` \u2192 use ${cyan(d.replacement)}` : "";
|
|
144415
|
+
console.log(` ${yellow(id.padEnd(colWidth))} ${dim(`v${d.installed_version}`)} ${yellow("deprecated")}${note}`);
|
|
144416
|
+
}
|
|
144417
|
+
console.log();
|
|
144418
|
+
if (updates.length === 0) {
|
|
144419
|
+
console.log(green("\u2713") + (target ? ` ${cyan(target)} is up to date.` : " All configs are up to date."));
|
|
144420
|
+
if (deprecated.length > 0) {
|
|
144421
|
+
console.log(yellow("\u26A0") + ` ${deprecated.length} deprecated \u2014 consider replacing them.`);
|
|
144422
|
+
}
|
|
144423
|
+
console.log();
|
|
144213
144424
|
return;
|
|
144214
144425
|
}
|
|
144215
|
-
|
|
144216
|
-
`);
|
|
144217
|
-
|
|
144218
|
-
|
|
144219
|
-
|
|
144220
|
-
|
|
144221
|
-
|
|
144222
|
-
|
|
144223
|
-
|
|
144224
|
-
|
|
144225
|
-
process.
|
|
144226
|
-
|
|
144227
|
-
|
|
144228
|
-
|
|
144229
|
-
|
|
144230
|
-
)
|
|
144231
|
-
|
|
144426
|
+
const noun = updates.length === 1 ? "config" : "configs";
|
|
144427
|
+
console.log(bold(` Updating ${updates.length} ${noun}...`));
|
|
144428
|
+
console.log();
|
|
144429
|
+
const entryBySlug = new Map(toCheck.map((e) => [e.slug, e]));
|
|
144430
|
+
let successCount = 0;
|
|
144431
|
+
let failCount = 0;
|
|
144432
|
+
for (const u of updates) {
|
|
144433
|
+
const entry = entryBySlug.get(u.slug);
|
|
144434
|
+
if (!entry) continue;
|
|
144435
|
+
const id = compoundId2(entry);
|
|
144436
|
+
process.stdout.write(` ${bold(id.padEnd(colWidth))} Downloading... `);
|
|
144437
|
+
try {
|
|
144438
|
+
const result = await downloadAndInstall(entry, u.latest_version, configDir);
|
|
144439
|
+
console.log(green("done") + ` ${dim(`${result.from} \u2192 ${result.to}`)}`);
|
|
144440
|
+
successCount++;
|
|
144441
|
+
} catch (err) {
|
|
144442
|
+
console.log(red("failed"));
|
|
144443
|
+
const msg = err instanceof RegistryError ? err.message : err.message;
|
|
144444
|
+
console.error(` ${"".padEnd(colWidth)} ${red("\u2717")} ${msg}`);
|
|
144445
|
+
failCount++;
|
|
144446
|
+
}
|
|
144232
144447
|
}
|
|
144233
|
-
|
|
144234
|
-
|
|
144235
|
-
`);
|
|
144448
|
+
console.log();
|
|
144449
|
+
if (failCount === 0) {
|
|
144450
|
+
const upToDateNote = up_to_date.length > 0 ? ` ${dim(`${up_to_date.length} already up to date.`)}` : "";
|
|
144451
|
+
console.log(green("\u2713") + ` ${successCount} ${noun} updated.${upToDateNote}`);
|
|
144452
|
+
} else if (successCount > 0) {
|
|
144453
|
+
console.log(yellow("\u26A0") + ` ${successCount} updated, ${failCount} failed.`);
|
|
144454
|
+
} else {
|
|
144455
|
+
console.log(red("\u2717") + ` All updates failed.`);
|
|
144456
|
+
process.exit(1);
|
|
144457
|
+
}
|
|
144458
|
+
console.log(dim(" Restart or reload heku to apply changes."));
|
|
144459
|
+
console.log();
|
|
144236
144460
|
}
|
|
144237
144461
|
|
|
144238
144462
|
// src/cli.ts
|
|
144239
144463
|
var args = process.argv.slice(2);
|
|
144240
144464
|
var command = args[0] ?? "start";
|
|
144241
|
-
if (command !== "update") {
|
|
144242
|
-
checkForUpdate();
|
|
144243
|
-
}
|
|
144244
144465
|
switch (command) {
|
|
144245
144466
|
case "start":
|
|
144246
144467
|
await run(args.slice(1));
|
|
@@ -144296,11 +144517,12 @@ function printUsage() {
|
|
|
144296
144517
|
heku auth setup [service] Interactive credential setup wizard
|
|
144297
144518
|
heku install <target> Install a config from the registry
|
|
144298
144519
|
heku uninstall <target> Remove an installed registry config
|
|
144520
|
+
heku update Update all installed configs to latest versions
|
|
144521
|
+
heku update <config> Update a specific config (e.g. github-http or @ns/github:http)
|
|
144299
144522
|
heku login Log in to the mcp.rtl.space registry
|
|
144300
144523
|
heku logout Log out of the registry
|
|
144301
144524
|
heku publish [file] Publish a config to the registry
|
|
144302
144525
|
heku fork <namespace/slug> Fork a registry config into your namespace
|
|
144303
|
-
heku update Update heku to the latest version
|
|
144304
144526
|
heku help Show this message
|
|
144305
144527
|
|
|
144306
144528
|
HTTP mode:
|