enact-cli 1.0.1 → 1.0.4
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/dist/index.js +891 -215
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -7049,7 +7049,7 @@ var require_public_api = __commonJS((exports) => {
|
|
|
7049
7049
|
});
|
|
7050
7050
|
|
|
7051
7051
|
// src/index.ts
|
|
7052
|
-
var
|
|
7052
|
+
var import_picocolors10 = __toESM(require_picocolors(), 1);
|
|
7053
7053
|
import { parseArgs } from "util";
|
|
7054
7054
|
|
|
7055
7055
|
// node_modules/@clack/prompts/dist/index.mjs
|
|
@@ -7285,6 +7285,9 @@ function BD(e, u) {
|
|
|
7285
7285
|
}
|
|
7286
7286
|
var AD = globalThis.process.platform.startsWith("win");
|
|
7287
7287
|
var S = Symbol("clack:cancel");
|
|
7288
|
+
function pD(e) {
|
|
7289
|
+
return e === S;
|
|
7290
|
+
}
|
|
7288
7291
|
function m(e, u) {
|
|
7289
7292
|
const t = e;
|
|
7290
7293
|
t.isTTY && t.setRawMode(u);
|
|
@@ -7755,55 +7758,82 @@ var $visitAsync = visit.visitAsync;
|
|
|
7755
7758
|
|
|
7756
7759
|
// src/utils/help.ts
|
|
7757
7760
|
var import_picocolors3 = __toESM(require_picocolors(), 1);
|
|
7761
|
+
import { readFileSync } from "fs";
|
|
7762
|
+
import { join } from "path";
|
|
7763
|
+
var __dirname = "/Users/keithgroves/projects/keithagroves/enact-project/enact-cli/src/utils";
|
|
7764
|
+
function getVersion() {
|
|
7765
|
+
try {
|
|
7766
|
+
const packageJsonPath = join(__dirname, "../../package.json");
|
|
7767
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf8"));
|
|
7768
|
+
return packageJson.version || "0.1.0";
|
|
7769
|
+
} catch (error) {
|
|
7770
|
+
return "0.1.0";
|
|
7771
|
+
}
|
|
7772
|
+
}
|
|
7758
7773
|
function showHelp() {
|
|
7774
|
+
const version = getVersion();
|
|
7759
7775
|
console.log(`
|
|
7760
|
-
${import_picocolors3.default.bold("Enact CLI")} ${import_picocolors3.default.dim(
|
|
7761
|
-
${import_picocolors3.default.dim("A
|
|
7776
|
+
${import_picocolors3.default.bold("Enact CLI")} ${import_picocolors3.default.dim(`v${version}`)}
|
|
7777
|
+
${import_picocolors3.default.dim("A CLI tool for managing and publishing Enact tools")}
|
|
7762
7778
|
|
|
7763
7779
|
${import_picocolors3.default.bold("Usage:")}
|
|
7764
7780
|
${import_picocolors3.default.cyan("enact")} ${import_picocolors3.default.green("<command>")} [options]
|
|
7765
7781
|
|
|
7766
7782
|
${import_picocolors3.default.bold("Commands:")}
|
|
7767
|
-
${import_picocolors3.default.green("
|
|
7768
|
-
|
|
7769
|
-
${import_picocolors3.default.
|
|
7770
|
-
${import_picocolors3.default.
|
|
7771
|
-
${import_picocolors3.default.
|
|
7783
|
+
${import_picocolors3.default.green("auth")} Manage authentication (login, logout, status, token)
|
|
7784
|
+
${import_picocolors3.default.green("init")} Create a new tool definition
|
|
7785
|
+
${import_picocolors3.default.green("publish")} Publish a tool to the registry
|
|
7786
|
+
${import_picocolors3.default.green("search")} Search for tools in the registry
|
|
7787
|
+
${import_picocolors3.default.green("remote")} Manage remote servers (add, list, remove)
|
|
7788
|
+
${import_picocolors3.default.green("user")} User operations (get public key)
|
|
7789
|
+
|
|
7790
|
+
${import_picocolors3.default.bold("Global Options:")}
|
|
7791
|
+
${import_picocolors3.default.yellow("--help, -h")} Show help message
|
|
7792
|
+
${import_picocolors3.default.yellow("--version, -v")} Show version information
|
|
7772
7793
|
|
|
7773
7794
|
${import_picocolors3.default.bold("Examples:")}
|
|
7774
|
-
${import_picocolors3.default.cyan("enact")}
|
|
7775
|
-
${import_picocolors3.default.cyan("enact")} ${import_picocolors3.default.green("
|
|
7795
|
+
${import_picocolors3.default.cyan("enact")} ${import_picocolors3.default.dim("# Interactive mode")}
|
|
7796
|
+
${import_picocolors3.default.cyan("enact")} ${import_picocolors3.default.green("search")} ${import_picocolors3.default.yellow("--tags")} web,api ${import_picocolors3.default.dim("# Search tools by tags")}
|
|
7797
|
+
${import_picocolors3.default.cyan("enact")} ${import_picocolors3.default.green("publish")} my-tool.yaml ${import_picocolors3.default.dim("# Publish a tool")}
|
|
7798
|
+
${import_picocolors3.default.cyan("enact")} ${import_picocolors3.default.green("auth")} login ${import_picocolors3.default.dim("# Login with OAuth")}
|
|
7799
|
+
${import_picocolors3.default.cyan("enact")} ${import_picocolors3.default.green("init")} ${import_picocolors3.default.yellow("--minimal")} ${import_picocolors3.default.dim("# Create minimal tool template")}
|
|
7800
|
+
|
|
7801
|
+
${import_picocolors3.default.bold("More Help:")}
|
|
7802
|
+
${import_picocolors3.default.cyan("enact")} ${import_picocolors3.default.green("<command>")} ${import_picocolors3.default.yellow("--help")} ${import_picocolors3.default.dim("# Show command-specific help")}
|
|
7776
7803
|
`);
|
|
7777
7804
|
}
|
|
7778
7805
|
function showVersion() {
|
|
7779
|
-
|
|
7806
|
+
const version = getVersion();
|
|
7807
|
+
console.log(`enact-cli v${version}`);
|
|
7780
7808
|
}
|
|
7781
7809
|
function showPublishHelp() {
|
|
7782
7810
|
console.log(`
|
|
7783
7811
|
${import_picocolors3.default.bold("Usage:")} ${import_picocolors3.default.cyan("enact")} ${import_picocolors3.default.green("publish")} [options] [file]
|
|
7784
7812
|
|
|
7785
|
-
${import_picocolors3.default.bold("
|
|
7813
|
+
${import_picocolors3.default.bold("Publish a tool to the Enact registry")}
|
|
7786
7814
|
|
|
7787
7815
|
${import_picocolors3.default.bold("Arguments:")}
|
|
7788
|
-
${import_picocolors3.default.
|
|
7816
|
+
${import_picocolors3.default.blue("file")} The tool definition file to publish (YAML format)
|
|
7789
7817
|
|
|
7790
7818
|
${import_picocolors3.default.bold("Options:")}
|
|
7791
|
-
${import_picocolors3.default.yellow("--help, -h")}
|
|
7792
|
-
${import_picocolors3.default.yellow("--url")}
|
|
7819
|
+
${import_picocolors3.default.yellow("--help, -h")} Show this help message
|
|
7820
|
+
${import_picocolors3.default.yellow("--url")} Specify the registry URL
|
|
7821
|
+
${import_picocolors3.default.yellow("--token, -t")} Specify authentication token
|
|
7793
7822
|
|
|
7794
7823
|
${import_picocolors3.default.bold("Examples:")}
|
|
7795
|
-
${import_picocolors3.default.cyan("enact")} ${import_picocolors3.default.green("publish")}
|
|
7796
|
-
${import_picocolors3.default.cyan("enact")} ${import_picocolors3.default.green("publish")} ${import_picocolors3.default.yellow("--url")} https://example.com
|
|
7824
|
+
${import_picocolors3.default.cyan("enact")} ${import_picocolors3.default.green("publish")} my-tool.yaml
|
|
7825
|
+
${import_picocolors3.default.cyan("enact")} ${import_picocolors3.default.green("publish")} ${import_picocolors3.default.yellow("--url")} https://registry.example.com my-tool.yaml
|
|
7826
|
+
${import_picocolors3.default.cyan("enact")} ${import_picocolors3.default.green("publish")} ${import_picocolors3.default.yellow("--token")} abc123 my-tool.yaml
|
|
7797
7827
|
`);
|
|
7798
7828
|
}
|
|
7799
7829
|
|
|
7800
7830
|
// src/utils/config.ts
|
|
7801
7831
|
import { homedir } from "os";
|
|
7802
|
-
import { join } from "path";
|
|
7832
|
+
import { join as join2 } from "path";
|
|
7803
7833
|
import { existsSync } from "fs";
|
|
7804
7834
|
import { mkdir, readFile, writeFile } from "fs/promises";
|
|
7805
|
-
var CONFIG_DIR =
|
|
7806
|
-
var CONFIG_FILE =
|
|
7835
|
+
var CONFIG_DIR = join2(homedir(), ".enact");
|
|
7836
|
+
var CONFIG_FILE = join2(CONFIG_DIR, "config.json");
|
|
7807
7837
|
async function ensureConfig() {
|
|
7808
7838
|
if (!existsSync(CONFIG_DIR)) {
|
|
7809
7839
|
await mkdir(CONFIG_DIR, { recursive: true });
|
|
@@ -7855,18 +7885,304 @@ async function getDefaultUrl() {
|
|
|
7855
7885
|
var import_picocolors4 = __toESM(require_picocolors(), 1);
|
|
7856
7886
|
import { existsSync as existsSync2 } from "fs";
|
|
7857
7887
|
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
|
|
7858
|
-
import { join as
|
|
7888
|
+
import { join as join3 } from "path";
|
|
7859
7889
|
import { homedir as homedir2 } from "os";
|
|
7860
7890
|
import { createServer } from "http";
|
|
7861
7891
|
import { parse } from "url";
|
|
7862
7892
|
import { randomBytes, createHash } from "crypto";
|
|
7863
7893
|
import { exec } from "child_process";
|
|
7864
7894
|
import { promisify } from "util";
|
|
7895
|
+
|
|
7896
|
+
// src/api/enact-api.ts
|
|
7897
|
+
class EnactApiClient {
|
|
7898
|
+
baseUrl;
|
|
7899
|
+
supabaseUrl;
|
|
7900
|
+
constructor(baseUrl = "https://enact.tools", supabaseUrl = "https://xjnhhxwxovjifdxdwzih.supabase.co") {
|
|
7901
|
+
this.baseUrl = baseUrl.replace(/\/$/, "");
|
|
7902
|
+
this.supabaseUrl = supabaseUrl.replace(/\/$/, "");
|
|
7903
|
+
}
|
|
7904
|
+
async makeRequest(endpoint, options = {}, token, tokenType = "jwt") {
|
|
7905
|
+
const url = endpoint.startsWith("http") ? endpoint : `${this.supabaseUrl}${endpoint}`;
|
|
7906
|
+
const headers = {
|
|
7907
|
+
"Content-Type": "application/json",
|
|
7908
|
+
...options.headers
|
|
7909
|
+
};
|
|
7910
|
+
if (token) {
|
|
7911
|
+
if (tokenType === "jwt") {
|
|
7912
|
+
headers["Authorization"] = `Bearer ${token}`;
|
|
7913
|
+
} else {
|
|
7914
|
+
headers["X-API-Key"] = token;
|
|
7915
|
+
}
|
|
7916
|
+
}
|
|
7917
|
+
const response = await fetch(url, {
|
|
7918
|
+
...options,
|
|
7919
|
+
headers
|
|
7920
|
+
});
|
|
7921
|
+
if (!response.ok) {
|
|
7922
|
+
const errorData = await response.json().catch(() => ({ error: "Unknown error" }));
|
|
7923
|
+
throw new EnactApiError(`${errorData.error || response.statusText}`, response.status, endpoint);
|
|
7924
|
+
}
|
|
7925
|
+
const responseData = await response.json();
|
|
7926
|
+
if (true) {
|
|
7927
|
+
console.log(`API Response for ${endpoint}:`, responseData);
|
|
7928
|
+
}
|
|
7929
|
+
return responseData;
|
|
7930
|
+
}
|
|
7931
|
+
async getTools(params) {
|
|
7932
|
+
const searchParams = new URLSearchParams;
|
|
7933
|
+
if (params?.limit)
|
|
7934
|
+
searchParams.set("limit", params.limit.toString());
|
|
7935
|
+
if (params?.offset)
|
|
7936
|
+
searchParams.set("offset", params.offset.toString());
|
|
7937
|
+
if (params?.tags)
|
|
7938
|
+
searchParams.set("tags", params.tags.join(","));
|
|
7939
|
+
if (params?.author)
|
|
7940
|
+
searchParams.set("author", params.author);
|
|
7941
|
+
const query = searchParams.toString();
|
|
7942
|
+
const endpoint = `/functions/v1/tools${query ? `?${query}` : ""}`;
|
|
7943
|
+
const response = await this.makeRequest(endpoint);
|
|
7944
|
+
if (Array.isArray(response)) {
|
|
7945
|
+
return response;
|
|
7946
|
+
} else if (response.data && Array.isArray(response.data)) {
|
|
7947
|
+
return response.data;
|
|
7948
|
+
} else if (response.tools && Array.isArray(response.tools)) {
|
|
7949
|
+
return response.tools;
|
|
7950
|
+
} else {
|
|
7951
|
+
console.warn("Unexpected response structure for getTools:", response);
|
|
7952
|
+
return [];
|
|
7953
|
+
}
|
|
7954
|
+
}
|
|
7955
|
+
async getTool(name) {
|
|
7956
|
+
const endpoint = `/functions/v1/tools/${encodeURIComponent(name)}`;
|
|
7957
|
+
return this.makeRequest(endpoint);
|
|
7958
|
+
}
|
|
7959
|
+
async getToolUsage(name) {
|
|
7960
|
+
const endpoint = `/functions/v1/tools/${encodeURIComponent(name)}/usage`;
|
|
7961
|
+
return this.makeRequest(endpoint);
|
|
7962
|
+
}
|
|
7963
|
+
async logToolUsage(name, usage) {
|
|
7964
|
+
const endpoint = `/functions/v1/tools/${encodeURIComponent(name)}/usage`;
|
|
7965
|
+
return this.makeRequest(endpoint, {
|
|
7966
|
+
method: "POST",
|
|
7967
|
+
body: JSON.stringify(usage)
|
|
7968
|
+
});
|
|
7969
|
+
}
|
|
7970
|
+
async searchTools(query) {
|
|
7971
|
+
const endpoint = "/functions/v1/tools-search";
|
|
7972
|
+
const response = await this.makeRequest(endpoint, {
|
|
7973
|
+
method: "POST",
|
|
7974
|
+
body: JSON.stringify(query)
|
|
7975
|
+
});
|
|
7976
|
+
if (Array.isArray(response)) {
|
|
7977
|
+
return response;
|
|
7978
|
+
} else if (response.data && Array.isArray(response.data)) {
|
|
7979
|
+
return response.data;
|
|
7980
|
+
} else if (response.results && Array.isArray(response.results)) {
|
|
7981
|
+
return response.results;
|
|
7982
|
+
} else if (response.tools && Array.isArray(response.tools)) {
|
|
7983
|
+
return response.tools;
|
|
7984
|
+
} else {
|
|
7985
|
+
console.warn("Unexpected response structure for searchTools:", response);
|
|
7986
|
+
return [];
|
|
7987
|
+
}
|
|
7988
|
+
}
|
|
7989
|
+
async publishTool(tool, token, tokenType = "cli") {
|
|
7990
|
+
const endpoint = "/functions/v1/tools";
|
|
7991
|
+
return this.makeRequest(endpoint, {
|
|
7992
|
+
method: "POST",
|
|
7993
|
+
body: JSON.stringify(tool)
|
|
7994
|
+
}, token, tokenType);
|
|
7995
|
+
}
|
|
7996
|
+
async updateTool(name, tool, token, tokenType = "cli") {
|
|
7997
|
+
const endpoint = `/functions/v1/tools/${encodeURIComponent(name)}`;
|
|
7998
|
+
return this.makeRequest(endpoint, {
|
|
7999
|
+
method: "PUT",
|
|
8000
|
+
body: JSON.stringify(tool)
|
|
8001
|
+
}, token, tokenType);
|
|
8002
|
+
}
|
|
8003
|
+
async deleteTool(name, token, tokenType = "cli") {
|
|
8004
|
+
const endpoint = `/functions/v1/tools/${encodeURIComponent(name)}`;
|
|
8005
|
+
return this.makeRequest(endpoint, {
|
|
8006
|
+
method: "DELETE"
|
|
8007
|
+
}, token, tokenType);
|
|
8008
|
+
}
|
|
8009
|
+
async createCLIToken(tokenData, jwtToken) {
|
|
8010
|
+
const endpoint = "/functions/v1/cli-token";
|
|
8011
|
+
return this.makeRequest(endpoint, {
|
|
8012
|
+
method: "POST",
|
|
8013
|
+
body: JSON.stringify(tokenData)
|
|
8014
|
+
}, jwtToken, "jwt");
|
|
8015
|
+
}
|
|
8016
|
+
async getCLITokens(jwtToken) {
|
|
8017
|
+
const endpoint = "/functions/v1/cli-token";
|
|
8018
|
+
return this.makeRequest(endpoint, {
|
|
8019
|
+
method: "GET"
|
|
8020
|
+
}, jwtToken, "jwt");
|
|
8021
|
+
}
|
|
8022
|
+
async deleteCLIToken(tokenId, jwtToken) {
|
|
8023
|
+
const endpoint = `/functions/v1/cli-token/${tokenId}`;
|
|
8024
|
+
return this.makeRequest(endpoint, {
|
|
8025
|
+
method: "DELETE"
|
|
8026
|
+
}, jwtToken, "jwt");
|
|
8027
|
+
}
|
|
8028
|
+
async exchangeOAuthCode(oauthData) {
|
|
8029
|
+
const endpoint = "/functions/v1/cli-oauth";
|
|
8030
|
+
return this.makeRequest(endpoint, {
|
|
8031
|
+
method: "POST",
|
|
8032
|
+
body: JSON.stringify(oauthData)
|
|
8033
|
+
});
|
|
8034
|
+
}
|
|
8035
|
+
async generateEmbeddings(data, token, tokenType = "cli") {
|
|
8036
|
+
const endpoint = "/functions/v1/generate-embeddings";
|
|
8037
|
+
return this.makeRequest(endpoint, {
|
|
8038
|
+
method: "POST",
|
|
8039
|
+
body: JSON.stringify(data)
|
|
8040
|
+
}, token, tokenType);
|
|
8041
|
+
}
|
|
8042
|
+
async toolExists(name) {
|
|
8043
|
+
try {
|
|
8044
|
+
await this.getTool(name);
|
|
8045
|
+
return true;
|
|
8046
|
+
} catch (error) {
|
|
8047
|
+
if (error instanceof Error && error.message.includes("404")) {
|
|
8048
|
+
return false;
|
|
8049
|
+
}
|
|
8050
|
+
throw error;
|
|
8051
|
+
}
|
|
8052
|
+
}
|
|
8053
|
+
async publishOrUpdateTool(tool, token, tokenType = "cli") {
|
|
8054
|
+
let exists;
|
|
8055
|
+
try {
|
|
8056
|
+
exists = await this.toolExists(tool.name);
|
|
8057
|
+
} catch (error) {
|
|
8058
|
+
exists = false;
|
|
8059
|
+
}
|
|
8060
|
+
if (exists) {
|
|
8061
|
+
const result = await this.updateTool(tool.name, tool, token, tokenType);
|
|
8062
|
+
return { isUpdate: true, result };
|
|
8063
|
+
} else {
|
|
8064
|
+
const result = await this.publishTool(tool, token, tokenType);
|
|
8065
|
+
return { isUpdate: false, result };
|
|
8066
|
+
}
|
|
8067
|
+
}
|
|
8068
|
+
async getToolsByTags(tags, limit = 20) {
|
|
8069
|
+
return this.searchTools({
|
|
8070
|
+
query: tags.join(" "),
|
|
8071
|
+
tags,
|
|
8072
|
+
limit
|
|
8073
|
+
});
|
|
8074
|
+
}
|
|
8075
|
+
async getToolsByAuthor(author, limit = 20) {
|
|
8076
|
+
return this.getTools({
|
|
8077
|
+
author,
|
|
8078
|
+
limit
|
|
8079
|
+
});
|
|
8080
|
+
}
|
|
8081
|
+
async getUserPublicKey(userId) {
|
|
8082
|
+
const url = `${this.supabaseUrl}/functions/v1/tools/user/public-key/${userId}`;
|
|
8083
|
+
const headers = {
|
|
8084
|
+
Accept: "application/json",
|
|
8085
|
+
"Content-Type": "application/json"
|
|
8086
|
+
};
|
|
8087
|
+
try {
|
|
8088
|
+
const response = await fetch(url, {
|
|
8089
|
+
method: "GET",
|
|
8090
|
+
headers
|
|
8091
|
+
});
|
|
8092
|
+
if (!response.ok) {
|
|
8093
|
+
const errorText = await response.text();
|
|
8094
|
+
let errorMessage = `HTTP ${response.status}: ${response.statusText}`;
|
|
8095
|
+
try {
|
|
8096
|
+
const errorJson = JSON.parse(errorText);
|
|
8097
|
+
if (errorJson.message) {
|
|
8098
|
+
errorMessage = errorJson.message;
|
|
8099
|
+
} else if (errorJson.error) {
|
|
8100
|
+
errorMessage = errorJson.error;
|
|
8101
|
+
}
|
|
8102
|
+
} catch {}
|
|
8103
|
+
throw new EnactApiError(errorMessage, response.status);
|
|
8104
|
+
}
|
|
8105
|
+
const data = await response.json();
|
|
8106
|
+
return data;
|
|
8107
|
+
} catch (error) {
|
|
8108
|
+
if (error instanceof EnactApiError) {
|
|
8109
|
+
throw error;
|
|
8110
|
+
}
|
|
8111
|
+
if (error instanceof Error) {
|
|
8112
|
+
if (error.message.includes("fetch")) {
|
|
8113
|
+
throw new EnactApiError("Network error: Could not connect to Enact API", 0);
|
|
8114
|
+
}
|
|
8115
|
+
throw new EnactApiError(error.message, 0);
|
|
8116
|
+
}
|
|
8117
|
+
throw new EnactApiError("Unknown error occurred", 0);
|
|
8118
|
+
}
|
|
8119
|
+
}
|
|
8120
|
+
generateOAuthUrl(options) {
|
|
8121
|
+
const params = new URLSearchParams({
|
|
8122
|
+
response_type: "code",
|
|
8123
|
+
client_id: options.clientId,
|
|
8124
|
+
redirect_uri: options.redirectUri,
|
|
8125
|
+
scope: options.scope,
|
|
8126
|
+
state: options.state,
|
|
8127
|
+
code_challenge: options.codeChallenge,
|
|
8128
|
+
code_challenge_method: options.codeChallengeMethod
|
|
8129
|
+
});
|
|
8130
|
+
return `${this.baseUrl}/auth/cli/oauth?${params.toString()}`;
|
|
8131
|
+
}
|
|
8132
|
+
validateTool(tool) {
|
|
8133
|
+
const errors2 = [];
|
|
8134
|
+
if (!tool.name || typeof tool.name !== "string") {
|
|
8135
|
+
errors2.push("Tool name is required and must be a string");
|
|
8136
|
+
} else if (!/^[a-zA-Z0-9_-]+\/[a-zA-Z0-9_\/-]+$/.test(tool.name)) {
|
|
8137
|
+
errors2.push("Tool name must follow hierarchical format: org/category/tool-name");
|
|
8138
|
+
}
|
|
8139
|
+
if (!tool.description || typeof tool.description !== "string") {
|
|
8140
|
+
errors2.push("Tool description is required and must be a string");
|
|
8141
|
+
}
|
|
8142
|
+
if (!tool.command || typeof tool.command !== "string") {
|
|
8143
|
+
errors2.push("Tool command is required and must be a string");
|
|
8144
|
+
}
|
|
8145
|
+
if (tool.timeout && typeof tool.timeout === "string") {
|
|
8146
|
+
if (!/^\d+[smh]$/.test(tool.timeout)) {
|
|
8147
|
+
errors2.push('Timeout must be in Go duration format (e.g., "30s", "5m", "1h")');
|
|
8148
|
+
}
|
|
8149
|
+
}
|
|
8150
|
+
if (tool.tags && !Array.isArray(tool.tags)) {
|
|
8151
|
+
errors2.push("Tags must be an array of strings");
|
|
8152
|
+
}
|
|
8153
|
+
if (tool.inputSchema && typeof tool.inputSchema !== "object") {
|
|
8154
|
+
errors2.push("inputSchema must be a valid JSON Schema object");
|
|
8155
|
+
}
|
|
8156
|
+
if (tool.outputSchema && typeof tool.outputSchema !== "object") {
|
|
8157
|
+
errors2.push("outputSchema must be a valid JSON Schema object");
|
|
8158
|
+
}
|
|
8159
|
+
return {
|
|
8160
|
+
valid: errors2.length === 0,
|
|
8161
|
+
errors: errors2
|
|
8162
|
+
};
|
|
8163
|
+
}
|
|
8164
|
+
}
|
|
8165
|
+
var enactApi = new EnactApiClient;
|
|
8166
|
+
|
|
8167
|
+
class EnactApiError extends Error {
|
|
8168
|
+
statusCode;
|
|
8169
|
+
endpoint;
|
|
8170
|
+
constructor(message, statusCode, endpoint) {
|
|
8171
|
+
super(message);
|
|
8172
|
+
this.statusCode = statusCode;
|
|
8173
|
+
this.endpoint = endpoint;
|
|
8174
|
+
this.name = "EnactApiError";
|
|
8175
|
+
}
|
|
8176
|
+
}
|
|
8177
|
+
function createEnactApiClient(baseUrl, supabaseUrl) {
|
|
8178
|
+
return new EnactApiClient(baseUrl, supabaseUrl);
|
|
8179
|
+
}
|
|
8180
|
+
|
|
8181
|
+
// src/commands/auth.ts
|
|
7865
8182
|
var execAsync = promisify(exec);
|
|
7866
|
-
var CONFIG_DIR2 =
|
|
7867
|
-
var AUTH_FILE =
|
|
8183
|
+
var CONFIG_DIR2 = join3(homedir2(), ".enact");
|
|
8184
|
+
var AUTH_FILE = join3(CONFIG_DIR2, "auth.json");
|
|
7868
8185
|
var DEFAULT_SERVER = "https://enact.tools";
|
|
7869
|
-
var SUPABASE_PROJECT_URL = "https://xjnhhxwxovjifdxdwzih.supabase.co";
|
|
7870
8186
|
async function handleAuthCommand(args, options) {
|
|
7871
8187
|
if (options.help || !args[0]) {
|
|
7872
8188
|
console.log(`
|
|
@@ -7930,16 +8246,14 @@ async function handleLogin(serverUrl, callbackPort) {
|
|
|
7930
8246
|
const codeChallenge = generateCodeChallenge(codeVerifier);
|
|
7931
8247
|
const state = generateState();
|
|
7932
8248
|
const redirectUri = `http://localhost:${callbackPort}/callback`;
|
|
7933
|
-
const
|
|
7934
|
-
|
|
7935
|
-
|
|
7936
|
-
redirect_uri: redirectUri,
|
|
8249
|
+
const authUrl = enactApi.generateOAuthUrl({
|
|
8250
|
+
clientId: "enact-cli",
|
|
8251
|
+
redirectUri,
|
|
7937
8252
|
scope: "publish read write",
|
|
7938
8253
|
state,
|
|
7939
|
-
|
|
7940
|
-
|
|
8254
|
+
codeChallenge,
|
|
8255
|
+
codeChallengeMethod: "S256"
|
|
7941
8256
|
});
|
|
7942
|
-
const authUrl = `${serverUrl}/auth/cli/oauth?${authParams.toString()}`;
|
|
7943
8257
|
const s = Y2();
|
|
7944
8258
|
s.start("Starting OAuth flow...");
|
|
7945
8259
|
let server = null;
|
|
@@ -8102,49 +8416,20 @@ async function startCallbackServerWithFallback(port, serverUrl, codeVerifier, st
|
|
|
8102
8416
|
});
|
|
8103
8417
|
}
|
|
8104
8418
|
async function exchangeCodeForToken(code, redirectUri, codeVerifier, serverUrl) {
|
|
8105
|
-
|
|
8106
|
-
console.log(`Exchanging code for token at: ${tokenEndpoint}`);
|
|
8419
|
+
console.log(`Exchanging code for token...`);
|
|
8107
8420
|
console.log("Exchange params:", {
|
|
8108
8421
|
code: code.substring(0, 8) + "...",
|
|
8109
8422
|
redirectUri,
|
|
8110
8423
|
codeVerifier: codeVerifier.substring(0, 8) + "..."
|
|
8111
8424
|
});
|
|
8112
|
-
const controller = new AbortController;
|
|
8113
|
-
const timeoutId = setTimeout(() => controller.abort(), 30000);
|
|
8114
8425
|
try {
|
|
8115
|
-
const
|
|
8116
|
-
|
|
8117
|
-
|
|
8118
|
-
|
|
8119
|
-
|
|
8120
|
-
|
|
8121
|
-
grant_type: "authorization_code",
|
|
8122
|
-
code,
|
|
8123
|
-
redirect_uri: redirectUri,
|
|
8124
|
-
client_id: "enact-cli",
|
|
8125
|
-
code_verifier: codeVerifier
|
|
8126
|
-
}),
|
|
8127
|
-
signal: controller.signal
|
|
8426
|
+
const tokenData = await enactApi.exchangeOAuthCode({
|
|
8427
|
+
grant_type: "authorization_code",
|
|
8428
|
+
code,
|
|
8429
|
+
redirect_uri: redirectUri,
|
|
8430
|
+
client_id: "enact-cli",
|
|
8431
|
+
code_verifier: codeVerifier
|
|
8128
8432
|
});
|
|
8129
|
-
clearTimeout(timeoutId);
|
|
8130
|
-
const responseText = await tokenResponse.text();
|
|
8131
|
-
console.log("Token exchange response status:", tokenResponse.status);
|
|
8132
|
-
if (!tokenResponse.ok) {
|
|
8133
|
-
console.error("Token exchange failed with status:", tokenResponse.status);
|
|
8134
|
-
console.error("Response body:", responseText);
|
|
8135
|
-
throw new Error(`Token exchange failed (${tokenResponse.status}): ${responseText}`);
|
|
8136
|
-
}
|
|
8137
|
-
let tokenData;
|
|
8138
|
-
try {
|
|
8139
|
-
tokenData = JSON.parse(responseText);
|
|
8140
|
-
} catch (parseError) {
|
|
8141
|
-
console.error("Failed to parse token response as JSON:", responseText);
|
|
8142
|
-
throw new Error(`Invalid JSON response from token endpoint`);
|
|
8143
|
-
}
|
|
8144
|
-
if (!tokenData.access_token) {
|
|
8145
|
-
console.error("No access token in response:", tokenData);
|
|
8146
|
-
throw new Error("No access token received from server");
|
|
8147
|
-
}
|
|
8148
8433
|
const expiresAt = new Date(Date.now() + tokenData.expires_in * 1000);
|
|
8149
8434
|
await writeAuthConfig({
|
|
8150
8435
|
token: tokenData.access_token,
|
|
@@ -8155,8 +8440,8 @@ async function exchangeCodeForToken(code, redirectUri, codeVerifier, serverUrl)
|
|
|
8155
8440
|
});
|
|
8156
8441
|
console.log("✓ Token stored successfully");
|
|
8157
8442
|
} catch (error) {
|
|
8158
|
-
if (error instanceof
|
|
8159
|
-
throw new Error(
|
|
8443
|
+
if (error instanceof EnactApiError) {
|
|
8444
|
+
throw new Error(`Token exchange failed: ${error.message}`);
|
|
8160
8445
|
}
|
|
8161
8446
|
throw error;
|
|
8162
8447
|
}
|
|
@@ -8295,15 +8580,13 @@ async function handlePublishCommand(args, options) {
|
|
|
8295
8580
|
return;
|
|
8296
8581
|
}
|
|
8297
8582
|
Ie(import_picocolors5.default.bgBlue(import_picocolors5.default.white(" Publish Enact Tool ")));
|
|
8298
|
-
let
|
|
8583
|
+
let token;
|
|
8299
8584
|
try {
|
|
8300
8585
|
if (options.token) {
|
|
8301
|
-
|
|
8302
|
-
"Content-Type": "application/json",
|
|
8303
|
-
"X-API-Key": options.token
|
|
8304
|
-
};
|
|
8586
|
+
token = options.token;
|
|
8305
8587
|
} else {
|
|
8306
|
-
authHeaders = await getAuthHeaders();
|
|
8588
|
+
const authHeaders = await getAuthHeaders();
|
|
8589
|
+
token = authHeaders["X-API-Key"];
|
|
8307
8590
|
}
|
|
8308
8591
|
} catch (error) {
|
|
8309
8592
|
Se(import_picocolors5.default.red(`✗ Authentication required. Run "enact auth login" to authenticate.`));
|
|
@@ -8311,45 +8594,8 @@ async function handlePublishCommand(args, options) {
|
|
|
8311
8594
|
}
|
|
8312
8595
|
let filePath = args[0];
|
|
8313
8596
|
if (!filePath) {
|
|
8314
|
-
|
|
8315
|
-
if (
|
|
8316
|
-
const action = await ve({
|
|
8317
|
-
message: "Select a tool manifest to publish:",
|
|
8318
|
-
options: [
|
|
8319
|
-
{ value: "select", label: "Choose from recent files" },
|
|
8320
|
-
{ value: "new", label: "Specify a new file" }
|
|
8321
|
-
]
|
|
8322
|
-
});
|
|
8323
|
-
if (action === "select") {
|
|
8324
|
-
const fileOptions = history.filter((file) => existsSync3(file) && isEnactFile(file)).map((file) => ({
|
|
8325
|
-
value: file,
|
|
8326
|
-
label: file
|
|
8327
|
-
}));
|
|
8328
|
-
if (fileOptions.length > 0) {
|
|
8329
|
-
filePath = await ve({
|
|
8330
|
-
message: "Select a tool manifest:",
|
|
8331
|
-
options: fileOptions
|
|
8332
|
-
});
|
|
8333
|
-
} else {
|
|
8334
|
-
Me("No recent Enact tool manifests found.", "History");
|
|
8335
|
-
filePath = await he({
|
|
8336
|
-
message: "Enter the path to the tool manifest (.yaml or .yml):",
|
|
8337
|
-
validate: validateEnactFile
|
|
8338
|
-
});
|
|
8339
|
-
}
|
|
8340
|
-
} else {
|
|
8341
|
-
filePath = await he({
|
|
8342
|
-
message: "Enter the path to the tool manifest (.yaml or .yml):",
|
|
8343
|
-
validate: validateEnactFile
|
|
8344
|
-
});
|
|
8345
|
-
}
|
|
8346
|
-
} else {
|
|
8347
|
-
filePath = await he({
|
|
8348
|
-
message: "Enter the path to the tool manifest (.yaml or .yml):",
|
|
8349
|
-
validate: validateEnactFile
|
|
8350
|
-
});
|
|
8351
|
-
}
|
|
8352
|
-
if (filePath === null) {
|
|
8597
|
+
filePath = await getFilePathInteractively();
|
|
8598
|
+
if (!filePath) {
|
|
8353
8599
|
Se(import_picocolors5.default.yellow("Operation cancelled"));
|
|
8354
8600
|
return;
|
|
8355
8601
|
}
|
|
@@ -8364,9 +8610,11 @@ async function handlePublishCommand(args, options) {
|
|
|
8364
8610
|
try {
|
|
8365
8611
|
const content = await readFile3(filePath, "utf8");
|
|
8366
8612
|
toolDefinition = $parse(content);
|
|
8367
|
-
const validation =
|
|
8368
|
-
if (validation) {
|
|
8369
|
-
Se(import_picocolors5.default.red(`Invalid tool manifest:
|
|
8613
|
+
const validation = enactApi.validateTool(toolDefinition);
|
|
8614
|
+
if (!validation.valid) {
|
|
8615
|
+
Se(import_picocolors5.default.red(`Invalid tool manifest:
|
|
8616
|
+
${validation.errors.join(`
|
|
8617
|
+
`)}`));
|
|
8370
8618
|
return;
|
|
8371
8619
|
}
|
|
8372
8620
|
} catch (error) {
|
|
@@ -8426,66 +8674,38 @@ Command: ${import_picocolors5.default.dim(toolDefinition.command)}`, "Tool Detai
|
|
|
8426
8674
|
const spinner = Y2();
|
|
8427
8675
|
spinner.start("Publishing tool to Enact registry");
|
|
8428
8676
|
try {
|
|
8429
|
-
|
|
8430
|
-
|
|
8431
|
-
|
|
8432
|
-
method: "GET",
|
|
8433
|
-
headers: {
|
|
8434
|
-
"Content-Type": "application/json"
|
|
8435
|
-
}
|
|
8436
|
-
});
|
|
8437
|
-
if (checkResponse.ok) {
|
|
8438
|
-
isUpdate = true;
|
|
8439
|
-
spinner.message("Tool exists, updating...");
|
|
8440
|
-
}
|
|
8441
|
-
} catch (checkError) {}
|
|
8442
|
-
const toolData = {
|
|
8443
|
-
...toolDefinition,
|
|
8444
|
-
inputSchema: toolDefinition.inputSchema,
|
|
8445
|
-
outputSchema: toolDefinition.outputSchema,
|
|
8446
|
-
env: toolDefinition.env,
|
|
8447
|
-
enact: toolDefinition.enact || "1.0.0"
|
|
8448
|
-
};
|
|
8449
|
-
const method = isUpdate ? "PUT" : "POST";
|
|
8450
|
-
const url = isUpdate ? `${apiUrl}/${encodeURIComponent(toolDefinition.name)}` : apiUrl;
|
|
8451
|
-
spinner.message(`Publishing to URL: ${url} with method: ${method}`);
|
|
8452
|
-
const publishResponse = await fetch(url, {
|
|
8453
|
-
method,
|
|
8454
|
-
headers: authHeaders,
|
|
8455
|
-
body: JSON.stringify(toolData)
|
|
8456
|
-
});
|
|
8457
|
-
if (!publishResponse.ok) {
|
|
8458
|
-
const errorData = await publishResponse.json().catch(() => ({ error: "Unknown error" }));
|
|
8459
|
-
if (publishResponse.status === 409) {
|
|
8460
|
-
throw new Error(`Tool '${toolDefinition.name}' already exists. Use a different name or update the existing tool.`);
|
|
8461
|
-
} else if (publishResponse.status === 400) {
|
|
8462
|
-
throw new Error(`Invalid tool definition: ${errorData.error || "Bad request"}`);
|
|
8463
|
-
} else {
|
|
8464
|
-
throw new Error(`Publish failed (${publishResponse.status}): ${errorData.error || publishResponse.statusText}`);
|
|
8465
|
-
}
|
|
8466
|
-
}
|
|
8467
|
-
const result = await publishResponse.json();
|
|
8677
|
+
const apiClient = apiUrl ? createEnactApiClient(apiUrl) : enactApi;
|
|
8678
|
+
Me(`Using API URL: ${import_picocolors5.default.cyan(apiClient.baseUrl)}`, "API Client");
|
|
8679
|
+
const result = await apiClient.publishOrUpdateTool(toolDefinition, token, "cli");
|
|
8468
8680
|
await addToHistory(filePath);
|
|
8469
|
-
spinner.stop(`Tool ${isUpdate ? "updated" : "published"} successfully`);
|
|
8470
|
-
let successMessage = `✓ ${import_picocolors5.default.bold(toolDefinition.name)} ${isUpdate ? "updated" : "published"} to Enact registry`;
|
|
8471
|
-
if (result.tool?.id) {
|
|
8681
|
+
spinner.stop(`Tool ${result.isUpdate ? "updated" : "published"} successfully`);
|
|
8682
|
+
let successMessage = `✓ ${import_picocolors5.default.bold(toolDefinition.name)} ${result.isUpdate ? "updated" : "published"} to Enact registry`;
|
|
8683
|
+
if (result.result?.tool?.id) {
|
|
8472
8684
|
successMessage += `
|
|
8473
|
-
\uD83D\uDCC4 Tool ID: ${import_picocolors5.default.cyan(result.tool.id)}`;
|
|
8685
|
+
\uD83D\uDCC4 Tool ID: ${import_picocolors5.default.cyan(result.result.tool.id)}`;
|
|
8474
8686
|
}
|
|
8475
|
-
if (result.tool?.name) {
|
|
8687
|
+
if (result.result?.tool?.name) {
|
|
8476
8688
|
successMessage += `
|
|
8477
|
-
\uD83D\uDD27 Tool Name: ${import_picocolors5.default.blue(result.tool.name)}`;
|
|
8689
|
+
\uD83D\uDD27 Tool Name: ${import_picocolors5.default.blue(result.result.tool.name)}`;
|
|
8478
8690
|
}
|
|
8479
8691
|
successMessage += `
|
|
8480
8692
|
\uD83D\uDD0D Discoverable via: "enact search ${toolDefinition.tags?.join(" ") || toolDefinition.name}"`;
|
|
8481
8693
|
Se(import_picocolors5.default.green(successMessage));
|
|
8482
8694
|
} catch (error) {
|
|
8483
8695
|
spinner.stop("Failed to publish tool");
|
|
8484
|
-
if (error instanceof
|
|
8485
|
-
if (error.
|
|
8696
|
+
if (error instanceof EnactApiError) {
|
|
8697
|
+
if (error.statusCode === 401 || error.statusCode === 403) {
|
|
8486
8698
|
Me("Authentication failed. Your token may have expired.", "Error");
|
|
8487
8699
|
Me('Run "enact auth login" to re-authenticate.', "Suggestion");
|
|
8488
|
-
} else if (error.
|
|
8700
|
+
} else if (error.statusCode === 409) {
|
|
8701
|
+
Me(`Tool '${toolDefinition.name}' already exists and you don't have permission to update it.`, "Error");
|
|
8702
|
+
} else if (error.statusCode === 400) {
|
|
8703
|
+
Me(`Invalid tool definition: ${error.message}`, "Error");
|
|
8704
|
+
} else {
|
|
8705
|
+
Me(error.message, "Error");
|
|
8706
|
+
}
|
|
8707
|
+
} else if (error instanceof Error) {
|
|
8708
|
+
if (error.message.includes("ENOTFOUND") || error.message.includes("ECONNREFUSED")) {
|
|
8489
8709
|
Me("Could not connect to the Enact registry. Check your internet connection and registry URL.", "Error");
|
|
8490
8710
|
} else {
|
|
8491
8711
|
Me(error.message, "Error");
|
|
@@ -8494,6 +8714,46 @@ Command: ${import_picocolors5.default.dim(toolDefinition.command)}`, "Tool Detai
|
|
|
8494
8714
|
Se(import_picocolors5.default.red("Publish failed"));
|
|
8495
8715
|
}
|
|
8496
8716
|
}
|
|
8717
|
+
async function getFilePathInteractively() {
|
|
8718
|
+
const history = await getHistory();
|
|
8719
|
+
if (history.length > 0) {
|
|
8720
|
+
const action = await ve({
|
|
8721
|
+
message: "Select a tool manifest to publish:",
|
|
8722
|
+
options: [
|
|
8723
|
+
{ value: "select", label: "Choose from recent files" },
|
|
8724
|
+
{ value: "new", label: "Specify a new file" }
|
|
8725
|
+
]
|
|
8726
|
+
});
|
|
8727
|
+
if (action === "select") {
|
|
8728
|
+
const fileOptions = history.filter((file) => existsSync3(file) && isEnactFile(file)).map((file) => ({
|
|
8729
|
+
value: file,
|
|
8730
|
+
label: file
|
|
8731
|
+
}));
|
|
8732
|
+
if (fileOptions.length > 0) {
|
|
8733
|
+
return await ve({
|
|
8734
|
+
message: "Select a tool manifest:",
|
|
8735
|
+
options: fileOptions
|
|
8736
|
+
});
|
|
8737
|
+
} else {
|
|
8738
|
+
Me("No recent Enact tool manifests found.", "History");
|
|
8739
|
+
return await he({
|
|
8740
|
+
message: "Enter the path to the tool manifest (.yaml or .yml):",
|
|
8741
|
+
validate: validateEnactFile
|
|
8742
|
+
});
|
|
8743
|
+
}
|
|
8744
|
+
} else {
|
|
8745
|
+
return await he({
|
|
8746
|
+
message: "Enter the path to the tool manifest (.yaml or .yml):",
|
|
8747
|
+
validate: validateEnactFile
|
|
8748
|
+
});
|
|
8749
|
+
}
|
|
8750
|
+
} else {
|
|
8751
|
+
return await he({
|
|
8752
|
+
message: "Enter the path to the tool manifest (.yaml or .yml):",
|
|
8753
|
+
validate: validateEnactFile
|
|
8754
|
+
});
|
|
8755
|
+
}
|
|
8756
|
+
}
|
|
8497
8757
|
function isEnactFile(filePath) {
|
|
8498
8758
|
const ext = extname(filePath).toLowerCase();
|
|
8499
8759
|
return ext === ".yaml" || ext === ".yml";
|
|
@@ -8507,46 +8767,15 @@ function validateEnactFile(value) {
|
|
|
8507
8767
|
return "File must be a YAML file (.yaml or .yml)";
|
|
8508
8768
|
return;
|
|
8509
8769
|
}
|
|
8510
|
-
function validateToolDefinition(tool) {
|
|
8511
|
-
if (!tool)
|
|
8512
|
-
return "Tool definition is required";
|
|
8513
|
-
if (!tool.name || typeof tool.name !== "string") {
|
|
8514
|
-
return "Tool name is required and must be a string";
|
|
8515
|
-
}
|
|
8516
|
-
if (!tool.description || typeof tool.description !== "string") {
|
|
8517
|
-
return "Tool description is required and must be a string";
|
|
8518
|
-
}
|
|
8519
|
-
if (!tool.command || typeof tool.command !== "string") {
|
|
8520
|
-
return "Tool command is required and must be a string";
|
|
8521
|
-
}
|
|
8522
|
-
if (!/^[a-zA-Z0-9_-]+\/[a-zA-Z0-9_\/-]+$/.test(tool.name)) {
|
|
8523
|
-
return "Tool name must follow hierarchical format: org/category/tool-name";
|
|
8524
|
-
}
|
|
8525
|
-
if (tool.timeout && typeof tool.timeout === "string") {
|
|
8526
|
-
if (!/^\d+[smh]$/.test(tool.timeout)) {
|
|
8527
|
-
return 'Timeout must be in Go duration format (e.g., "30s", "5m", "1h")';
|
|
8528
|
-
}
|
|
8529
|
-
}
|
|
8530
|
-
if (tool.tags && !Array.isArray(tool.tags)) {
|
|
8531
|
-
return "Tags must be an array of strings";
|
|
8532
|
-
}
|
|
8533
|
-
if (tool.inputSchema && typeof tool.inputSchema !== "object") {
|
|
8534
|
-
return "inputSchema must be a valid JSON Schema object";
|
|
8535
|
-
}
|
|
8536
|
-
if (tool.outputSchema && typeof tool.outputSchema !== "object") {
|
|
8537
|
-
return "outputSchema must be a valid JSON Schema object";
|
|
8538
|
-
}
|
|
8539
|
-
return;
|
|
8540
|
-
}
|
|
8541
8770
|
|
|
8542
8771
|
// src/commands/remote.ts
|
|
8543
8772
|
var import_picocolors6 = __toESM(require_picocolors(), 1);
|
|
8544
8773
|
import { existsSync as existsSync4 } from "fs";
|
|
8545
8774
|
import { readFile as readFile4, writeFile as writeFile3, mkdir as mkdir3 } from "fs/promises";
|
|
8546
|
-
import { join as
|
|
8775
|
+
import { join as join4 } from "path";
|
|
8547
8776
|
import { homedir as homedir3 } from "os";
|
|
8548
|
-
var CONFIG_DIR3 =
|
|
8549
|
-
var CONFIG_FILE2 =
|
|
8777
|
+
var CONFIG_DIR3 = join4(homedir3(), ".enact");
|
|
8778
|
+
var CONFIG_FILE2 = join4(CONFIG_DIR3, "config.json");
|
|
8550
8779
|
async function handleRemoteCommand(args, options) {
|
|
8551
8780
|
if (options.help || !args[0]) {
|
|
8552
8781
|
console.log(`
|
|
@@ -9195,6 +9424,401 @@ function yamlStringify(obj, indent = 0) {
|
|
|
9195
9424
|
return result;
|
|
9196
9425
|
}
|
|
9197
9426
|
|
|
9427
|
+
// src/commands/search.ts
|
|
9428
|
+
var import_picocolors8 = __toESM(require_picocolors(), 1);
|
|
9429
|
+
async function handleSearchCommand(args, options) {
|
|
9430
|
+
if (options.help) {
|
|
9431
|
+
console.log(`
|
|
9432
|
+
Usage: enact search [query] [options]
|
|
9433
|
+
|
|
9434
|
+
Search for Enact tools in the registry.
|
|
9435
|
+
|
|
9436
|
+
Arguments:
|
|
9437
|
+
query Search query (keywords, tool names, descriptions)
|
|
9438
|
+
|
|
9439
|
+
Options:
|
|
9440
|
+
--help, -h Show this help message
|
|
9441
|
+
--limit <number> Maximum number of results (default: 20)
|
|
9442
|
+
--tags <tags> Filter by tags (comma-separated)
|
|
9443
|
+
--format <format> Output format: table, json, list (default: table)
|
|
9444
|
+
--author <author> Filter by author
|
|
9445
|
+
|
|
9446
|
+
Examples:
|
|
9447
|
+
enact search "text processing"
|
|
9448
|
+
enact search formatter --tags cli,text
|
|
9449
|
+
enact search --author myorg
|
|
9450
|
+
enact search prettier --limit 5 --format json
|
|
9451
|
+
`);
|
|
9452
|
+
return;
|
|
9453
|
+
}
|
|
9454
|
+
if (args.length === 0 && !options.author) {
|
|
9455
|
+
Ie(import_picocolors8.default.bgGreen(import_picocolors8.default.white(" Search Enact Tools ")));
|
|
9456
|
+
}
|
|
9457
|
+
let query = args.join(" ");
|
|
9458
|
+
if (!query && !options.author) {
|
|
9459
|
+
const queryResponse = await he({
|
|
9460
|
+
message: "What are you looking for?",
|
|
9461
|
+
placeholder: "Enter keywords, tool names, or descriptions...",
|
|
9462
|
+
validate: (value) => {
|
|
9463
|
+
if (!value.trim())
|
|
9464
|
+
return "Please enter a search query";
|
|
9465
|
+
return;
|
|
9466
|
+
}
|
|
9467
|
+
});
|
|
9468
|
+
if (queryResponse === null) {
|
|
9469
|
+
Se(import_picocolors8.default.yellow("Search cancelled"));
|
|
9470
|
+
return;
|
|
9471
|
+
}
|
|
9472
|
+
query = queryResponse;
|
|
9473
|
+
}
|
|
9474
|
+
let limit = options.limit;
|
|
9475
|
+
let tags = options.tags;
|
|
9476
|
+
let format = options.format || "table";
|
|
9477
|
+
let author = options.author;
|
|
9478
|
+
if (args.length === 0 && !options.author) {
|
|
9479
|
+
const addFilters = await ye({
|
|
9480
|
+
message: "Add additional filters?",
|
|
9481
|
+
initialValue: false
|
|
9482
|
+
});
|
|
9483
|
+
if (addFilters) {
|
|
9484
|
+
const tagsInput = await he({
|
|
9485
|
+
message: "Filter by tags (comma-separated, optional):",
|
|
9486
|
+
placeholder: "cli, text, formatter"
|
|
9487
|
+
});
|
|
9488
|
+
if (tagsInput) {
|
|
9489
|
+
tags = tagsInput.split(",").map((t) => t.trim()).filter((t) => t);
|
|
9490
|
+
}
|
|
9491
|
+
const authorInput = await he({
|
|
9492
|
+
message: "Filter by author (optional):",
|
|
9493
|
+
placeholder: "myorg, username"
|
|
9494
|
+
});
|
|
9495
|
+
if (authorInput) {
|
|
9496
|
+
author = authorInput;
|
|
9497
|
+
}
|
|
9498
|
+
limit = await he({
|
|
9499
|
+
message: "Maximum results:",
|
|
9500
|
+
placeholder: "20",
|
|
9501
|
+
initialValue: "20",
|
|
9502
|
+
validate: (value) => {
|
|
9503
|
+
const num = parseInt(value);
|
|
9504
|
+
if (isNaN(num) || num < 1 || num > 100) {
|
|
9505
|
+
return "Please enter a number between 1 and 100";
|
|
9506
|
+
}
|
|
9507
|
+
return;
|
|
9508
|
+
}
|
|
9509
|
+
}).then((val) => parseInt(val));
|
|
9510
|
+
format = await ve({
|
|
9511
|
+
message: "Output format:",
|
|
9512
|
+
options: [
|
|
9513
|
+
{ value: "table", label: "Table (default)" },
|
|
9514
|
+
{ value: "list", label: "Simple list" },
|
|
9515
|
+
{ value: "json", label: "JSON output" }
|
|
9516
|
+
]
|
|
9517
|
+
});
|
|
9518
|
+
}
|
|
9519
|
+
}
|
|
9520
|
+
const spinner = Y2();
|
|
9521
|
+
spinner.start("Searching tools...");
|
|
9522
|
+
try {
|
|
9523
|
+
let results;
|
|
9524
|
+
if (author && !query) {
|
|
9525
|
+
results = await enactApi.getToolsByAuthor(author, limit || 20);
|
|
9526
|
+
} else if (query) {
|
|
9527
|
+
results = await enactApi.searchTools({
|
|
9528
|
+
query,
|
|
9529
|
+
limit: limit || 20,
|
|
9530
|
+
tags,
|
|
9531
|
+
format
|
|
9532
|
+
});
|
|
9533
|
+
} else {
|
|
9534
|
+
results = await enactApi.getTools({
|
|
9535
|
+
limit: limit || 20,
|
|
9536
|
+
tags,
|
|
9537
|
+
author
|
|
9538
|
+
});
|
|
9539
|
+
}
|
|
9540
|
+
spinner.stop(`Found ${results.length} tool${results.length === 1 ? "" : "s"}`);
|
|
9541
|
+
if (results.length === 0) {
|
|
9542
|
+
Me("No tools found matching your criteria.", "No Results");
|
|
9543
|
+
Me(`Try:
|
|
9544
|
+
• Broader keywords
|
|
9545
|
+
• Removing filters
|
|
9546
|
+
• Different spelling`, "Suggestions");
|
|
9547
|
+
Se("");
|
|
9548
|
+
return;
|
|
9549
|
+
}
|
|
9550
|
+
if (format === "json") {
|
|
9551
|
+
console.log(JSON.stringify(results, null, 2));
|
|
9552
|
+
} else if (format === "list") {
|
|
9553
|
+
displayResultsList(results);
|
|
9554
|
+
} else {
|
|
9555
|
+
displayResultsTable(results);
|
|
9556
|
+
}
|
|
9557
|
+
if (args.length === 0 && !options.author && results.length > 1) {
|
|
9558
|
+
const viewDetail = await ye({
|
|
9559
|
+
message: "View details for a specific tool?",
|
|
9560
|
+
initialValue: false
|
|
9561
|
+
});
|
|
9562
|
+
if (viewDetail) {
|
|
9563
|
+
const selectedTool = await ve({
|
|
9564
|
+
message: "Select a tool to view details:",
|
|
9565
|
+
options: results.map((tool) => ({
|
|
9566
|
+
value: tool.name,
|
|
9567
|
+
label: `${tool.name} - ${tool.description.substring(0, 60)}${tool.description.length > 60 ? "..." : ""}`
|
|
9568
|
+
}))
|
|
9569
|
+
});
|
|
9570
|
+
if (selectedTool) {
|
|
9571
|
+
await showToolDetails(selectedTool);
|
|
9572
|
+
}
|
|
9573
|
+
}
|
|
9574
|
+
}
|
|
9575
|
+
if (args.length === 0 && !options.author) {
|
|
9576
|
+
Se(import_picocolors8.default.green("Search completed"));
|
|
9577
|
+
}
|
|
9578
|
+
} catch (error) {
|
|
9579
|
+
spinner.stop("Search failed");
|
|
9580
|
+
if (error instanceof EnactApiError) {
|
|
9581
|
+
Me(error.message, "Error");
|
|
9582
|
+
} else if (error instanceof Error) {
|
|
9583
|
+
if (error.message.includes("ENOTFOUND") || error.message.includes("ECONNREFUSED")) {
|
|
9584
|
+
Me("Could not connect to the Enact registry. Check your internet connection.", "Error");
|
|
9585
|
+
} else {
|
|
9586
|
+
Me(error.message, "Error");
|
|
9587
|
+
}
|
|
9588
|
+
}
|
|
9589
|
+
if (args.length === 0 && !options.author) {
|
|
9590
|
+
Se(import_picocolors8.default.red("Search failed"));
|
|
9591
|
+
} else {
|
|
9592
|
+
console.error(import_picocolors8.default.red(`Search failed: ${error.message}`));
|
|
9593
|
+
}
|
|
9594
|
+
}
|
|
9595
|
+
}
|
|
9596
|
+
function displayResultsTable(results) {
|
|
9597
|
+
console.log(`
|
|
9598
|
+
` + import_picocolors8.default.bold("Search Results:"));
|
|
9599
|
+
console.log("═".repeat(100));
|
|
9600
|
+
const nameWidth = 25;
|
|
9601
|
+
const descWidth = 50;
|
|
9602
|
+
const tagsWidth = 20;
|
|
9603
|
+
console.log(import_picocolors8.default.bold(import_picocolors8.default.cyan("NAME".padEnd(nameWidth))) + " │ " + import_picocolors8.default.bold(import_picocolors8.default.cyan("DESCRIPTION".padEnd(descWidth))) + " │ " + import_picocolors8.default.bold(import_picocolors8.default.cyan("TAGS".padEnd(tagsWidth))));
|
|
9604
|
+
console.log("─".repeat(nameWidth) + "─┼─" + "─".repeat(descWidth) + "─┼─" + "─".repeat(tagsWidth));
|
|
9605
|
+
results.forEach((tool) => {
|
|
9606
|
+
const name = tool.name.length > nameWidth ? tool.name.substring(0, nameWidth - 3) + "..." : tool.name.padEnd(nameWidth);
|
|
9607
|
+
const desc = tool.description.length > descWidth ? tool.description.substring(0, descWidth - 3) + "..." : tool.description.padEnd(descWidth);
|
|
9608
|
+
const tags = (tool.tags || []).join(", ");
|
|
9609
|
+
const tagsDisplay = tags.length > tagsWidth ? tags.substring(0, tagsWidth - 3) + "..." : tags.padEnd(tagsWidth);
|
|
9610
|
+
console.log(import_picocolors8.default.green(name) + " │ " + import_picocolors8.default.dim(desc) + " │ " + import_picocolors8.default.yellow(tagsDisplay));
|
|
9611
|
+
});
|
|
9612
|
+
console.log("═".repeat(100));
|
|
9613
|
+
console.log(import_picocolors8.default.dim(`Total: ${results.length} tool${results.length === 1 ? "" : "s"}`));
|
|
9614
|
+
}
|
|
9615
|
+
function displayResultsList(results) {
|
|
9616
|
+
console.log(`
|
|
9617
|
+
` + import_picocolors8.default.bold("Search Results:"));
|
|
9618
|
+
console.log("");
|
|
9619
|
+
results.forEach((tool, index) => {
|
|
9620
|
+
console.log(`${import_picocolors8.default.cyan(`${index + 1}.`)} ${import_picocolors8.default.bold(import_picocolors8.default.green(tool.name))}`);
|
|
9621
|
+
console.log(` ${import_picocolors8.default.dim(tool.description)}`);
|
|
9622
|
+
if (tool.tags && tool.tags.length > 0) {
|
|
9623
|
+
console.log(` ${import_picocolors8.default.yellow("Tags:")} ${tool.tags.join(", ")}`);
|
|
9624
|
+
}
|
|
9625
|
+
console.log("");
|
|
9626
|
+
});
|
|
9627
|
+
console.log(import_picocolors8.default.dim(`Total: ${results.length} tool${results.length === 1 ? "" : "s"}`));
|
|
9628
|
+
}
|
|
9629
|
+
async function showToolDetails(toolName) {
|
|
9630
|
+
const spinner = Y2();
|
|
9631
|
+
spinner.start(`Loading details for ${toolName}...`);
|
|
9632
|
+
try {
|
|
9633
|
+
const tool = await enactApi.getTool(toolName);
|
|
9634
|
+
const usage = await enactApi.getToolUsage(toolName);
|
|
9635
|
+
spinner.stop("Tool details loaded");
|
|
9636
|
+
console.log(`
|
|
9637
|
+
` + import_picocolors8.default.bold(import_picocolors8.default.bgBlue(import_picocolors8.default.white(` ${tool.name} `))));
|
|
9638
|
+
console.log("");
|
|
9639
|
+
console.log(import_picocolors8.default.bold("Description:"));
|
|
9640
|
+
console.log(tool.description);
|
|
9641
|
+
console.log("");
|
|
9642
|
+
console.log(import_picocolors8.default.bold("Command:"));
|
|
9643
|
+
console.log(import_picocolors8.default.cyan(tool.command));
|
|
9644
|
+
console.log("");
|
|
9645
|
+
if (tool.tags && tool.tags.length > 0) {
|
|
9646
|
+
console.log(import_picocolors8.default.bold("Tags:"));
|
|
9647
|
+
console.log(tool.tags.map((tag) => import_picocolors8.default.yellow(tag)).join(", "));
|
|
9648
|
+
console.log("");
|
|
9649
|
+
}
|
|
9650
|
+
if (tool.timeout) {
|
|
9651
|
+
console.log(import_picocolors8.default.bold("Timeout:"));
|
|
9652
|
+
console.log(tool.timeout);
|
|
9653
|
+
console.log("");
|
|
9654
|
+
}
|
|
9655
|
+
if (tool.inputSchema) {
|
|
9656
|
+
console.log(import_picocolors8.default.bold("Input Schema:"));
|
|
9657
|
+
console.log(JSON.stringify(tool.inputSchema, null, 2));
|
|
9658
|
+
console.log("");
|
|
9659
|
+
}
|
|
9660
|
+
if (tool.examples && tool.examples.length > 0) {
|
|
9661
|
+
console.log(import_picocolors8.default.bold("Examples:"));
|
|
9662
|
+
tool.examples.forEach((example, index) => {
|
|
9663
|
+
console.log(import_picocolors8.default.cyan(`Example ${index + 1}:`));
|
|
9664
|
+
if (example.description) {
|
|
9665
|
+
console.log(` Description: ${example.description}`);
|
|
9666
|
+
}
|
|
9667
|
+
console.log(` Input: ${JSON.stringify(example.input)}`);
|
|
9668
|
+
if (example.output) {
|
|
9669
|
+
console.log(` Output: ${example.output}`);
|
|
9670
|
+
}
|
|
9671
|
+
console.log("");
|
|
9672
|
+
});
|
|
9673
|
+
}
|
|
9674
|
+
if (tool.env && Object.keys(tool.env).length > 0) {
|
|
9675
|
+
console.log(import_picocolors8.default.bold("Environment Variables:"));
|
|
9676
|
+
Object.entries(tool.env).forEach(([key, config]) => {
|
|
9677
|
+
console.log(` ${import_picocolors8.default.yellow(key)}: ${config.description}`);
|
|
9678
|
+
if (config.required) {
|
|
9679
|
+
console.log(` Required: ${import_picocolors8.default.red("Yes")}`);
|
|
9680
|
+
} else {
|
|
9681
|
+
console.log(` Required: ${import_picocolors8.default.green("No")}`);
|
|
9682
|
+
if (config.default) {
|
|
9683
|
+
console.log(` Default: ${config.default}`);
|
|
9684
|
+
}
|
|
9685
|
+
}
|
|
9686
|
+
});
|
|
9687
|
+
console.log("");
|
|
9688
|
+
}
|
|
9689
|
+
if (usage) {
|
|
9690
|
+
console.log(import_picocolors8.default.bold("Usage Statistics:"));
|
|
9691
|
+
console.log(` Views: ${usage.views || 0}`);
|
|
9692
|
+
console.log(` Downloads: ${usage.downloads || 0}`);
|
|
9693
|
+
console.log(` Executions: ${usage.executions || 0}`);
|
|
9694
|
+
console.log("");
|
|
9695
|
+
}
|
|
9696
|
+
} catch (error) {
|
|
9697
|
+
spinner.stop("Failed to load tool details");
|
|
9698
|
+
Me(`Failed to load details: ${error.message}`, "Error");
|
|
9699
|
+
}
|
|
9700
|
+
}
|
|
9701
|
+
|
|
9702
|
+
// src/commands/user.ts
|
|
9703
|
+
var import_picocolors9 = __toESM(require_picocolors(), 1);
|
|
9704
|
+
async function handleUserCommand(args, options) {
|
|
9705
|
+
if (options.help) {
|
|
9706
|
+
showUserHelp();
|
|
9707
|
+
return;
|
|
9708
|
+
}
|
|
9709
|
+
const subcommand = args[0];
|
|
9710
|
+
switch (subcommand) {
|
|
9711
|
+
case "public-key":
|
|
9712
|
+
await handlePublicKeyCommand(args.slice(1), options);
|
|
9713
|
+
break;
|
|
9714
|
+
default:
|
|
9715
|
+
if (!subcommand) {
|
|
9716
|
+
console.error(import_picocolors9.default.red("Missing subcommand. Use --help for usage information."));
|
|
9717
|
+
} else {
|
|
9718
|
+
console.error(import_picocolors9.default.red(`Unknown subcommand: ${subcommand}`));
|
|
9719
|
+
}
|
|
9720
|
+
showUserHelp();
|
|
9721
|
+
process.exit(1);
|
|
9722
|
+
}
|
|
9723
|
+
}
|
|
9724
|
+
async function handlePublicKeyCommand(args, options) {
|
|
9725
|
+
Ie(import_picocolors9.default.bgBlue(import_picocolors9.default.white(" Get User Public Key ")));
|
|
9726
|
+
let token;
|
|
9727
|
+
try {
|
|
9728
|
+
if (options.token) {
|
|
9729
|
+
token = options.token;
|
|
9730
|
+
} else {
|
|
9731
|
+
const authHeaders = await getAuthHeaders();
|
|
9732
|
+
}
|
|
9733
|
+
} catch (error) {
|
|
9734
|
+
Se(import_picocolors9.default.red(`✗ Authentication required. Run "enact auth login" to authenticate.`));
|
|
9735
|
+
return;
|
|
9736
|
+
}
|
|
9737
|
+
let userId = args[0];
|
|
9738
|
+
if (!userId) {
|
|
9739
|
+
userId = await he({
|
|
9740
|
+
message: "Enter user ID:",
|
|
9741
|
+
placeholder: "user-123",
|
|
9742
|
+
validate: (value) => {
|
|
9743
|
+
if (!value)
|
|
9744
|
+
return "User ID is required";
|
|
9745
|
+
return;
|
|
9746
|
+
}
|
|
9747
|
+
});
|
|
9748
|
+
if (pD(userId)) {
|
|
9749
|
+
Se(import_picocolors9.default.yellow("Operation cancelled"));
|
|
9750
|
+
return;
|
|
9751
|
+
}
|
|
9752
|
+
}
|
|
9753
|
+
let apiUrl = options.server;
|
|
9754
|
+
if (!apiUrl) {
|
|
9755
|
+
const defaultUrl = await getDefaultUrl();
|
|
9756
|
+
console.log("defaultUrl", defaultUrl);
|
|
9757
|
+
if (defaultUrl) {} else {
|
|
9758
|
+
apiUrl = "https://api.enact.dev";
|
|
9759
|
+
}
|
|
9760
|
+
}
|
|
9761
|
+
const spinner = Y2();
|
|
9762
|
+
spinner.start("Fetching public key...");
|
|
9763
|
+
try {
|
|
9764
|
+
const apiClient = apiUrl ? createEnactApiClient(apiUrl) : enactApi;
|
|
9765
|
+
const data = await apiClient.getUserPublicKey(userId);
|
|
9766
|
+
spinner.stop("Public key retrieved successfully");
|
|
9767
|
+
if (options.format === "json") {
|
|
9768
|
+
console.log(JSON.stringify(data, null, 2));
|
|
9769
|
+
} else if (options.format === "raw" && data.publicKey) {
|
|
9770
|
+
console.log(data.publicKey);
|
|
9771
|
+
} else {
|
|
9772
|
+
Me(`User ID: ${import_picocolors9.default.cyan(userId)}
|
|
9773
|
+
Public Key: ${import_picocolors9.default.yellow(data.publicKey || "Not available")}
|
|
9774
|
+
Key Type: ${import_picocolors9.default.blue(data.keyType || "Unknown")}
|
|
9775
|
+
Created: ${import_picocolors9.default.gray(data.createdAt ? new Date(data.createdAt).toLocaleString() : "Unknown")}`, "Public Key Information");
|
|
9776
|
+
}
|
|
9777
|
+
Se(import_picocolors9.default.green("✓ Public key retrieved successfully"));
|
|
9778
|
+
} catch (error) {
|
|
9779
|
+
spinner.stop("Failed to fetch public key" + error);
|
|
9780
|
+
if (error instanceof EnactApiError) {
|
|
9781
|
+
if (error.statusCode === 401 || error.statusCode === 403) {
|
|
9782
|
+
Me("Authentication failed. Your token may have expired.", "Error");
|
|
9783
|
+
Me('Run "enact auth login" to re-authenticate.', "Suggestion");
|
|
9784
|
+
} else if (error.statusCode === 404) {
|
|
9785
|
+
Me(`User '${userId}' not found or no public key available.`, "Error");
|
|
9786
|
+
} else if (error.statusCode === 400) {
|
|
9787
|
+
Me(`Invalid user ID: ${error.message}`, "Error");
|
|
9788
|
+
} else {
|
|
9789
|
+
Me(error.message, "Error");
|
|
9790
|
+
}
|
|
9791
|
+
} else if (error instanceof Error) {
|
|
9792
|
+
if (error.message.includes("ENOTFOUND") || error.message.includes("ECONNREFUSED")) {
|
|
9793
|
+
Me("Could not connect to the Enact API. Check your internet connection and server URL.", "Error");
|
|
9794
|
+
} else {
|
|
9795
|
+
Me(error.message, "Error");
|
|
9796
|
+
}
|
|
9797
|
+
}
|
|
9798
|
+
Se(import_picocolors9.default.red("Failed to fetch public key"));
|
|
9799
|
+
}
|
|
9800
|
+
}
|
|
9801
|
+
function showUserHelp() {
|
|
9802
|
+
console.log(`
|
|
9803
|
+
${import_picocolors9.default.bold("USAGE")}
|
|
9804
|
+
enact user <subcommand> [options]
|
|
9805
|
+
|
|
9806
|
+
${import_picocolors9.default.bold("SUBCOMMANDS")}
|
|
9807
|
+
public-key [userId] Get a user's public key
|
|
9808
|
+
|
|
9809
|
+
${import_picocolors9.default.bold("OPTIONS")}
|
|
9810
|
+
-h, --help Show help information
|
|
9811
|
+
-s, --server <url> API server URL (default: https://api.enact.dev)
|
|
9812
|
+
-t, --token <token> Authentication token
|
|
9813
|
+
-f, --format <format> Output format (json|raw|default)
|
|
9814
|
+
|
|
9815
|
+
${import_picocolors9.default.bold("EXAMPLES")}
|
|
9816
|
+
enact user public-key user-123
|
|
9817
|
+
enact user public-key --format json
|
|
9818
|
+
enact user public-key user-456 --token your-token
|
|
9819
|
+
`);
|
|
9820
|
+
}
|
|
9821
|
+
|
|
9198
9822
|
// src/index.ts
|
|
9199
9823
|
var { values, positionals } = parseArgs({
|
|
9200
9824
|
args: process.argv,
|
|
@@ -9225,6 +9849,21 @@ var { values, positionals } = parseArgs({
|
|
|
9225
9849
|
minimal: {
|
|
9226
9850
|
type: "boolean",
|
|
9227
9851
|
short: "m"
|
|
9852
|
+
},
|
|
9853
|
+
limit: {
|
|
9854
|
+
type: "string",
|
|
9855
|
+
short: "l"
|
|
9856
|
+
},
|
|
9857
|
+
tags: {
|
|
9858
|
+
type: "string"
|
|
9859
|
+
},
|
|
9860
|
+
format: {
|
|
9861
|
+
type: "string",
|
|
9862
|
+
short: "f"
|
|
9863
|
+
},
|
|
9864
|
+
author: {
|
|
9865
|
+
type: "string",
|
|
9866
|
+
short: "a"
|
|
9228
9867
|
}
|
|
9229
9868
|
},
|
|
9230
9869
|
allowPositionals: true,
|
|
@@ -9257,6 +9896,15 @@ async function main() {
|
|
|
9257
9896
|
token: values.token
|
|
9258
9897
|
});
|
|
9259
9898
|
break;
|
|
9899
|
+
case "search":
|
|
9900
|
+
await handleSearchCommand(commandArgs, {
|
|
9901
|
+
help: values.help,
|
|
9902
|
+
limit: values.limit ? parseInt(values.limit) : undefined,
|
|
9903
|
+
tags: values.tags ? (values.tags + "").split(",").map((t) => t.trim()) : undefined,
|
|
9904
|
+
format: values.format,
|
|
9905
|
+
author: values.author
|
|
9906
|
+
});
|
|
9907
|
+
break;
|
|
9260
9908
|
case "remote":
|
|
9261
9909
|
await handleRemoteCommand(commandArgs, {
|
|
9262
9910
|
help: values.help
|
|
@@ -9268,20 +9916,30 @@ async function main() {
|
|
|
9268
9916
|
minimal: values.minimal
|
|
9269
9917
|
});
|
|
9270
9918
|
break;
|
|
9919
|
+
case "user":
|
|
9920
|
+
await handleUserCommand(commandArgs, {
|
|
9921
|
+
help: values.help,
|
|
9922
|
+
server: values.server,
|
|
9923
|
+
token: values.token,
|
|
9924
|
+
format: values.format
|
|
9925
|
+
});
|
|
9926
|
+
break;
|
|
9271
9927
|
case undefined:
|
|
9272
9928
|
if (values.help) {
|
|
9273
9929
|
showHelp();
|
|
9274
9930
|
} else {
|
|
9275
|
-
Ie(
|
|
9931
|
+
Ie(import_picocolors10.default.bgCyan(import_picocolors10.default.black(" Enact CLI ")));
|
|
9276
9932
|
const action = await ve({
|
|
9277
9933
|
message: "What would you like to do?",
|
|
9278
9934
|
options: [
|
|
9279
|
-
{ value: "
|
|
9280
|
-
{ value: "publish", label: "Publish a
|
|
9281
|
-
{ value: "init", label: "Create a new tool definition" },
|
|
9282
|
-
{ value: "
|
|
9283
|
-
{ value: "
|
|
9284
|
-
{ value: "
|
|
9935
|
+
{ value: "search", label: "\uD83D\uDD0D Search for tools" },
|
|
9936
|
+
{ value: "publish", label: "\uD83D\uDCE4 Publish a tool" },
|
|
9937
|
+
{ value: "init", label: "\uD83D\uDCDD Create a new tool definition" },
|
|
9938
|
+
{ value: "auth", label: "\uD83D\uDD10 Manage authentication" },
|
|
9939
|
+
{ value: "remote", label: "\uD83C\uDF10 Manage remote servers" },
|
|
9940
|
+
{ value: "user", label: "\uD83D\uDC64 User operations" },
|
|
9941
|
+
{ value: "help", label: "❓ Show help" },
|
|
9942
|
+
{ value: "exit", label: "\uD83D\uDC4B Exit" }
|
|
9285
9943
|
]
|
|
9286
9944
|
});
|
|
9287
9945
|
if (action === null || action === "exit") {
|
|
@@ -9292,14 +9950,18 @@ async function main() {
|
|
|
9292
9950
|
showHelp();
|
|
9293
9951
|
return;
|
|
9294
9952
|
}
|
|
9953
|
+
if (action === "search") {
|
|
9954
|
+
await handleSearchCommand([], {});
|
|
9955
|
+
return;
|
|
9956
|
+
}
|
|
9295
9957
|
if (action === "auth") {
|
|
9296
9958
|
const authAction = await ve({
|
|
9297
9959
|
message: "Authentication:",
|
|
9298
9960
|
options: [
|
|
9299
|
-
{ value: "login", label: "Login (OAuth)" },
|
|
9300
|
-
{ value: "status", label: "Check auth status" },
|
|
9301
|
-
{ value: "logout", label: "Logout" },
|
|
9302
|
-
{ value: "token", label: "Show token" }
|
|
9961
|
+
{ value: "login", label: "\uD83D\uDD11 Login (OAuth)" },
|
|
9962
|
+
{ value: "status", label: "\uD83D\uDCCA Check auth status" },
|
|
9963
|
+
{ value: "logout", label: "\uD83D\uDEAA Logout" },
|
|
9964
|
+
{ value: "token", label: "\uD83D\uDD10 Show token" }
|
|
9303
9965
|
]
|
|
9304
9966
|
});
|
|
9305
9967
|
if (authAction !== null) {
|
|
@@ -9309,17 +9971,19 @@ async function main() {
|
|
|
9309
9971
|
}
|
|
9310
9972
|
if (action === "publish") {
|
|
9311
9973
|
await handlePublishCommand([], {});
|
|
9974
|
+
return;
|
|
9312
9975
|
}
|
|
9313
9976
|
if (action === "init") {
|
|
9314
9977
|
await handleInitCommand([], {});
|
|
9978
|
+
return;
|
|
9315
9979
|
}
|
|
9316
9980
|
if (action === "remote") {
|
|
9317
9981
|
const remoteAction = await ve({
|
|
9318
9982
|
message: "Remote management:",
|
|
9319
9983
|
options: [
|
|
9320
|
-
{ value: "add", label: "Add remote server" },
|
|
9321
|
-
{ value: "list", label: "List remote servers" },
|
|
9322
|
-
{ value: "remove", label: "Remove remote server" }
|
|
9984
|
+
{ value: "add", label: "➕ Add remote server" },
|
|
9985
|
+
{ value: "list", label: "\uD83D\uDCCB List remote servers" },
|
|
9986
|
+
{ value: "remove", label: "\uD83D\uDDD1️ Remove remote server" }
|
|
9323
9987
|
]
|
|
9324
9988
|
});
|
|
9325
9989
|
if (remoteAction !== null) {
|
|
@@ -9327,15 +9991,27 @@ async function main() {
|
|
|
9327
9991
|
}
|
|
9328
9992
|
return;
|
|
9329
9993
|
}
|
|
9994
|
+
if (action === "user") {
|
|
9995
|
+
const userAction = await ve({
|
|
9996
|
+
message: "User operations:",
|
|
9997
|
+
options: [
|
|
9998
|
+
{ value: "public-key", label: "\uD83D\uDD11 Get user public key" }
|
|
9999
|
+
]
|
|
10000
|
+
});
|
|
10001
|
+
if (userAction !== null) {
|
|
10002
|
+
await handleUserCommand([userAction], {});
|
|
10003
|
+
}
|
|
10004
|
+
return;
|
|
10005
|
+
}
|
|
9330
10006
|
}
|
|
9331
10007
|
break;
|
|
9332
10008
|
default:
|
|
9333
|
-
console.error(
|
|
10009
|
+
console.error(import_picocolors10.default.red(`Unknown command: ${command}`));
|
|
9334
10010
|
showHelp();
|
|
9335
10011
|
process.exit(1);
|
|
9336
10012
|
}
|
|
9337
10013
|
} catch (error) {
|
|
9338
|
-
console.error(
|
|
10014
|
+
console.error(import_picocolors10.default.red(`Error: ${error.message}`));
|
|
9339
10015
|
process.exit(1);
|
|
9340
10016
|
}
|
|
9341
10017
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "enact-cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"description": "Official CLI for the Enact Protocol - package, secure, and discover AI tools",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -61,4 +61,4 @@
|
|
|
61
61
|
"picocolors": "^1.1.1",
|
|
62
62
|
"yaml": "^2.8.0"
|
|
63
63
|
}
|
|
64
|
-
}
|
|
64
|
+
}
|