enact-cli 1.0.1 → 1.0.3
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 +866 -204
- package/package.json +1 -1
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);
|
|
@@ -7758,21 +7761,32 @@ var import_picocolors3 = __toESM(require_picocolors(), 1);
|
|
|
7758
7761
|
function showHelp() {
|
|
7759
7762
|
console.log(`
|
|
7760
7763
|
${import_picocolors3.default.bold("Enact CLI")} ${import_picocolors3.default.dim("v0.1.0")}
|
|
7761
|
-
${import_picocolors3.default.dim("A
|
|
7764
|
+
${import_picocolors3.default.dim("A CLI tool for managing and publishing Enact tools")}
|
|
7762
7765
|
|
|
7763
7766
|
${import_picocolors3.default.bold("Usage:")}
|
|
7764
7767
|
${import_picocolors3.default.cyan("enact")} ${import_picocolors3.default.green("<command>")} [options]
|
|
7765
7768
|
|
|
7766
7769
|
${import_picocolors3.default.bold("Commands:")}
|
|
7767
|
-
${import_picocolors3.default.green("
|
|
7768
|
-
|
|
7769
|
-
${import_picocolors3.default.
|
|
7770
|
-
${import_picocolors3.default.
|
|
7771
|
-
${import_picocolors3.default.
|
|
7770
|
+
${import_picocolors3.default.green("auth")} Manage authentication (login, logout, status, token)
|
|
7771
|
+
${import_picocolors3.default.green("init")} Create a new tool definition
|
|
7772
|
+
${import_picocolors3.default.green("publish")} Publish a tool to the registry
|
|
7773
|
+
${import_picocolors3.default.green("search")} Search for tools in the registry
|
|
7774
|
+
${import_picocolors3.default.green("remote")} Manage remote servers (add, list, remove)
|
|
7775
|
+
${import_picocolors3.default.green("user")} User operations (get public key)
|
|
7776
|
+
|
|
7777
|
+
${import_picocolors3.default.bold("Global Options:")}
|
|
7778
|
+
${import_picocolors3.default.yellow("--help, -h")} Show help message
|
|
7779
|
+
${import_picocolors3.default.yellow("--version, -v")} Show version information
|
|
7772
7780
|
|
|
7773
7781
|
${import_picocolors3.default.bold("Examples:")}
|
|
7774
|
-
${import_picocolors3.default.cyan("enact")}
|
|
7775
|
-
${import_picocolors3.default.cyan("enact")} ${import_picocolors3.default.green("
|
|
7782
|
+
${import_picocolors3.default.cyan("enact")} ${import_picocolors3.default.dim("# Interactive mode")}
|
|
7783
|
+
${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")}
|
|
7784
|
+
${import_picocolors3.default.cyan("enact")} ${import_picocolors3.default.green("publish")} my-tool.yaml ${import_picocolors3.default.dim("# Publish a tool")}
|
|
7785
|
+
${import_picocolors3.default.cyan("enact")} ${import_picocolors3.default.green("auth")} login ${import_picocolors3.default.dim("# Login with OAuth")}
|
|
7786
|
+
${import_picocolors3.default.cyan("enact")} ${import_picocolors3.default.green("init")} ${import_picocolors3.default.yellow("--minimal")} ${import_picocolors3.default.dim("# Create minimal tool template")}
|
|
7787
|
+
|
|
7788
|
+
${import_picocolors3.default.bold("More Help:")}
|
|
7789
|
+
${import_picocolors3.default.cyan("enact")} ${import_picocolors3.default.green("<command>")} ${import_picocolors3.default.yellow("--help")} ${import_picocolors3.default.dim("# Show command-specific help")}
|
|
7776
7790
|
`);
|
|
7777
7791
|
}
|
|
7778
7792
|
function showVersion() {
|
|
@@ -7782,18 +7796,20 @@ function showPublishHelp() {
|
|
|
7782
7796
|
console.log(`
|
|
7783
7797
|
${import_picocolors3.default.bold("Usage:")} ${import_picocolors3.default.cyan("enact")} ${import_picocolors3.default.green("publish")} [options] [file]
|
|
7784
7798
|
|
|
7785
|
-
${import_picocolors3.default.bold("
|
|
7799
|
+
${import_picocolors3.default.bold("Publish a tool to the Enact registry")}
|
|
7786
7800
|
|
|
7787
7801
|
${import_picocolors3.default.bold("Arguments:")}
|
|
7788
|
-
${import_picocolors3.default.
|
|
7802
|
+
${import_picocolors3.default.blue("file")} The tool definition file to publish (YAML format)
|
|
7789
7803
|
|
|
7790
7804
|
${import_picocolors3.default.bold("Options:")}
|
|
7791
|
-
${import_picocolors3.default.yellow("--help, -h")}
|
|
7792
|
-
${import_picocolors3.default.yellow("--url")}
|
|
7805
|
+
${import_picocolors3.default.yellow("--help, -h")} Show this help message
|
|
7806
|
+
${import_picocolors3.default.yellow("--url")} Specify the registry URL
|
|
7807
|
+
${import_picocolors3.default.yellow("--token, -t")} Specify authentication token
|
|
7793
7808
|
|
|
7794
7809
|
${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
|
|
7810
|
+
${import_picocolors3.default.cyan("enact")} ${import_picocolors3.default.green("publish")} my-tool.yaml
|
|
7811
|
+
${import_picocolors3.default.cyan("enact")} ${import_picocolors3.default.green("publish")} ${import_picocolors3.default.yellow("--url")} https://registry.example.com my-tool.yaml
|
|
7812
|
+
${import_picocolors3.default.cyan("enact")} ${import_picocolors3.default.green("publish")} ${import_picocolors3.default.yellow("--token")} abc123 my-tool.yaml
|
|
7797
7813
|
`);
|
|
7798
7814
|
}
|
|
7799
7815
|
|
|
@@ -7862,11 +7878,297 @@ import { parse } from "url";
|
|
|
7862
7878
|
import { randomBytes, createHash } from "crypto";
|
|
7863
7879
|
import { exec } from "child_process";
|
|
7864
7880
|
import { promisify } from "util";
|
|
7881
|
+
|
|
7882
|
+
// src/api/enact-api.ts
|
|
7883
|
+
class EnactApiClient {
|
|
7884
|
+
baseUrl;
|
|
7885
|
+
supabaseUrl;
|
|
7886
|
+
constructor(baseUrl = "https://enact.tools", supabaseUrl = "https://xjnhhxwxovjifdxdwzih.supabase.co") {
|
|
7887
|
+
this.baseUrl = baseUrl.replace(/\/$/, "");
|
|
7888
|
+
this.supabaseUrl = supabaseUrl.replace(/\/$/, "");
|
|
7889
|
+
}
|
|
7890
|
+
async makeRequest(endpoint, options = {}, token, tokenType = "jwt") {
|
|
7891
|
+
const url = endpoint.startsWith("http") ? endpoint : `${this.supabaseUrl}${endpoint}`;
|
|
7892
|
+
const headers = {
|
|
7893
|
+
"Content-Type": "application/json",
|
|
7894
|
+
...options.headers
|
|
7895
|
+
};
|
|
7896
|
+
if (token) {
|
|
7897
|
+
if (tokenType === "jwt") {
|
|
7898
|
+
headers["Authorization"] = `Bearer ${token}`;
|
|
7899
|
+
} else {
|
|
7900
|
+
headers["X-API-Key"] = token;
|
|
7901
|
+
}
|
|
7902
|
+
}
|
|
7903
|
+
const response = await fetch(url, {
|
|
7904
|
+
...options,
|
|
7905
|
+
headers
|
|
7906
|
+
});
|
|
7907
|
+
if (!response.ok) {
|
|
7908
|
+
const errorData = await response.json().catch(() => ({ error: "Unknown error" }));
|
|
7909
|
+
throw new EnactApiError(`${errorData.error || response.statusText}`, response.status, endpoint);
|
|
7910
|
+
}
|
|
7911
|
+
const responseData = await response.json();
|
|
7912
|
+
if (true) {
|
|
7913
|
+
console.log(`API Response for ${endpoint}:`, responseData);
|
|
7914
|
+
}
|
|
7915
|
+
return responseData;
|
|
7916
|
+
}
|
|
7917
|
+
async getTools(params) {
|
|
7918
|
+
const searchParams = new URLSearchParams;
|
|
7919
|
+
if (params?.limit)
|
|
7920
|
+
searchParams.set("limit", params.limit.toString());
|
|
7921
|
+
if (params?.offset)
|
|
7922
|
+
searchParams.set("offset", params.offset.toString());
|
|
7923
|
+
if (params?.tags)
|
|
7924
|
+
searchParams.set("tags", params.tags.join(","));
|
|
7925
|
+
if (params?.author)
|
|
7926
|
+
searchParams.set("author", params.author);
|
|
7927
|
+
const query = searchParams.toString();
|
|
7928
|
+
const endpoint = `/functions/v1/tools${query ? `?${query}` : ""}`;
|
|
7929
|
+
const response = await this.makeRequest(endpoint);
|
|
7930
|
+
if (Array.isArray(response)) {
|
|
7931
|
+
return response;
|
|
7932
|
+
} else if (response.data && Array.isArray(response.data)) {
|
|
7933
|
+
return response.data;
|
|
7934
|
+
} else if (response.tools && Array.isArray(response.tools)) {
|
|
7935
|
+
return response.tools;
|
|
7936
|
+
} else {
|
|
7937
|
+
console.warn("Unexpected response structure for getTools:", response);
|
|
7938
|
+
return [];
|
|
7939
|
+
}
|
|
7940
|
+
}
|
|
7941
|
+
async getTool(name) {
|
|
7942
|
+
const endpoint = `/functions/v1/tools/${encodeURIComponent(name)}`;
|
|
7943
|
+
return this.makeRequest(endpoint);
|
|
7944
|
+
}
|
|
7945
|
+
async getToolUsage(name) {
|
|
7946
|
+
const endpoint = `/functions/v1/tools/${encodeURIComponent(name)}/usage`;
|
|
7947
|
+
return this.makeRequest(endpoint);
|
|
7948
|
+
}
|
|
7949
|
+
async logToolUsage(name, usage) {
|
|
7950
|
+
const endpoint = `/functions/v1/tools/${encodeURIComponent(name)}/usage`;
|
|
7951
|
+
return this.makeRequest(endpoint, {
|
|
7952
|
+
method: "POST",
|
|
7953
|
+
body: JSON.stringify(usage)
|
|
7954
|
+
});
|
|
7955
|
+
}
|
|
7956
|
+
async searchTools(query) {
|
|
7957
|
+
const endpoint = "/functions/v1/tools-search";
|
|
7958
|
+
const response = await this.makeRequest(endpoint, {
|
|
7959
|
+
method: "POST",
|
|
7960
|
+
body: JSON.stringify(query)
|
|
7961
|
+
});
|
|
7962
|
+
if (Array.isArray(response)) {
|
|
7963
|
+
return response;
|
|
7964
|
+
} else if (response.data && Array.isArray(response.data)) {
|
|
7965
|
+
return response.data;
|
|
7966
|
+
} else if (response.results && Array.isArray(response.results)) {
|
|
7967
|
+
return response.results;
|
|
7968
|
+
} else if (response.tools && Array.isArray(response.tools)) {
|
|
7969
|
+
return response.tools;
|
|
7970
|
+
} else {
|
|
7971
|
+
console.warn("Unexpected response structure for searchTools:", response);
|
|
7972
|
+
return [];
|
|
7973
|
+
}
|
|
7974
|
+
}
|
|
7975
|
+
async publishTool(tool, token, tokenType = "cli") {
|
|
7976
|
+
const endpoint = "/functions/v1/tools";
|
|
7977
|
+
return this.makeRequest(endpoint, {
|
|
7978
|
+
method: "POST",
|
|
7979
|
+
body: JSON.stringify(tool)
|
|
7980
|
+
}, token, tokenType);
|
|
7981
|
+
}
|
|
7982
|
+
async updateTool(name, tool, token, tokenType = "cli") {
|
|
7983
|
+
const endpoint = `/functions/v1/tools/${encodeURIComponent(name)}`;
|
|
7984
|
+
return this.makeRequest(endpoint, {
|
|
7985
|
+
method: "PUT",
|
|
7986
|
+
body: JSON.stringify(tool)
|
|
7987
|
+
}, token, tokenType);
|
|
7988
|
+
}
|
|
7989
|
+
async deleteTool(name, token, tokenType = "cli") {
|
|
7990
|
+
const endpoint = `/functions/v1/tools/${encodeURIComponent(name)}`;
|
|
7991
|
+
return this.makeRequest(endpoint, {
|
|
7992
|
+
method: "DELETE"
|
|
7993
|
+
}, token, tokenType);
|
|
7994
|
+
}
|
|
7995
|
+
async createCLIToken(tokenData, jwtToken) {
|
|
7996
|
+
const endpoint = "/functions/v1/cli-token";
|
|
7997
|
+
return this.makeRequest(endpoint, {
|
|
7998
|
+
method: "POST",
|
|
7999
|
+
body: JSON.stringify(tokenData)
|
|
8000
|
+
}, jwtToken, "jwt");
|
|
8001
|
+
}
|
|
8002
|
+
async getCLITokens(jwtToken) {
|
|
8003
|
+
const endpoint = "/functions/v1/cli-token";
|
|
8004
|
+
return this.makeRequest(endpoint, {
|
|
8005
|
+
method: "GET"
|
|
8006
|
+
}, jwtToken, "jwt");
|
|
8007
|
+
}
|
|
8008
|
+
async deleteCLIToken(tokenId, jwtToken) {
|
|
8009
|
+
const endpoint = `/functions/v1/cli-token/${tokenId}`;
|
|
8010
|
+
return this.makeRequest(endpoint, {
|
|
8011
|
+
method: "DELETE"
|
|
8012
|
+
}, jwtToken, "jwt");
|
|
8013
|
+
}
|
|
8014
|
+
async exchangeOAuthCode(oauthData) {
|
|
8015
|
+
const endpoint = "/functions/v1/cli-oauth";
|
|
8016
|
+
return this.makeRequest(endpoint, {
|
|
8017
|
+
method: "POST",
|
|
8018
|
+
body: JSON.stringify(oauthData)
|
|
8019
|
+
});
|
|
8020
|
+
}
|
|
8021
|
+
async generateEmbeddings(data, token, tokenType = "cli") {
|
|
8022
|
+
const endpoint = "/functions/v1/generate-embeddings";
|
|
8023
|
+
return this.makeRequest(endpoint, {
|
|
8024
|
+
method: "POST",
|
|
8025
|
+
body: JSON.stringify(data)
|
|
8026
|
+
}, token, tokenType);
|
|
8027
|
+
}
|
|
8028
|
+
async toolExists(name) {
|
|
8029
|
+
try {
|
|
8030
|
+
await this.getTool(name);
|
|
8031
|
+
return true;
|
|
8032
|
+
} catch (error) {
|
|
8033
|
+
if (error instanceof Error && error.message.includes("404")) {
|
|
8034
|
+
return false;
|
|
8035
|
+
}
|
|
8036
|
+
throw error;
|
|
8037
|
+
}
|
|
8038
|
+
}
|
|
8039
|
+
async publishOrUpdateTool(tool, token, tokenType = "cli") {
|
|
8040
|
+
let exists;
|
|
8041
|
+
try {
|
|
8042
|
+
exists = await this.toolExists(tool.name);
|
|
8043
|
+
} catch (error) {
|
|
8044
|
+
exists = false;
|
|
8045
|
+
}
|
|
8046
|
+
if (exists) {
|
|
8047
|
+
const result = await this.updateTool(tool.name, tool, token, tokenType);
|
|
8048
|
+
return { isUpdate: true, result };
|
|
8049
|
+
} else {
|
|
8050
|
+
const result = await this.publishTool(tool, token, tokenType);
|
|
8051
|
+
return { isUpdate: false, result };
|
|
8052
|
+
}
|
|
8053
|
+
}
|
|
8054
|
+
async getToolsByTags(tags, limit = 20) {
|
|
8055
|
+
return this.searchTools({
|
|
8056
|
+
query: tags.join(" "),
|
|
8057
|
+
tags,
|
|
8058
|
+
limit
|
|
8059
|
+
});
|
|
8060
|
+
}
|
|
8061
|
+
async getToolsByAuthor(author, limit = 20) {
|
|
8062
|
+
return this.getTools({
|
|
8063
|
+
author,
|
|
8064
|
+
limit
|
|
8065
|
+
});
|
|
8066
|
+
}
|
|
8067
|
+
async getUserPublicKey(userId) {
|
|
8068
|
+
const url = `${this.supabaseUrl}/functions/v1/tools/user/public-key/${userId}`;
|
|
8069
|
+
const headers = {
|
|
8070
|
+
Accept: "application/json",
|
|
8071
|
+
"Content-Type": "application/json"
|
|
8072
|
+
};
|
|
8073
|
+
try {
|
|
8074
|
+
const response = await fetch(url, {
|
|
8075
|
+
method: "GET",
|
|
8076
|
+
headers
|
|
8077
|
+
});
|
|
8078
|
+
if (!response.ok) {
|
|
8079
|
+
const errorText = await response.text();
|
|
8080
|
+
let errorMessage = `HTTP ${response.status}: ${response.statusText}`;
|
|
8081
|
+
try {
|
|
8082
|
+
const errorJson = JSON.parse(errorText);
|
|
8083
|
+
if (errorJson.message) {
|
|
8084
|
+
errorMessage = errorJson.message;
|
|
8085
|
+
} else if (errorJson.error) {
|
|
8086
|
+
errorMessage = errorJson.error;
|
|
8087
|
+
}
|
|
8088
|
+
} catch {}
|
|
8089
|
+
throw new EnactApiError(errorMessage, response.status);
|
|
8090
|
+
}
|
|
8091
|
+
const data = await response.json();
|
|
8092
|
+
return data;
|
|
8093
|
+
} catch (error) {
|
|
8094
|
+
if (error instanceof EnactApiError) {
|
|
8095
|
+
throw error;
|
|
8096
|
+
}
|
|
8097
|
+
if (error instanceof Error) {
|
|
8098
|
+
if (error.message.includes("fetch")) {
|
|
8099
|
+
throw new EnactApiError("Network error: Could not connect to Enact API", 0);
|
|
8100
|
+
}
|
|
8101
|
+
throw new EnactApiError(error.message, 0);
|
|
8102
|
+
}
|
|
8103
|
+
throw new EnactApiError("Unknown error occurred", 0);
|
|
8104
|
+
}
|
|
8105
|
+
}
|
|
8106
|
+
generateOAuthUrl(options) {
|
|
8107
|
+
const params = new URLSearchParams({
|
|
8108
|
+
response_type: "code",
|
|
8109
|
+
client_id: options.clientId,
|
|
8110
|
+
redirect_uri: options.redirectUri,
|
|
8111
|
+
scope: options.scope,
|
|
8112
|
+
state: options.state,
|
|
8113
|
+
code_challenge: options.codeChallenge,
|
|
8114
|
+
code_challenge_method: options.codeChallengeMethod
|
|
8115
|
+
});
|
|
8116
|
+
return `${this.baseUrl}/auth/cli/oauth?${params.toString()}`;
|
|
8117
|
+
}
|
|
8118
|
+
validateTool(tool) {
|
|
8119
|
+
const errors2 = [];
|
|
8120
|
+
if (!tool.name || typeof tool.name !== "string") {
|
|
8121
|
+
errors2.push("Tool name is required and must be a string");
|
|
8122
|
+
} else if (!/^[a-zA-Z0-9_-]+\/[a-zA-Z0-9_\/-]+$/.test(tool.name)) {
|
|
8123
|
+
errors2.push("Tool name must follow hierarchical format: org/category/tool-name");
|
|
8124
|
+
}
|
|
8125
|
+
if (!tool.description || typeof tool.description !== "string") {
|
|
8126
|
+
errors2.push("Tool description is required and must be a string");
|
|
8127
|
+
}
|
|
8128
|
+
if (!tool.command || typeof tool.command !== "string") {
|
|
8129
|
+
errors2.push("Tool command is required and must be a string");
|
|
8130
|
+
}
|
|
8131
|
+
if (tool.timeout && typeof tool.timeout === "string") {
|
|
8132
|
+
if (!/^\d+[smh]$/.test(tool.timeout)) {
|
|
8133
|
+
errors2.push('Timeout must be in Go duration format (e.g., "30s", "5m", "1h")');
|
|
8134
|
+
}
|
|
8135
|
+
}
|
|
8136
|
+
if (tool.tags && !Array.isArray(tool.tags)) {
|
|
8137
|
+
errors2.push("Tags must be an array of strings");
|
|
8138
|
+
}
|
|
8139
|
+
if (tool.inputSchema && typeof tool.inputSchema !== "object") {
|
|
8140
|
+
errors2.push("inputSchema must be a valid JSON Schema object");
|
|
8141
|
+
}
|
|
8142
|
+
if (tool.outputSchema && typeof tool.outputSchema !== "object") {
|
|
8143
|
+
errors2.push("outputSchema must be a valid JSON Schema object");
|
|
8144
|
+
}
|
|
8145
|
+
return {
|
|
8146
|
+
valid: errors2.length === 0,
|
|
8147
|
+
errors: errors2
|
|
8148
|
+
};
|
|
8149
|
+
}
|
|
8150
|
+
}
|
|
8151
|
+
var enactApi = new EnactApiClient;
|
|
8152
|
+
|
|
8153
|
+
class EnactApiError extends Error {
|
|
8154
|
+
statusCode;
|
|
8155
|
+
endpoint;
|
|
8156
|
+
constructor(message, statusCode, endpoint) {
|
|
8157
|
+
super(message);
|
|
8158
|
+
this.statusCode = statusCode;
|
|
8159
|
+
this.endpoint = endpoint;
|
|
8160
|
+
this.name = "EnactApiError";
|
|
8161
|
+
}
|
|
8162
|
+
}
|
|
8163
|
+
function createEnactApiClient(baseUrl, supabaseUrl) {
|
|
8164
|
+
return new EnactApiClient(baseUrl, supabaseUrl);
|
|
8165
|
+
}
|
|
8166
|
+
|
|
8167
|
+
// src/commands/auth.ts
|
|
7865
8168
|
var execAsync = promisify(exec);
|
|
7866
8169
|
var CONFIG_DIR2 = join2(homedir2(), ".enact");
|
|
7867
8170
|
var AUTH_FILE = join2(CONFIG_DIR2, "auth.json");
|
|
7868
8171
|
var DEFAULT_SERVER = "https://enact.tools";
|
|
7869
|
-
var SUPABASE_PROJECT_URL = "https://xjnhhxwxovjifdxdwzih.supabase.co";
|
|
7870
8172
|
async function handleAuthCommand(args, options) {
|
|
7871
8173
|
if (options.help || !args[0]) {
|
|
7872
8174
|
console.log(`
|
|
@@ -7930,16 +8232,14 @@ async function handleLogin(serverUrl, callbackPort) {
|
|
|
7930
8232
|
const codeChallenge = generateCodeChallenge(codeVerifier);
|
|
7931
8233
|
const state = generateState();
|
|
7932
8234
|
const redirectUri = `http://localhost:${callbackPort}/callback`;
|
|
7933
|
-
const
|
|
7934
|
-
|
|
7935
|
-
|
|
7936
|
-
redirect_uri: redirectUri,
|
|
8235
|
+
const authUrl = enactApi.generateOAuthUrl({
|
|
8236
|
+
clientId: "enact-cli",
|
|
8237
|
+
redirectUri,
|
|
7937
8238
|
scope: "publish read write",
|
|
7938
8239
|
state,
|
|
7939
|
-
|
|
7940
|
-
|
|
8240
|
+
codeChallenge,
|
|
8241
|
+
codeChallengeMethod: "S256"
|
|
7941
8242
|
});
|
|
7942
|
-
const authUrl = `${serverUrl}/auth/cli/oauth?${authParams.toString()}`;
|
|
7943
8243
|
const s = Y2();
|
|
7944
8244
|
s.start("Starting OAuth flow...");
|
|
7945
8245
|
let server = null;
|
|
@@ -8102,49 +8402,20 @@ async function startCallbackServerWithFallback(port, serverUrl, codeVerifier, st
|
|
|
8102
8402
|
});
|
|
8103
8403
|
}
|
|
8104
8404
|
async function exchangeCodeForToken(code, redirectUri, codeVerifier, serverUrl) {
|
|
8105
|
-
|
|
8106
|
-
console.log(`Exchanging code for token at: ${tokenEndpoint}`);
|
|
8405
|
+
console.log(`Exchanging code for token...`);
|
|
8107
8406
|
console.log("Exchange params:", {
|
|
8108
8407
|
code: code.substring(0, 8) + "...",
|
|
8109
8408
|
redirectUri,
|
|
8110
8409
|
codeVerifier: codeVerifier.substring(0, 8) + "..."
|
|
8111
8410
|
});
|
|
8112
|
-
const controller = new AbortController;
|
|
8113
|
-
const timeoutId = setTimeout(() => controller.abort(), 30000);
|
|
8114
8411
|
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
|
|
8412
|
+
const tokenData = await enactApi.exchangeOAuthCode({
|
|
8413
|
+
grant_type: "authorization_code",
|
|
8414
|
+
code,
|
|
8415
|
+
redirect_uri: redirectUri,
|
|
8416
|
+
client_id: "enact-cli",
|
|
8417
|
+
code_verifier: codeVerifier
|
|
8128
8418
|
});
|
|
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
8419
|
const expiresAt = new Date(Date.now() + tokenData.expires_in * 1000);
|
|
8149
8420
|
await writeAuthConfig({
|
|
8150
8421
|
token: tokenData.access_token,
|
|
@@ -8155,8 +8426,8 @@ async function exchangeCodeForToken(code, redirectUri, codeVerifier, serverUrl)
|
|
|
8155
8426
|
});
|
|
8156
8427
|
console.log("✓ Token stored successfully");
|
|
8157
8428
|
} catch (error) {
|
|
8158
|
-
if (error instanceof
|
|
8159
|
-
throw new Error(
|
|
8429
|
+
if (error instanceof EnactApiError) {
|
|
8430
|
+
throw new Error(`Token exchange failed: ${error.message}`);
|
|
8160
8431
|
}
|
|
8161
8432
|
throw error;
|
|
8162
8433
|
}
|
|
@@ -8295,15 +8566,13 @@ async function handlePublishCommand(args, options) {
|
|
|
8295
8566
|
return;
|
|
8296
8567
|
}
|
|
8297
8568
|
Ie(import_picocolors5.default.bgBlue(import_picocolors5.default.white(" Publish Enact Tool ")));
|
|
8298
|
-
let
|
|
8569
|
+
let token;
|
|
8299
8570
|
try {
|
|
8300
8571
|
if (options.token) {
|
|
8301
|
-
|
|
8302
|
-
"Content-Type": "application/json",
|
|
8303
|
-
"X-API-Key": options.token
|
|
8304
|
-
};
|
|
8572
|
+
token = options.token;
|
|
8305
8573
|
} else {
|
|
8306
|
-
authHeaders = await getAuthHeaders();
|
|
8574
|
+
const authHeaders = await getAuthHeaders();
|
|
8575
|
+
token = authHeaders["X-API-Key"];
|
|
8307
8576
|
}
|
|
8308
8577
|
} catch (error) {
|
|
8309
8578
|
Se(import_picocolors5.default.red(`✗ Authentication required. Run "enact auth login" to authenticate.`));
|
|
@@ -8311,45 +8580,8 @@ async function handlePublishCommand(args, options) {
|
|
|
8311
8580
|
}
|
|
8312
8581
|
let filePath = args[0];
|
|
8313
8582
|
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) {
|
|
8583
|
+
filePath = await getFilePathInteractively();
|
|
8584
|
+
if (!filePath) {
|
|
8353
8585
|
Se(import_picocolors5.default.yellow("Operation cancelled"));
|
|
8354
8586
|
return;
|
|
8355
8587
|
}
|
|
@@ -8364,9 +8596,11 @@ async function handlePublishCommand(args, options) {
|
|
|
8364
8596
|
try {
|
|
8365
8597
|
const content = await readFile3(filePath, "utf8");
|
|
8366
8598
|
toolDefinition = $parse(content);
|
|
8367
|
-
const validation =
|
|
8368
|
-
if (validation) {
|
|
8369
|
-
Se(import_picocolors5.default.red(`Invalid tool manifest:
|
|
8599
|
+
const validation = enactApi.validateTool(toolDefinition);
|
|
8600
|
+
if (!validation.valid) {
|
|
8601
|
+
Se(import_picocolors5.default.red(`Invalid tool manifest:
|
|
8602
|
+
${validation.errors.join(`
|
|
8603
|
+
`)}`));
|
|
8370
8604
|
return;
|
|
8371
8605
|
}
|
|
8372
8606
|
} catch (error) {
|
|
@@ -8426,66 +8660,38 @@ Command: ${import_picocolors5.default.dim(toolDefinition.command)}`, "Tool Detai
|
|
|
8426
8660
|
const spinner = Y2();
|
|
8427
8661
|
spinner.start("Publishing tool to Enact registry");
|
|
8428
8662
|
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();
|
|
8663
|
+
const apiClient = apiUrl ? createEnactApiClient(apiUrl) : enactApi;
|
|
8664
|
+
Me(`Using API URL: ${import_picocolors5.default.cyan(apiClient.baseUrl)}`, "API Client");
|
|
8665
|
+
const result = await apiClient.publishOrUpdateTool(toolDefinition, token, "cli");
|
|
8468
8666
|
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) {
|
|
8667
|
+
spinner.stop(`Tool ${result.isUpdate ? "updated" : "published"} successfully`);
|
|
8668
|
+
let successMessage = `✓ ${import_picocolors5.default.bold(toolDefinition.name)} ${result.isUpdate ? "updated" : "published"} to Enact registry`;
|
|
8669
|
+
if (result.result?.tool?.id) {
|
|
8472
8670
|
successMessage += `
|
|
8473
|
-
\uD83D\uDCC4 Tool ID: ${import_picocolors5.default.cyan(result.tool.id)}`;
|
|
8671
|
+
\uD83D\uDCC4 Tool ID: ${import_picocolors5.default.cyan(result.result.tool.id)}`;
|
|
8474
8672
|
}
|
|
8475
|
-
if (result.tool?.name) {
|
|
8673
|
+
if (result.result?.tool?.name) {
|
|
8476
8674
|
successMessage += `
|
|
8477
|
-
\uD83D\uDD27 Tool Name: ${import_picocolors5.default.blue(result.tool.name)}`;
|
|
8675
|
+
\uD83D\uDD27 Tool Name: ${import_picocolors5.default.blue(result.result.tool.name)}`;
|
|
8478
8676
|
}
|
|
8479
8677
|
successMessage += `
|
|
8480
8678
|
\uD83D\uDD0D Discoverable via: "enact search ${toolDefinition.tags?.join(" ") || toolDefinition.name}"`;
|
|
8481
8679
|
Se(import_picocolors5.default.green(successMessage));
|
|
8482
8680
|
} catch (error) {
|
|
8483
8681
|
spinner.stop("Failed to publish tool");
|
|
8484
|
-
if (error instanceof
|
|
8485
|
-
if (error.
|
|
8682
|
+
if (error instanceof EnactApiError) {
|
|
8683
|
+
if (error.statusCode === 401 || error.statusCode === 403) {
|
|
8486
8684
|
Me("Authentication failed. Your token may have expired.", "Error");
|
|
8487
8685
|
Me('Run "enact auth login" to re-authenticate.', "Suggestion");
|
|
8488
|
-
} else if (error.
|
|
8686
|
+
} else if (error.statusCode === 409) {
|
|
8687
|
+
Me(`Tool '${toolDefinition.name}' already exists and you don't have permission to update it.`, "Error");
|
|
8688
|
+
} else if (error.statusCode === 400) {
|
|
8689
|
+
Me(`Invalid tool definition: ${error.message}`, "Error");
|
|
8690
|
+
} else {
|
|
8691
|
+
Me(error.message, "Error");
|
|
8692
|
+
}
|
|
8693
|
+
} else if (error instanceof Error) {
|
|
8694
|
+
if (error.message.includes("ENOTFOUND") || error.message.includes("ECONNREFUSED")) {
|
|
8489
8695
|
Me("Could not connect to the Enact registry. Check your internet connection and registry URL.", "Error");
|
|
8490
8696
|
} else {
|
|
8491
8697
|
Me(error.message, "Error");
|
|
@@ -8494,6 +8700,46 @@ Command: ${import_picocolors5.default.dim(toolDefinition.command)}`, "Tool Detai
|
|
|
8494
8700
|
Se(import_picocolors5.default.red("Publish failed"));
|
|
8495
8701
|
}
|
|
8496
8702
|
}
|
|
8703
|
+
async function getFilePathInteractively() {
|
|
8704
|
+
const history = await getHistory();
|
|
8705
|
+
if (history.length > 0) {
|
|
8706
|
+
const action = await ve({
|
|
8707
|
+
message: "Select a tool manifest to publish:",
|
|
8708
|
+
options: [
|
|
8709
|
+
{ value: "select", label: "Choose from recent files" },
|
|
8710
|
+
{ value: "new", label: "Specify a new file" }
|
|
8711
|
+
]
|
|
8712
|
+
});
|
|
8713
|
+
if (action === "select") {
|
|
8714
|
+
const fileOptions = history.filter((file) => existsSync3(file) && isEnactFile(file)).map((file) => ({
|
|
8715
|
+
value: file,
|
|
8716
|
+
label: file
|
|
8717
|
+
}));
|
|
8718
|
+
if (fileOptions.length > 0) {
|
|
8719
|
+
return await ve({
|
|
8720
|
+
message: "Select a tool manifest:",
|
|
8721
|
+
options: fileOptions
|
|
8722
|
+
});
|
|
8723
|
+
} else {
|
|
8724
|
+
Me("No recent Enact tool manifests found.", "History");
|
|
8725
|
+
return await he({
|
|
8726
|
+
message: "Enter the path to the tool manifest (.yaml or .yml):",
|
|
8727
|
+
validate: validateEnactFile
|
|
8728
|
+
});
|
|
8729
|
+
}
|
|
8730
|
+
} else {
|
|
8731
|
+
return await he({
|
|
8732
|
+
message: "Enter the path to the tool manifest (.yaml or .yml):",
|
|
8733
|
+
validate: validateEnactFile
|
|
8734
|
+
});
|
|
8735
|
+
}
|
|
8736
|
+
} else {
|
|
8737
|
+
return await he({
|
|
8738
|
+
message: "Enter the path to the tool manifest (.yaml or .yml):",
|
|
8739
|
+
validate: validateEnactFile
|
|
8740
|
+
});
|
|
8741
|
+
}
|
|
8742
|
+
}
|
|
8497
8743
|
function isEnactFile(filePath) {
|
|
8498
8744
|
const ext = extname(filePath).toLowerCase();
|
|
8499
8745
|
return ext === ".yaml" || ext === ".yml";
|
|
@@ -8507,37 +8753,6 @@ function validateEnactFile(value) {
|
|
|
8507
8753
|
return "File must be a YAML file (.yaml or .yml)";
|
|
8508
8754
|
return;
|
|
8509
8755
|
}
|
|
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
8756
|
|
|
8542
8757
|
// src/commands/remote.ts
|
|
8543
8758
|
var import_picocolors6 = __toESM(require_picocolors(), 1);
|
|
@@ -9195,6 +9410,401 @@ function yamlStringify(obj, indent = 0) {
|
|
|
9195
9410
|
return result;
|
|
9196
9411
|
}
|
|
9197
9412
|
|
|
9413
|
+
// src/commands/search.ts
|
|
9414
|
+
var import_picocolors8 = __toESM(require_picocolors(), 1);
|
|
9415
|
+
async function handleSearchCommand(args, options) {
|
|
9416
|
+
if (options.help) {
|
|
9417
|
+
console.log(`
|
|
9418
|
+
Usage: enact search [query] [options]
|
|
9419
|
+
|
|
9420
|
+
Search for Enact tools in the registry.
|
|
9421
|
+
|
|
9422
|
+
Arguments:
|
|
9423
|
+
query Search query (keywords, tool names, descriptions)
|
|
9424
|
+
|
|
9425
|
+
Options:
|
|
9426
|
+
--help, -h Show this help message
|
|
9427
|
+
--limit <number> Maximum number of results (default: 20)
|
|
9428
|
+
--tags <tags> Filter by tags (comma-separated)
|
|
9429
|
+
--format <format> Output format: table, json, list (default: table)
|
|
9430
|
+
--author <author> Filter by author
|
|
9431
|
+
|
|
9432
|
+
Examples:
|
|
9433
|
+
enact search "text processing"
|
|
9434
|
+
enact search formatter --tags cli,text
|
|
9435
|
+
enact search --author myorg
|
|
9436
|
+
enact search prettier --limit 5 --format json
|
|
9437
|
+
`);
|
|
9438
|
+
return;
|
|
9439
|
+
}
|
|
9440
|
+
if (args.length === 0 && !options.author) {
|
|
9441
|
+
Ie(import_picocolors8.default.bgGreen(import_picocolors8.default.white(" Search Enact Tools ")));
|
|
9442
|
+
}
|
|
9443
|
+
let query = args.join(" ");
|
|
9444
|
+
if (!query && !options.author) {
|
|
9445
|
+
const queryResponse = await he({
|
|
9446
|
+
message: "What are you looking for?",
|
|
9447
|
+
placeholder: "Enter keywords, tool names, or descriptions...",
|
|
9448
|
+
validate: (value) => {
|
|
9449
|
+
if (!value.trim())
|
|
9450
|
+
return "Please enter a search query";
|
|
9451
|
+
return;
|
|
9452
|
+
}
|
|
9453
|
+
});
|
|
9454
|
+
if (queryResponse === null) {
|
|
9455
|
+
Se(import_picocolors8.default.yellow("Search cancelled"));
|
|
9456
|
+
return;
|
|
9457
|
+
}
|
|
9458
|
+
query = queryResponse;
|
|
9459
|
+
}
|
|
9460
|
+
let limit = options.limit;
|
|
9461
|
+
let tags = options.tags;
|
|
9462
|
+
let format = options.format || "table";
|
|
9463
|
+
let author = options.author;
|
|
9464
|
+
if (args.length === 0 && !options.author) {
|
|
9465
|
+
const addFilters = await ye({
|
|
9466
|
+
message: "Add additional filters?",
|
|
9467
|
+
initialValue: false
|
|
9468
|
+
});
|
|
9469
|
+
if (addFilters) {
|
|
9470
|
+
const tagsInput = await he({
|
|
9471
|
+
message: "Filter by tags (comma-separated, optional):",
|
|
9472
|
+
placeholder: "cli, text, formatter"
|
|
9473
|
+
});
|
|
9474
|
+
if (tagsInput) {
|
|
9475
|
+
tags = tagsInput.split(",").map((t) => t.trim()).filter((t) => t);
|
|
9476
|
+
}
|
|
9477
|
+
const authorInput = await he({
|
|
9478
|
+
message: "Filter by author (optional):",
|
|
9479
|
+
placeholder: "myorg, username"
|
|
9480
|
+
});
|
|
9481
|
+
if (authorInput) {
|
|
9482
|
+
author = authorInput;
|
|
9483
|
+
}
|
|
9484
|
+
limit = await he({
|
|
9485
|
+
message: "Maximum results:",
|
|
9486
|
+
placeholder: "20",
|
|
9487
|
+
initialValue: "20",
|
|
9488
|
+
validate: (value) => {
|
|
9489
|
+
const num = parseInt(value);
|
|
9490
|
+
if (isNaN(num) || num < 1 || num > 100) {
|
|
9491
|
+
return "Please enter a number between 1 and 100";
|
|
9492
|
+
}
|
|
9493
|
+
return;
|
|
9494
|
+
}
|
|
9495
|
+
}).then((val) => parseInt(val));
|
|
9496
|
+
format = await ve({
|
|
9497
|
+
message: "Output format:",
|
|
9498
|
+
options: [
|
|
9499
|
+
{ value: "table", label: "Table (default)" },
|
|
9500
|
+
{ value: "list", label: "Simple list" },
|
|
9501
|
+
{ value: "json", label: "JSON output" }
|
|
9502
|
+
]
|
|
9503
|
+
});
|
|
9504
|
+
}
|
|
9505
|
+
}
|
|
9506
|
+
const spinner = Y2();
|
|
9507
|
+
spinner.start("Searching tools...");
|
|
9508
|
+
try {
|
|
9509
|
+
let results;
|
|
9510
|
+
if (author && !query) {
|
|
9511
|
+
results = await enactApi.getToolsByAuthor(author, limit || 20);
|
|
9512
|
+
} else if (query) {
|
|
9513
|
+
results = await enactApi.searchTools({
|
|
9514
|
+
query,
|
|
9515
|
+
limit: limit || 20,
|
|
9516
|
+
tags,
|
|
9517
|
+
format
|
|
9518
|
+
});
|
|
9519
|
+
} else {
|
|
9520
|
+
results = await enactApi.getTools({
|
|
9521
|
+
limit: limit || 20,
|
|
9522
|
+
tags,
|
|
9523
|
+
author
|
|
9524
|
+
});
|
|
9525
|
+
}
|
|
9526
|
+
spinner.stop(`Found ${results.length} tool${results.length === 1 ? "" : "s"}`);
|
|
9527
|
+
if (results.length === 0) {
|
|
9528
|
+
Me("No tools found matching your criteria.", "No Results");
|
|
9529
|
+
Me(`Try:
|
|
9530
|
+
• Broader keywords
|
|
9531
|
+
• Removing filters
|
|
9532
|
+
• Different spelling`, "Suggestions");
|
|
9533
|
+
Se("");
|
|
9534
|
+
return;
|
|
9535
|
+
}
|
|
9536
|
+
if (format === "json") {
|
|
9537
|
+
console.log(JSON.stringify(results, null, 2));
|
|
9538
|
+
} else if (format === "list") {
|
|
9539
|
+
displayResultsList(results);
|
|
9540
|
+
} else {
|
|
9541
|
+
displayResultsTable(results);
|
|
9542
|
+
}
|
|
9543
|
+
if (args.length === 0 && !options.author && results.length > 1) {
|
|
9544
|
+
const viewDetail = await ye({
|
|
9545
|
+
message: "View details for a specific tool?",
|
|
9546
|
+
initialValue: false
|
|
9547
|
+
});
|
|
9548
|
+
if (viewDetail) {
|
|
9549
|
+
const selectedTool = await ve({
|
|
9550
|
+
message: "Select a tool to view details:",
|
|
9551
|
+
options: results.map((tool) => ({
|
|
9552
|
+
value: tool.name,
|
|
9553
|
+
label: `${tool.name} - ${tool.description.substring(0, 60)}${tool.description.length > 60 ? "..." : ""}`
|
|
9554
|
+
}))
|
|
9555
|
+
});
|
|
9556
|
+
if (selectedTool) {
|
|
9557
|
+
await showToolDetails(selectedTool);
|
|
9558
|
+
}
|
|
9559
|
+
}
|
|
9560
|
+
}
|
|
9561
|
+
if (args.length === 0 && !options.author) {
|
|
9562
|
+
Se(import_picocolors8.default.green("Search completed"));
|
|
9563
|
+
}
|
|
9564
|
+
} catch (error) {
|
|
9565
|
+
spinner.stop("Search failed");
|
|
9566
|
+
if (error instanceof EnactApiError) {
|
|
9567
|
+
Me(error.message, "Error");
|
|
9568
|
+
} else if (error instanceof Error) {
|
|
9569
|
+
if (error.message.includes("ENOTFOUND") || error.message.includes("ECONNREFUSED")) {
|
|
9570
|
+
Me("Could not connect to the Enact registry. Check your internet connection.", "Error");
|
|
9571
|
+
} else {
|
|
9572
|
+
Me(error.message, "Error");
|
|
9573
|
+
}
|
|
9574
|
+
}
|
|
9575
|
+
if (args.length === 0 && !options.author) {
|
|
9576
|
+
Se(import_picocolors8.default.red("Search failed"));
|
|
9577
|
+
} else {
|
|
9578
|
+
console.error(import_picocolors8.default.red(`Search failed: ${error.message}`));
|
|
9579
|
+
}
|
|
9580
|
+
}
|
|
9581
|
+
}
|
|
9582
|
+
function displayResultsTable(results) {
|
|
9583
|
+
console.log(`
|
|
9584
|
+
` + import_picocolors8.default.bold("Search Results:"));
|
|
9585
|
+
console.log("═".repeat(100));
|
|
9586
|
+
const nameWidth = 25;
|
|
9587
|
+
const descWidth = 50;
|
|
9588
|
+
const tagsWidth = 20;
|
|
9589
|
+
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))));
|
|
9590
|
+
console.log("─".repeat(nameWidth) + "─┼─" + "─".repeat(descWidth) + "─┼─" + "─".repeat(tagsWidth));
|
|
9591
|
+
results.forEach((tool) => {
|
|
9592
|
+
const name = tool.name.length > nameWidth ? tool.name.substring(0, nameWidth - 3) + "..." : tool.name.padEnd(nameWidth);
|
|
9593
|
+
const desc = tool.description.length > descWidth ? tool.description.substring(0, descWidth - 3) + "..." : tool.description.padEnd(descWidth);
|
|
9594
|
+
const tags = (tool.tags || []).join(", ");
|
|
9595
|
+
const tagsDisplay = tags.length > tagsWidth ? tags.substring(0, tagsWidth - 3) + "..." : tags.padEnd(tagsWidth);
|
|
9596
|
+
console.log(import_picocolors8.default.green(name) + " │ " + import_picocolors8.default.dim(desc) + " │ " + import_picocolors8.default.yellow(tagsDisplay));
|
|
9597
|
+
});
|
|
9598
|
+
console.log("═".repeat(100));
|
|
9599
|
+
console.log(import_picocolors8.default.dim(`Total: ${results.length} tool${results.length === 1 ? "" : "s"}`));
|
|
9600
|
+
}
|
|
9601
|
+
function displayResultsList(results) {
|
|
9602
|
+
console.log(`
|
|
9603
|
+
` + import_picocolors8.default.bold("Search Results:"));
|
|
9604
|
+
console.log("");
|
|
9605
|
+
results.forEach((tool, index) => {
|
|
9606
|
+
console.log(`${import_picocolors8.default.cyan(`${index + 1}.`)} ${import_picocolors8.default.bold(import_picocolors8.default.green(tool.name))}`);
|
|
9607
|
+
console.log(` ${import_picocolors8.default.dim(tool.description)}`);
|
|
9608
|
+
if (tool.tags && tool.tags.length > 0) {
|
|
9609
|
+
console.log(` ${import_picocolors8.default.yellow("Tags:")} ${tool.tags.join(", ")}`);
|
|
9610
|
+
}
|
|
9611
|
+
console.log("");
|
|
9612
|
+
});
|
|
9613
|
+
console.log(import_picocolors8.default.dim(`Total: ${results.length} tool${results.length === 1 ? "" : "s"}`));
|
|
9614
|
+
}
|
|
9615
|
+
async function showToolDetails(toolName) {
|
|
9616
|
+
const spinner = Y2();
|
|
9617
|
+
spinner.start(`Loading details for ${toolName}...`);
|
|
9618
|
+
try {
|
|
9619
|
+
const tool = await enactApi.getTool(toolName);
|
|
9620
|
+
const usage = await enactApi.getToolUsage(toolName);
|
|
9621
|
+
spinner.stop("Tool details loaded");
|
|
9622
|
+
console.log(`
|
|
9623
|
+
` + import_picocolors8.default.bold(import_picocolors8.default.bgBlue(import_picocolors8.default.white(` ${tool.name} `))));
|
|
9624
|
+
console.log("");
|
|
9625
|
+
console.log(import_picocolors8.default.bold("Description:"));
|
|
9626
|
+
console.log(tool.description);
|
|
9627
|
+
console.log("");
|
|
9628
|
+
console.log(import_picocolors8.default.bold("Command:"));
|
|
9629
|
+
console.log(import_picocolors8.default.cyan(tool.command));
|
|
9630
|
+
console.log("");
|
|
9631
|
+
if (tool.tags && tool.tags.length > 0) {
|
|
9632
|
+
console.log(import_picocolors8.default.bold("Tags:"));
|
|
9633
|
+
console.log(tool.tags.map((tag) => import_picocolors8.default.yellow(tag)).join(", "));
|
|
9634
|
+
console.log("");
|
|
9635
|
+
}
|
|
9636
|
+
if (tool.timeout) {
|
|
9637
|
+
console.log(import_picocolors8.default.bold("Timeout:"));
|
|
9638
|
+
console.log(tool.timeout);
|
|
9639
|
+
console.log("");
|
|
9640
|
+
}
|
|
9641
|
+
if (tool.inputSchema) {
|
|
9642
|
+
console.log(import_picocolors8.default.bold("Input Schema:"));
|
|
9643
|
+
console.log(JSON.stringify(tool.inputSchema, null, 2));
|
|
9644
|
+
console.log("");
|
|
9645
|
+
}
|
|
9646
|
+
if (tool.examples && tool.examples.length > 0) {
|
|
9647
|
+
console.log(import_picocolors8.default.bold("Examples:"));
|
|
9648
|
+
tool.examples.forEach((example, index) => {
|
|
9649
|
+
console.log(import_picocolors8.default.cyan(`Example ${index + 1}:`));
|
|
9650
|
+
if (example.description) {
|
|
9651
|
+
console.log(` Description: ${example.description}`);
|
|
9652
|
+
}
|
|
9653
|
+
console.log(` Input: ${JSON.stringify(example.input)}`);
|
|
9654
|
+
if (example.output) {
|
|
9655
|
+
console.log(` Output: ${example.output}`);
|
|
9656
|
+
}
|
|
9657
|
+
console.log("");
|
|
9658
|
+
});
|
|
9659
|
+
}
|
|
9660
|
+
if (tool.env && Object.keys(tool.env).length > 0) {
|
|
9661
|
+
console.log(import_picocolors8.default.bold("Environment Variables:"));
|
|
9662
|
+
Object.entries(tool.env).forEach(([key, config]) => {
|
|
9663
|
+
console.log(` ${import_picocolors8.default.yellow(key)}: ${config.description}`);
|
|
9664
|
+
if (config.required) {
|
|
9665
|
+
console.log(` Required: ${import_picocolors8.default.red("Yes")}`);
|
|
9666
|
+
} else {
|
|
9667
|
+
console.log(` Required: ${import_picocolors8.default.green("No")}`);
|
|
9668
|
+
if (config.default) {
|
|
9669
|
+
console.log(` Default: ${config.default}`);
|
|
9670
|
+
}
|
|
9671
|
+
}
|
|
9672
|
+
});
|
|
9673
|
+
console.log("");
|
|
9674
|
+
}
|
|
9675
|
+
if (usage) {
|
|
9676
|
+
console.log(import_picocolors8.default.bold("Usage Statistics:"));
|
|
9677
|
+
console.log(` Views: ${usage.views || 0}`);
|
|
9678
|
+
console.log(` Downloads: ${usage.downloads || 0}`);
|
|
9679
|
+
console.log(` Executions: ${usage.executions || 0}`);
|
|
9680
|
+
console.log("");
|
|
9681
|
+
}
|
|
9682
|
+
} catch (error) {
|
|
9683
|
+
spinner.stop("Failed to load tool details");
|
|
9684
|
+
Me(`Failed to load details: ${error.message}`, "Error");
|
|
9685
|
+
}
|
|
9686
|
+
}
|
|
9687
|
+
|
|
9688
|
+
// src/commands/user.ts
|
|
9689
|
+
var import_picocolors9 = __toESM(require_picocolors(), 1);
|
|
9690
|
+
async function handleUserCommand(args, options) {
|
|
9691
|
+
if (options.help) {
|
|
9692
|
+
showUserHelp();
|
|
9693
|
+
return;
|
|
9694
|
+
}
|
|
9695
|
+
const subcommand = args[0];
|
|
9696
|
+
switch (subcommand) {
|
|
9697
|
+
case "public-key":
|
|
9698
|
+
await handlePublicKeyCommand(args.slice(1), options);
|
|
9699
|
+
break;
|
|
9700
|
+
default:
|
|
9701
|
+
if (!subcommand) {
|
|
9702
|
+
console.error(import_picocolors9.default.red("Missing subcommand. Use --help for usage information."));
|
|
9703
|
+
} else {
|
|
9704
|
+
console.error(import_picocolors9.default.red(`Unknown subcommand: ${subcommand}`));
|
|
9705
|
+
}
|
|
9706
|
+
showUserHelp();
|
|
9707
|
+
process.exit(1);
|
|
9708
|
+
}
|
|
9709
|
+
}
|
|
9710
|
+
async function handlePublicKeyCommand(args, options) {
|
|
9711
|
+
Ie(import_picocolors9.default.bgBlue(import_picocolors9.default.white(" Get User Public Key ")));
|
|
9712
|
+
let token;
|
|
9713
|
+
try {
|
|
9714
|
+
if (options.token) {
|
|
9715
|
+
token = options.token;
|
|
9716
|
+
} else {
|
|
9717
|
+
const authHeaders = await getAuthHeaders();
|
|
9718
|
+
}
|
|
9719
|
+
} catch (error) {
|
|
9720
|
+
Se(import_picocolors9.default.red(`✗ Authentication required. Run "enact auth login" to authenticate.`));
|
|
9721
|
+
return;
|
|
9722
|
+
}
|
|
9723
|
+
let userId = args[0];
|
|
9724
|
+
if (!userId) {
|
|
9725
|
+
userId = await he({
|
|
9726
|
+
message: "Enter user ID:",
|
|
9727
|
+
placeholder: "user-123",
|
|
9728
|
+
validate: (value) => {
|
|
9729
|
+
if (!value)
|
|
9730
|
+
return "User ID is required";
|
|
9731
|
+
return;
|
|
9732
|
+
}
|
|
9733
|
+
});
|
|
9734
|
+
if (pD(userId)) {
|
|
9735
|
+
Se(import_picocolors9.default.yellow("Operation cancelled"));
|
|
9736
|
+
return;
|
|
9737
|
+
}
|
|
9738
|
+
}
|
|
9739
|
+
let apiUrl = options.server;
|
|
9740
|
+
if (!apiUrl) {
|
|
9741
|
+
const defaultUrl = await getDefaultUrl();
|
|
9742
|
+
console.log("defaultUrl", defaultUrl);
|
|
9743
|
+
if (defaultUrl) {} else {
|
|
9744
|
+
apiUrl = "https://api.enact.dev";
|
|
9745
|
+
}
|
|
9746
|
+
}
|
|
9747
|
+
const spinner = Y2();
|
|
9748
|
+
spinner.start("Fetching public key...");
|
|
9749
|
+
try {
|
|
9750
|
+
const apiClient = apiUrl ? createEnactApiClient(apiUrl) : enactApi;
|
|
9751
|
+
const data = await apiClient.getUserPublicKey(userId);
|
|
9752
|
+
spinner.stop("Public key retrieved successfully");
|
|
9753
|
+
if (options.format === "json") {
|
|
9754
|
+
console.log(JSON.stringify(data, null, 2));
|
|
9755
|
+
} else if (options.format === "raw" && data.publicKey) {
|
|
9756
|
+
console.log(data.publicKey);
|
|
9757
|
+
} else {
|
|
9758
|
+
Me(`User ID: ${import_picocolors9.default.cyan(userId)}
|
|
9759
|
+
Public Key: ${import_picocolors9.default.yellow(data.publicKey || "Not available")}
|
|
9760
|
+
Key Type: ${import_picocolors9.default.blue(data.keyType || "Unknown")}
|
|
9761
|
+
Created: ${import_picocolors9.default.gray(data.createdAt ? new Date(data.createdAt).toLocaleString() : "Unknown")}`, "Public Key Information");
|
|
9762
|
+
}
|
|
9763
|
+
Se(import_picocolors9.default.green("✓ Public key retrieved successfully"));
|
|
9764
|
+
} catch (error) {
|
|
9765
|
+
spinner.stop("Failed to fetch public key" + error);
|
|
9766
|
+
if (error instanceof EnactApiError) {
|
|
9767
|
+
if (error.statusCode === 401 || error.statusCode === 403) {
|
|
9768
|
+
Me("Authentication failed. Your token may have expired.", "Error");
|
|
9769
|
+
Me('Run "enact auth login" to re-authenticate.', "Suggestion");
|
|
9770
|
+
} else if (error.statusCode === 404) {
|
|
9771
|
+
Me(`User '${userId}' not found or no public key available.`, "Error");
|
|
9772
|
+
} else if (error.statusCode === 400) {
|
|
9773
|
+
Me(`Invalid user ID: ${error.message}`, "Error");
|
|
9774
|
+
} else {
|
|
9775
|
+
Me(error.message, "Error");
|
|
9776
|
+
}
|
|
9777
|
+
} else if (error instanceof Error) {
|
|
9778
|
+
if (error.message.includes("ENOTFOUND") || error.message.includes("ECONNREFUSED")) {
|
|
9779
|
+
Me("Could not connect to the Enact API. Check your internet connection and server URL.", "Error");
|
|
9780
|
+
} else {
|
|
9781
|
+
Me(error.message, "Error");
|
|
9782
|
+
}
|
|
9783
|
+
}
|
|
9784
|
+
Se(import_picocolors9.default.red("Failed to fetch public key"));
|
|
9785
|
+
}
|
|
9786
|
+
}
|
|
9787
|
+
function showUserHelp() {
|
|
9788
|
+
console.log(`
|
|
9789
|
+
${import_picocolors9.default.bold("USAGE")}
|
|
9790
|
+
enact user <subcommand> [options]
|
|
9791
|
+
|
|
9792
|
+
${import_picocolors9.default.bold("SUBCOMMANDS")}
|
|
9793
|
+
public-key [userId] Get a user's public key
|
|
9794
|
+
|
|
9795
|
+
${import_picocolors9.default.bold("OPTIONS")}
|
|
9796
|
+
-h, --help Show help information
|
|
9797
|
+
-s, --server <url> API server URL (default: https://api.enact.dev)
|
|
9798
|
+
-t, --token <token> Authentication token
|
|
9799
|
+
-f, --format <format> Output format (json|raw|default)
|
|
9800
|
+
|
|
9801
|
+
${import_picocolors9.default.bold("EXAMPLES")}
|
|
9802
|
+
enact user public-key user-123
|
|
9803
|
+
enact user public-key --format json
|
|
9804
|
+
enact user public-key user-456 --token your-token
|
|
9805
|
+
`);
|
|
9806
|
+
}
|
|
9807
|
+
|
|
9198
9808
|
// src/index.ts
|
|
9199
9809
|
var { values, positionals } = parseArgs({
|
|
9200
9810
|
args: process.argv,
|
|
@@ -9225,6 +9835,21 @@ var { values, positionals } = parseArgs({
|
|
|
9225
9835
|
minimal: {
|
|
9226
9836
|
type: "boolean",
|
|
9227
9837
|
short: "m"
|
|
9838
|
+
},
|
|
9839
|
+
limit: {
|
|
9840
|
+
type: "string",
|
|
9841
|
+
short: "l"
|
|
9842
|
+
},
|
|
9843
|
+
tags: {
|
|
9844
|
+
type: "string"
|
|
9845
|
+
},
|
|
9846
|
+
format: {
|
|
9847
|
+
type: "string",
|
|
9848
|
+
short: "f"
|
|
9849
|
+
},
|
|
9850
|
+
author: {
|
|
9851
|
+
type: "string",
|
|
9852
|
+
short: "a"
|
|
9228
9853
|
}
|
|
9229
9854
|
},
|
|
9230
9855
|
allowPositionals: true,
|
|
@@ -9257,6 +9882,15 @@ async function main() {
|
|
|
9257
9882
|
token: values.token
|
|
9258
9883
|
});
|
|
9259
9884
|
break;
|
|
9885
|
+
case "search":
|
|
9886
|
+
await handleSearchCommand(commandArgs, {
|
|
9887
|
+
help: values.help,
|
|
9888
|
+
limit: values.limit ? parseInt(values.limit) : undefined,
|
|
9889
|
+
tags: values.tags ? (values.tags + "").split(",").map((t) => t.trim()) : undefined,
|
|
9890
|
+
format: values.format,
|
|
9891
|
+
author: values.author
|
|
9892
|
+
});
|
|
9893
|
+
break;
|
|
9260
9894
|
case "remote":
|
|
9261
9895
|
await handleRemoteCommand(commandArgs, {
|
|
9262
9896
|
help: values.help
|
|
@@ -9268,20 +9902,30 @@ async function main() {
|
|
|
9268
9902
|
minimal: values.minimal
|
|
9269
9903
|
});
|
|
9270
9904
|
break;
|
|
9905
|
+
case "user":
|
|
9906
|
+
await handleUserCommand(commandArgs, {
|
|
9907
|
+
help: values.help,
|
|
9908
|
+
server: values.server,
|
|
9909
|
+
token: values.token,
|
|
9910
|
+
format: values.format
|
|
9911
|
+
});
|
|
9912
|
+
break;
|
|
9271
9913
|
case undefined:
|
|
9272
9914
|
if (values.help) {
|
|
9273
9915
|
showHelp();
|
|
9274
9916
|
} else {
|
|
9275
|
-
Ie(
|
|
9917
|
+
Ie(import_picocolors10.default.bgCyan(import_picocolors10.default.black(" Enact CLI ")));
|
|
9276
9918
|
const action = await ve({
|
|
9277
9919
|
message: "What would you like to do?",
|
|
9278
9920
|
options: [
|
|
9279
|
-
{ value: "
|
|
9280
|
-
{ value: "publish", label: "Publish a
|
|
9281
|
-
{ value: "init", label: "Create a new tool definition" },
|
|
9282
|
-
{ value: "
|
|
9283
|
-
{ value: "
|
|
9284
|
-
{ value: "
|
|
9921
|
+
{ value: "search", label: "\uD83D\uDD0D Search for tools" },
|
|
9922
|
+
{ value: "publish", label: "\uD83D\uDCE4 Publish a tool" },
|
|
9923
|
+
{ value: "init", label: "\uD83D\uDCDD Create a new tool definition" },
|
|
9924
|
+
{ value: "auth", label: "\uD83D\uDD10 Manage authentication" },
|
|
9925
|
+
{ value: "remote", label: "\uD83C\uDF10 Manage remote servers" },
|
|
9926
|
+
{ value: "user", label: "\uD83D\uDC64 User operations" },
|
|
9927
|
+
{ value: "help", label: "❓ Show help" },
|
|
9928
|
+
{ value: "exit", label: "\uD83D\uDC4B Exit" }
|
|
9285
9929
|
]
|
|
9286
9930
|
});
|
|
9287
9931
|
if (action === null || action === "exit") {
|
|
@@ -9292,14 +9936,18 @@ async function main() {
|
|
|
9292
9936
|
showHelp();
|
|
9293
9937
|
return;
|
|
9294
9938
|
}
|
|
9939
|
+
if (action === "search") {
|
|
9940
|
+
await handleSearchCommand([], {});
|
|
9941
|
+
return;
|
|
9942
|
+
}
|
|
9295
9943
|
if (action === "auth") {
|
|
9296
9944
|
const authAction = await ve({
|
|
9297
9945
|
message: "Authentication:",
|
|
9298
9946
|
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" }
|
|
9947
|
+
{ value: "login", label: "\uD83D\uDD11 Login (OAuth)" },
|
|
9948
|
+
{ value: "status", label: "\uD83D\uDCCA Check auth status" },
|
|
9949
|
+
{ value: "logout", label: "\uD83D\uDEAA Logout" },
|
|
9950
|
+
{ value: "token", label: "\uD83D\uDD10 Show token" }
|
|
9303
9951
|
]
|
|
9304
9952
|
});
|
|
9305
9953
|
if (authAction !== null) {
|
|
@@ -9309,17 +9957,19 @@ async function main() {
|
|
|
9309
9957
|
}
|
|
9310
9958
|
if (action === "publish") {
|
|
9311
9959
|
await handlePublishCommand([], {});
|
|
9960
|
+
return;
|
|
9312
9961
|
}
|
|
9313
9962
|
if (action === "init") {
|
|
9314
9963
|
await handleInitCommand([], {});
|
|
9964
|
+
return;
|
|
9315
9965
|
}
|
|
9316
9966
|
if (action === "remote") {
|
|
9317
9967
|
const remoteAction = await ve({
|
|
9318
9968
|
message: "Remote management:",
|
|
9319
9969
|
options: [
|
|
9320
|
-
{ value: "add", label: "Add remote server" },
|
|
9321
|
-
{ value: "list", label: "List remote servers" },
|
|
9322
|
-
{ value: "remove", label: "Remove remote server" }
|
|
9970
|
+
{ value: "add", label: "➕ Add remote server" },
|
|
9971
|
+
{ value: "list", label: "\uD83D\uDCCB List remote servers" },
|
|
9972
|
+
{ value: "remove", label: "\uD83D\uDDD1️ Remove remote server" }
|
|
9323
9973
|
]
|
|
9324
9974
|
});
|
|
9325
9975
|
if (remoteAction !== null) {
|
|
@@ -9327,15 +9977,27 @@ async function main() {
|
|
|
9327
9977
|
}
|
|
9328
9978
|
return;
|
|
9329
9979
|
}
|
|
9980
|
+
if (action === "user") {
|
|
9981
|
+
const userAction = await ve({
|
|
9982
|
+
message: "User operations:",
|
|
9983
|
+
options: [
|
|
9984
|
+
{ value: "public-key", label: "\uD83D\uDD11 Get user public key" }
|
|
9985
|
+
]
|
|
9986
|
+
});
|
|
9987
|
+
if (userAction !== null) {
|
|
9988
|
+
await handleUserCommand([userAction], {});
|
|
9989
|
+
}
|
|
9990
|
+
return;
|
|
9991
|
+
}
|
|
9330
9992
|
}
|
|
9331
9993
|
break;
|
|
9332
9994
|
default:
|
|
9333
|
-
console.error(
|
|
9995
|
+
console.error(import_picocolors10.default.red(`Unknown command: ${command}`));
|
|
9334
9996
|
showHelp();
|
|
9335
9997
|
process.exit(1);
|
|
9336
9998
|
}
|
|
9337
9999
|
} catch (error) {
|
|
9338
|
-
console.error(
|
|
10000
|
+
console.error(import_picocolors10.default.red(`Error: ${error.message}`));
|
|
9339
10001
|
process.exit(1);
|
|
9340
10002
|
}
|
|
9341
10003
|
}
|