@easynet/agent-tool-hub 1.0.6

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.
Files changed (42) hide show
  1. package/README.md +132 -0
  2. package/dist/N8nLocalAdapter-6RKQJXJP.js +4 -0
  3. package/dist/N8nLocalAdapter-6RKQJXJP.js.map +1 -0
  4. package/dist/N8nLocalAdapter-MDWME5ZG.cjs +13 -0
  5. package/dist/N8nLocalAdapter-MDWME5ZG.cjs.map +1 -0
  6. package/dist/chunk-57LVNNHL.js +19 -0
  7. package/dist/chunk-57LVNNHL.js.map +1 -0
  8. package/dist/chunk-6QTWECRD.cjs +23 -0
  9. package/dist/chunk-6QTWECRD.cjs.map +1 -0
  10. package/dist/chunk-HPDQEW2P.js +5251 -0
  11. package/dist/chunk-HPDQEW2P.js.map +1 -0
  12. package/dist/chunk-MHEFFZBB.js +134 -0
  13. package/dist/chunk-MHEFFZBB.js.map +1 -0
  14. package/dist/chunk-NTTBDQUF.cjs +118 -0
  15. package/dist/chunk-NTTBDQUF.cjs.map +1 -0
  16. package/dist/chunk-TIKHPRMB.cjs +5313 -0
  17. package/dist/chunk-TIKHPRMB.cjs.map +1 -0
  18. package/dist/chunk-X53WXBKX.cjs +136 -0
  19. package/dist/chunk-X53WXBKX.cjs.map +1 -0
  20. package/dist/chunk-YSYEED4K.js +114 -0
  21. package/dist/chunk-YSYEED4K.js.map +1 -0
  22. package/dist/cli.cjs +194 -0
  23. package/dist/cli.cjs.map +1 -0
  24. package/dist/cli.d.cts +10 -0
  25. package/dist/cli.d.ts +10 -0
  26. package/dist/cli.js +186 -0
  27. package/dist/cli.js.map +1 -0
  28. package/dist/index.cjs +592 -0
  29. package/dist/index.cjs.map +1 -0
  30. package/dist/index.d.cts +552 -0
  31. package/dist/index.d.ts +552 -0
  32. package/dist/index.js +358 -0
  33. package/dist/index.js.map +1 -0
  34. package/dist/toolhub-runtime-CQkP4QVW.d.cts +1564 -0
  35. package/dist/toolhub-runtime-CQkP4QVW.d.ts +1564 -0
  36. package/dist/toolhub-runtime.cjs +30 -0
  37. package/dist/toolhub-runtime.cjs.map +1 -0
  38. package/dist/toolhub-runtime.d.cts +4 -0
  39. package/dist/toolhub-runtime.d.ts +4 -0
  40. package/dist/toolhub-runtime.js +5 -0
  41. package/dist/toolhub-runtime.js.map +1 -0
  42. package/package.json +77 -0
@@ -0,0 +1,136 @@
1
+ 'use strict';
2
+
3
+ var chunkNTTBDQUF_cjs = require('./chunk-NTTBDQUF.cjs');
4
+ var n8nLocal = require('@easynet/n8n-local');
5
+
6
+ var N8nLocalAdapter = class {
7
+ kind = "n8n";
8
+ instance;
9
+ autoStart;
10
+ startPromise;
11
+ workflowMap = /* @__PURE__ */ new Map();
12
+ // toolName -> workflowId
13
+ logger;
14
+ constructor(options = {}) {
15
+ if (process.env.N8N_START_HTTP_SERVER === void 0) {
16
+ const start = options.startHttpServer ?? false;
17
+ process.env.N8N_START_HTTP_SERVER = start ? "true" : "false";
18
+ }
19
+ process.env.DB_TYPE = "sqlite";
20
+ if (options.sqliteDatabase) {
21
+ process.env.DB_SQLITE_DATABASE = options.sqliteDatabase;
22
+ } else if (!process.env.DB_SQLITE_DATABASE) {
23
+ process.env.DB_SQLITE_DATABASE = "database.sqlite";
24
+ }
25
+ if (options.dataFolder) {
26
+ process.env.N8N_DATA_FOLDER = options.dataFolder;
27
+ }
28
+ this.instance = options.instance ?? new n8nLocal.N8nLocal();
29
+ this.autoStart = options.autoStart ?? true;
30
+ this.logger = chunkNTTBDQUF_cjs.createLogger({ ...options.debug, prefix: "N8nLocalAdapter" });
31
+ }
32
+ async listTools() {
33
+ return [];
34
+ }
35
+ async invoke(spec, args, _ctx) {
36
+ if (this.logger.isEnabled("debug")) {
37
+ this.logger.debug("invoke.start", {
38
+ tool: spec.name,
39
+ args: this.logger.options.includeArgs ? chunkNTTBDQUF_cjs.sanitizeForLog(args) : void 0
40
+ });
41
+ }
42
+ try {
43
+ await this.ensureStarted();
44
+ const workflowId = await this.ensureWorkflowImported(spec);
45
+ const result = await this.instance.runWorkflow(workflowId, args);
46
+ if (this.logger.isEnabled("debug")) {
47
+ this.logger.debug("invoke.ok", {
48
+ tool: spec.name,
49
+ workflowId,
50
+ result: this.logger.options.includeResults ? chunkNTTBDQUF_cjs.summarizeForLog(result) : void 0
51
+ });
52
+ }
53
+ return { result, raw: result };
54
+ } catch (error) {
55
+ this.logger.warn("invoke.error", {
56
+ tool: spec.name,
57
+ message: error instanceof Error ? error.message : String(error)
58
+ });
59
+ throw error;
60
+ }
61
+ }
62
+ async stop() {
63
+ this.logger.info("n8nlocal.stop", {});
64
+ await this.instance.stop();
65
+ }
66
+ async start() {
67
+ if (!this.startPromise) {
68
+ this.startPromise = this.instance.start();
69
+ }
70
+ this.logger.info("n8nlocal.start", {});
71
+ await this.startPromise;
72
+ }
73
+ async syncWorkflows(specs) {
74
+ this.logger.info("n8nlocal.sync.start", { count: specs.length });
75
+ await this.ensureStarted();
76
+ const workflows = await this.instance.workflow.listWorkflows();
77
+ const byId = new Map(workflows.map((wf) => [String(wf.id), wf]));
78
+ const byName = new Map(workflows.map((wf) => [String(wf.name), wf]));
79
+ for (const spec of specs) {
80
+ if (spec.kind !== "n8n") continue;
81
+ const normalized = this.normalizeWorkflow(this.getWorkflowDefinition(spec), spec);
82
+ const id = String(normalized.id);
83
+ const name = String(normalized.name);
84
+ const existing = byId.get(id) ?? byName.get(name);
85
+ if (existing) {
86
+ const updated = await this.instance.workflow.updateWorkflow(existing.id, normalized);
87
+ this.workflowMap.set(spec.name, String(updated.id));
88
+ } else {
89
+ const imported = await this.instance.workflow.importWorkflow(normalized);
90
+ this.workflowMap.set(spec.name, String(imported.id));
91
+ }
92
+ }
93
+ this.logger.info("n8nlocal.sync.done", { count: specs.length });
94
+ }
95
+ async ensureStarted() {
96
+ if (!this.autoStart) {
97
+ throw new Error("n8n-local instance not started. Call start() or enable autoStart.");
98
+ }
99
+ if (!this.startPromise) {
100
+ this.startPromise = this.instance.start();
101
+ }
102
+ await this.startPromise;
103
+ }
104
+ async ensureWorkflowImported(spec) {
105
+ const cached = this.workflowMap.get(spec.name);
106
+ if (cached) return cached;
107
+ const workflowDef = this.getWorkflowDefinition(spec);
108
+ const normalized = this.normalizeWorkflow(workflowDef, spec);
109
+ const imported = await this.instance.workflow.importWorkflow(normalized);
110
+ const workflowId = String(imported.id);
111
+ this.workflowMap.set(spec.name, workflowId);
112
+ return workflowId;
113
+ }
114
+ getWorkflowDefinition(spec) {
115
+ if (spec.impl && typeof spec.impl === "object") {
116
+ return spec.impl;
117
+ }
118
+ throw new Error(`n8n workflow definition missing for tool: ${spec.name}`);
119
+ }
120
+ normalizeWorkflow(workflow, spec) {
121
+ const normalized = { ...workflow };
122
+ if (!normalized.id) {
123
+ normalized.id = spec.resourceId ?? spec.name;
124
+ }
125
+ if (!normalized.name) {
126
+ normalized.name = spec.name;
127
+ }
128
+ if (!normalized.nodes) normalized.nodes = [];
129
+ if (!normalized.connections) normalized.connections = {};
130
+ return normalized;
131
+ }
132
+ };
133
+
134
+ exports.N8nLocalAdapter = N8nLocalAdapter;
135
+ //# sourceMappingURL=chunk-X53WXBKX.cjs.map
136
+ //# sourceMappingURL=chunk-X53WXBKX.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/adapters/N8nLocalAdapter.ts"],"names":["N8nLocal","createLogger","sanitizeForLog","summarizeForLog"],"mappings":"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","file":"chunk-X53WXBKX.cjs","sourcesContent":["import type { ToolAdapter, ToolSpec } from \"../types/ToolSpec.js\";\nimport type { ExecContext } from \"../types/ToolIntent.js\";\nimport { N8nLocal } from \"@easynet/n8n-local\";\nimport { createLogger, sanitizeForLog, summarizeForLog } from \"../observability/Logger.js\";\nimport type { DebugOptions, Logger } from \"../observability/Logger.js\";\n\nexport interface N8nLocalAdapterOptions {\n /** Reuse an existing N8nLocal instance */\n instance?: N8nLocal;\n /** Auto-start n8n-local on first invoke (default: true) */\n autoStart?: boolean;\n /** Whether to start the internal HTTP server (default: false) */\n startHttpServer?: boolean;\n /** SQLite database file path (default: \"database.sqlite\") */\n sqliteDatabase?: string;\n /** Optional data folder for workflow sync */\n dataFolder?: string;\n /** Debug/logging configuration */\n debug?: DebugOptions;\n}\n\n/**\n * Adapter for n8n-local (embedded) workflow execution.\n * Uses in-process instance, no HTTP API calls.\n */\nexport class N8nLocalAdapter implements ToolAdapter {\n readonly kind = \"n8n\" as const;\n private readonly instance: N8nLocal;\n private readonly autoStart: boolean;\n private startPromise?: Promise<void>;\n private readonly workflowMap = new Map<string, string>(); // toolName -> workflowId\n private readonly logger: Logger;\n\n constructor(options: N8nLocalAdapterOptions = {}) {\n if (process.env.N8N_START_HTTP_SERVER === undefined) {\n const start = options.startHttpServer ?? false;\n process.env.N8N_START_HTTP_SERVER = start ? \"true\" : \"false\";\n }\n process.env.DB_TYPE = \"sqlite\";\n if (options.sqliteDatabase) {\n process.env.DB_SQLITE_DATABASE = options.sqliteDatabase;\n } else if (!process.env.DB_SQLITE_DATABASE) {\n process.env.DB_SQLITE_DATABASE = \"database.sqlite\";\n }\n if (options.dataFolder) {\n process.env.N8N_DATA_FOLDER = options.dataFolder;\n }\n\n this.instance = options.instance ?? new N8nLocal();\n this.autoStart = options.autoStart ?? true;\n this.logger = createLogger({ ...options.debug, prefix: \"N8nLocalAdapter\" });\n }\n\n async listTools(): Promise<ToolSpec[]> {\n return [];\n }\n\n async invoke(\n spec: ToolSpec,\n args: unknown,\n _ctx: ExecContext,\n ): Promise<{ result: unknown; raw?: unknown }> {\n if (this.logger.isEnabled(\"debug\")) {\n this.logger.debug(\"invoke.start\", {\n tool: spec.name,\n args: this.logger.options.includeArgs ? sanitizeForLog(args) : undefined,\n });\n }\n try {\n await this.ensureStarted();\n const workflowId = await this.ensureWorkflowImported(spec);\n const result = await this.instance.runWorkflow(workflowId, args);\n\n if (this.logger.isEnabled(\"debug\")) {\n this.logger.debug(\"invoke.ok\", {\n tool: spec.name,\n workflowId,\n result: this.logger.options.includeResults\n ? summarizeForLog(result)\n : undefined,\n });\n }\n\n return { result, raw: result };\n } catch (error) {\n this.logger.warn(\"invoke.error\", {\n tool: spec.name,\n message: error instanceof Error ? error.message : String(error),\n });\n throw error;\n }\n }\n\n async stop(): Promise<void> {\n this.logger.info(\"n8nlocal.stop\", {});\n await this.instance.stop();\n }\n\n async start(): Promise<void> {\n if (!this.startPromise) {\n this.startPromise = this.instance.start();\n }\n this.logger.info(\"n8nlocal.start\", {});\n await this.startPromise;\n }\n\n async syncWorkflows(specs: ToolSpec[]): Promise<void> {\n this.logger.info(\"n8nlocal.sync.start\", { count: specs.length });\n await this.ensureStarted();\n const workflows = await this.instance.workflow.listWorkflows();\n const byId = new Map(workflows.map((wf: any) => [String(wf.id), wf]));\n const byName = new Map(workflows.map((wf: any) => [String(wf.name), wf]));\n\n for (const spec of specs) {\n if (spec.kind !== \"n8n\") continue;\n const normalized = this.normalizeWorkflow(this.getWorkflowDefinition(spec), spec);\n const id = String(normalized.id);\n const name = String(normalized.name);\n const existing = byId.get(id) ?? byName.get(name);\n\n if (existing) {\n const updated = await this.instance.workflow.updateWorkflow(existing.id, normalized as any);\n this.workflowMap.set(spec.name, String(updated.id));\n } else {\n const imported = await this.instance.workflow.importWorkflow(normalized as any);\n this.workflowMap.set(spec.name, String(imported.id));\n }\n }\n this.logger.info(\"n8nlocal.sync.done\", { count: specs.length });\n }\n\n private async ensureStarted(): Promise<void> {\n if (!this.autoStart) {\n throw new Error(\"n8n-local instance not started. Call start() or enable autoStart.\");\n }\n\n if (!this.startPromise) {\n this.startPromise = this.instance.start();\n }\n await this.startPromise;\n }\n\n private async ensureWorkflowImported(spec: ToolSpec): Promise<string> {\n const cached = this.workflowMap.get(spec.name);\n if (cached) return cached;\n\n const workflowDef = this.getWorkflowDefinition(spec);\n const normalized = this.normalizeWorkflow(workflowDef, spec);\n const imported = await this.instance.workflow.importWorkflow(normalized as any);\n const workflowId = String(imported.id);\n this.workflowMap.set(spec.name, workflowId);\n return workflowId;\n }\n\n private getWorkflowDefinition(spec: ToolSpec): Record<string, unknown> {\n if (spec.impl && typeof spec.impl === \"object\") {\n return spec.impl as Record<string, unknown>;\n }\n throw new Error(`n8n workflow definition missing for tool: ${spec.name}`);\n }\n\n private normalizeWorkflow(\n workflow: Record<string, unknown>,\n spec: ToolSpec,\n ): Record<string, unknown> {\n const normalized = { ...workflow };\n if (!normalized.id) {\n normalized.id = spec.resourceId ?? spec.name;\n }\n if (!normalized.name) {\n normalized.name = spec.name;\n }\n if (!normalized.nodes) normalized.nodes = [];\n if (!normalized.connections) normalized.connections = {};\n return normalized;\n }\n}\n"]}
@@ -0,0 +1,114 @@
1
+ // src/observability/Logger.ts
2
+ var LEVEL_ORDER = {
3
+ silent: 0,
4
+ error: 1,
5
+ warn: 2,
6
+ info: 3,
7
+ debug: 4,
8
+ trace: 5
9
+ };
10
+ function createLogger(options = {}) {
11
+ const resolved = resolveDebugOptions(options);
12
+ const log = (level, message, meta) => {
13
+ if (!resolved.enabled) return;
14
+ if (LEVEL_ORDER[level] > LEVEL_ORDER[resolved.level]) return;
15
+ const prefix = `[${resolved.prefix}]`;
16
+ const levelTag = `[${level.toUpperCase()}]`;
17
+ const metaText = meta ? ` ${safeStringify(meta, 1e3)}` : "";
18
+ switch (level) {
19
+ case "error":
20
+ console.error(`${prefix} ${levelTag} ${message}${metaText}`);
21
+ break;
22
+ case "warn":
23
+ console.warn(`${prefix} ${levelTag} ${message}${metaText}`);
24
+ break;
25
+ case "info":
26
+ console.info(`${prefix} ${levelTag} ${message}${metaText}`);
27
+ break;
28
+ default:
29
+ console.log(`${prefix} ${levelTag} ${message}${metaText}`);
30
+ break;
31
+ }
32
+ };
33
+ return {
34
+ options: resolved,
35
+ isEnabled: (level) => resolved.enabled && LEVEL_ORDER[level] <= LEVEL_ORDER[resolved.level],
36
+ error: (message, meta) => log("error", message, meta),
37
+ warn: (message, meta) => log("warn", message, meta),
38
+ info: (message, meta) => log("info", message, meta),
39
+ debug: (message, meta) => log("debug", message, meta),
40
+ trace: (message, meta) => log("trace", message, meta)
41
+ };
42
+ }
43
+ function resolveDebugOptions(options = {}) {
44
+ const envLevel = parseEnvLogLevel();
45
+ const enabledFromEnv = envLevel !== void 0 && envLevel !== "silent";
46
+ const enabled = options.enabled ?? enabledFromEnv ?? false;
47
+ const level = options.level ?? envLevel ?? (enabled ? "debug" : "silent");
48
+ return {
49
+ enabled,
50
+ level,
51
+ includeArgs: options.includeArgs ?? false,
52
+ includeResults: options.includeResults ?? false,
53
+ includeRaw: options.includeRaw ?? false,
54
+ logEvents: options.logEvents ?? false,
55
+ prefix: options.prefix ?? "agent-tool-hub"
56
+ };
57
+ }
58
+ function sanitizeForLog(value, maxLen = 500) {
59
+ const str = safeStringify(value, maxLen);
60
+ return str.replace(
61
+ /"(password|token|secret|key|auth)":\s*"[^"]*"/gi,
62
+ '"$1":"[REDACTED]"'
63
+ );
64
+ }
65
+ function summarizeForLog(value, maxLen = 200) {
66
+ if (value === null) return "null";
67
+ if (value === void 0) return "undefined";
68
+ if (typeof value === "string") {
69
+ return value.length > maxLen ? `${value.slice(0, maxLen)}...` : value;
70
+ }
71
+ if (typeof value === "number" || typeof value === "boolean") {
72
+ return String(value);
73
+ }
74
+ if (Array.isArray(value)) {
75
+ return `Array(${value.length})`;
76
+ }
77
+ if (typeof value === "object") {
78
+ const keys = Object.keys(value);
79
+ const shown = keys.slice(0, 5).join(", ");
80
+ return `Object(keys: ${shown}${keys.length > 5 ? ", ..." : ""})`;
81
+ }
82
+ return String(value);
83
+ }
84
+ function safeStringify(value, maxLen) {
85
+ try {
86
+ const json = JSON.stringify(value);
87
+ if (!json) return String(value);
88
+ return json.length > maxLen ? `${json.slice(0, maxLen)}...` : json;
89
+ } catch {
90
+ const fallback = String(value);
91
+ return fallback.length > maxLen ? `${fallback.slice(0, maxLen)}...` : fallback;
92
+ }
93
+ }
94
+ function parseEnvLogLevel() {
95
+ const raw = process.env.TOOLHUB_LOG_LEVEL ?? process.env.TOOLHUB_DEBUG ?? process.env.DEBUG;
96
+ if (!raw) return void 0;
97
+ const value = raw.trim().toLowerCase();
98
+ if (!value || value === "0" || value === "false" || value === "off") {
99
+ return "silent";
100
+ }
101
+ if (value.includes("trace")) return "trace";
102
+ if (value.includes("debug") || value === "1" || value === "true" || value === "yes") {
103
+ return "debug";
104
+ }
105
+ if (value.includes("info")) return "info";
106
+ if (value.includes("warn")) return "warn";
107
+ if (value.includes("error")) return "error";
108
+ if (value.includes("silent")) return "silent";
109
+ return "debug";
110
+ }
111
+
112
+ export { createLogger, sanitizeForLog, summarizeForLog };
113
+ //# sourceMappingURL=chunk-YSYEED4K.js.map
114
+ //# sourceMappingURL=chunk-YSYEED4K.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/observability/Logger.ts"],"names":[],"mappings":"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","file":"chunk-YSYEED4K.js","sourcesContent":["export type LogLevel = \"silent\" | \"error\" | \"warn\" | \"info\" | \"debug\" | \"trace\";\n\nexport interface DebugOptions {\n enabled?: boolean;\n level?: LogLevel;\n includeArgs?: boolean;\n includeResults?: boolean;\n includeRaw?: boolean;\n logEvents?: boolean;\n prefix?: string;\n}\n\nexport interface ResolvedDebugOptions {\n enabled: boolean;\n level: LogLevel;\n includeArgs: boolean;\n includeResults: boolean;\n includeRaw: boolean;\n logEvents: boolean;\n prefix: string;\n}\n\nexport interface Logger {\n options: ResolvedDebugOptions;\n isEnabled(level: LogLevel): boolean;\n error(message: string, meta?: Record<string, unknown>): void;\n warn(message: string, meta?: Record<string, unknown>): void;\n info(message: string, meta?: Record<string, unknown>): void;\n debug(message: string, meta?: Record<string, unknown>): void;\n trace(message: string, meta?: Record<string, unknown>): void;\n}\n\nconst LEVEL_ORDER: Record<LogLevel, number> = {\n silent: 0,\n error: 1,\n warn: 2,\n info: 3,\n debug: 4,\n trace: 5,\n};\n\nexport function createLogger(options: DebugOptions = {}): Logger {\n const resolved = resolveDebugOptions(options);\n\n const log = (level: LogLevel, message: string, meta?: Record<string, unknown>) => {\n if (!resolved.enabled) return;\n if (LEVEL_ORDER[level] > LEVEL_ORDER[resolved.level]) return;\n\n const prefix = `[${resolved.prefix}]`;\n const levelTag = `[${level.toUpperCase()}]`;\n const metaText = meta ? ` ${safeStringify(meta, 1000)}` : \"\";\n\n switch (level) {\n case \"error\":\n console.error(`${prefix} ${levelTag} ${message}${metaText}`);\n break;\n case \"warn\":\n console.warn(`${prefix} ${levelTag} ${message}${metaText}`);\n break;\n case \"info\":\n console.info(`${prefix} ${levelTag} ${message}${metaText}`);\n break;\n default:\n console.log(`${prefix} ${levelTag} ${message}${metaText}`);\n break;\n }\n };\n\n return {\n options: resolved,\n isEnabled: (level) => resolved.enabled && LEVEL_ORDER[level] <= LEVEL_ORDER[resolved.level],\n error: (message, meta) => log(\"error\", message, meta),\n warn: (message, meta) => log(\"warn\", message, meta),\n info: (message, meta) => log(\"info\", message, meta),\n debug: (message, meta) => log(\"debug\", message, meta),\n trace: (message, meta) => log(\"trace\", message, meta),\n };\n}\n\nexport function resolveDebugOptions(options: DebugOptions = {}): ResolvedDebugOptions {\n const envLevel = parseEnvLogLevel();\n const enabledFromEnv = envLevel !== undefined && envLevel !== \"silent\";\n const enabled = options.enabled ?? enabledFromEnv ?? false;\n const level =\n options.level ?? envLevel ?? (enabled ? \"debug\" : \"silent\");\n\n return {\n enabled,\n level,\n includeArgs: options.includeArgs ?? false,\n includeResults: options.includeResults ?? false,\n includeRaw: options.includeRaw ?? false,\n logEvents: options.logEvents ?? false,\n prefix: options.prefix ?? \"agent-tool-hub\",\n };\n}\n\nexport function sanitizeForLog(value: unknown, maxLen = 500): string {\n const str = safeStringify(value, maxLen);\n return str.replace(\n /\"(password|token|secret|key|auth)\":\\s*\"[^\"]*\"/gi,\n \"\\\"$1\\\":\\\"[REDACTED]\\\"\",\n );\n}\n\nexport function summarizeForLog(value: unknown, maxLen = 200): string {\n if (value === null) return \"null\";\n if (value === undefined) return \"undefined\";\n if (typeof value === \"string\") {\n return value.length > maxLen ? `${value.slice(0, maxLen)}...` : value;\n }\n if (typeof value === \"number\" || typeof value === \"boolean\") {\n return String(value);\n }\n if (Array.isArray(value)) {\n return `Array(${value.length})`;\n }\n if (typeof value === \"object\") {\n const keys = Object.keys(value as Record<string, unknown>);\n const shown = keys.slice(0, 5).join(\", \");\n return `Object(keys: ${shown}${keys.length > 5 ? \", ...\" : \"\"})`;\n }\n return String(value);\n}\n\nfunction safeStringify(value: unknown, maxLen: number): string {\n try {\n const json = JSON.stringify(value);\n if (!json) return String(value);\n return json.length > maxLen ? `${json.slice(0, maxLen)}...` : json;\n } catch {\n const fallback = String(value);\n return fallback.length > maxLen ? `${fallback.slice(0, maxLen)}...` : fallback;\n }\n}\n\nfunction parseEnvLogLevel(): LogLevel | undefined {\n const raw =\n process.env.TOOLHUB_LOG_LEVEL ??\n process.env.TOOLHUB_DEBUG ??\n process.env.DEBUG;\n\n if (!raw) return undefined;\n const value = raw.trim().toLowerCase();\n if (!value || value === \"0\" || value === \"false\" || value === \"off\") {\n return \"silent\";\n }\n if (value.includes(\"trace\")) return \"trace\";\n if (value.includes(\"debug\") || value === \"1\" || value === \"true\" || value === \"yes\") {\n return \"debug\";\n }\n if (value.includes(\"info\")) return \"info\";\n if (value.includes(\"warn\")) return \"warn\";\n if (value.includes(\"error\")) return \"error\";\n if (value.includes(\"silent\")) return \"silent\";\n return \"debug\";\n}\n"]}
package/dist/cli.cjs ADDED
@@ -0,0 +1,194 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ var chunkTIKHPRMB_cjs = require('./chunk-TIKHPRMB.cjs');
5
+ require('./chunk-NTTBDQUF.cjs');
6
+ var path = require('path');
7
+ var url = require('url');
8
+ var fs = require('fs/promises');
9
+
10
+ var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
11
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
12
+
13
+ var path__default = /*#__PURE__*/_interopDefault(path);
14
+ var fs__default = /*#__PURE__*/_interopDefault(fs);
15
+
16
+ var DEFAULT_CONFIG = "toolhub.yaml";
17
+ function parseArgv(argv) {
18
+ const args = argv.slice(2);
19
+ let command = "help";
20
+ let configPath = path__default.default.resolve(process.cwd(), DEFAULT_CONFIG);
21
+ let detail = "normal";
22
+ let help = false;
23
+ for (let i = 0; i < args.length; i++) {
24
+ const arg = args[i];
25
+ if (arg === "--help" || arg === "-h") {
26
+ help = true;
27
+ } else if (arg === "--config" || arg === "-c") {
28
+ configPath = path__default.default.resolve(process.cwd(), args[++i] ?? "");
29
+ } else if (arg === "--detail" || arg === "-d") {
30
+ const v = (args[++i] ?? "normal").toLowerCase();
31
+ detail = v === "short" || v === "full" ? v : "normal";
32
+ } else if (arg && !arg.startsWith("-") && (arg === "scan" || arg === "verify" || arg === "list" || arg === "help")) {
33
+ command = arg;
34
+ }
35
+ }
36
+ return { command, configPath, detail, help };
37
+ }
38
+ function printHelp() {
39
+ const bin = "agent-tool-hub";
40
+ process.stdout.write(`
41
+ Usage: ${bin} <command> [options]
42
+
43
+ Commands:
44
+ scan Scan configured tool roots and load tools into the hub.
45
+ verify Scan and verify tools; exit with code 1 if any discovery errors.
46
+ list List discovered tools (use --detail to control output).
47
+
48
+ Options:
49
+ --config, -c <path> Config file path (default: ./${DEFAULT_CONFIG}).
50
+ --detail, -d <level> For 'list': short | normal | full (default: normal).
51
+ --help, -h Show this help.
52
+
53
+ Examples:
54
+ ${bin} scan
55
+ ${bin} verify -c ./toolhub.yaml
56
+ ${bin} list --detail short
57
+ ${bin} list --detail full
58
+ `);
59
+ }
60
+ async function ensureConfig(configPath) {
61
+ try {
62
+ await fs__default.default.access(configPath);
63
+ return true;
64
+ } catch {
65
+ return false;
66
+ }
67
+ }
68
+ async function runWithHub(configPath, collectErrors) {
69
+ const errors = [];
70
+ const { options } = await chunkTIKHPRMB_cjs.loadToolHubConfig(configPath);
71
+ const optionsWithErrorHandler = {
72
+ ...options,
73
+ ...{
74
+ onDiscoverError(dir, err) {
75
+ errors.push({ dir, message: err.message });
76
+ }
77
+ }
78
+ };
79
+ const hub = await createHubAndInit(optionsWithErrorHandler);
80
+ return { hub, errors };
81
+ }
82
+ async function createHubAndInit(options) {
83
+ const hub = chunkTIKHPRMB_cjs.createToolHub(options);
84
+ await hub.initAllTools();
85
+ return hub;
86
+ }
87
+ function formatRoot(root) {
88
+ if (typeof root === "string") return root;
89
+ return root.namespace ? `${root.path} (${root.namespace})` : root.path;
90
+ }
91
+ async function cmdScan(configPath) {
92
+ const { options } = await chunkTIKHPRMB_cjs.loadToolHubConfig(configPath);
93
+ const hub = await createHubAndInit(options);
94
+ const specs = hub.getRegistry().snapshot();
95
+ const roots = options.roots ?? [];
96
+ process.stdout.write(`Scanned ${specs.length} tool(s) from ${roots.length} root(s).
97
+ `);
98
+ process.stdout.write(`Roots: ${roots.map(formatRoot).join(", ")}
99
+ `);
100
+ await hub.shutdown();
101
+ return 0;
102
+ }
103
+ async function cmdVerify(configPath) {
104
+ const { hub, errors } = await runWithHub(configPath);
105
+ const specs = hub.getRegistry().snapshot();
106
+ await hub.shutdown();
107
+ if (errors.length > 0) {
108
+ process.stderr.write(`Verify failed: ${errors.length} error(s) during discovery.
109
+ `);
110
+ for (const e of errors) {
111
+ process.stderr.write(` ${e.dir}: ${e.message}
112
+ `);
113
+ }
114
+ return 1;
115
+ }
116
+ process.stdout.write(`Verified ${specs.length} tool(s). No errors.
117
+ `);
118
+ return 0;
119
+ }
120
+ function formatSpecShort(spec) {
121
+ return spec.name;
122
+ }
123
+ function formatSpecNormal(spec) {
124
+ const desc = (spec.description ?? "").replace(/\n/g, " ").slice(0, 60);
125
+ return `${spec.name} ${spec.kind} ${desc}${desc.length >= 60 ? "\u2026" : ""}`;
126
+ }
127
+ function formatSpecFull(spec) {
128
+ return JSON.stringify(
129
+ {
130
+ name: spec.name,
131
+ kind: spec.kind,
132
+ version: spec.version,
133
+ description: spec.description,
134
+ tags: spec.tags,
135
+ capabilities: spec.capabilities,
136
+ endpoint: spec.endpoint,
137
+ resourceId: spec.resourceId
138
+ },
139
+ null,
140
+ 2
141
+ );
142
+ }
143
+ async function cmdList(configPath, detail) {
144
+ const { options } = await chunkTIKHPRMB_cjs.loadToolHubConfig(configPath);
145
+ const hub = await createHubAndInit(options);
146
+ const specs = hub.getRegistry().snapshot();
147
+ const formatter = detail === "short" ? formatSpecShort : detail === "full" ? formatSpecFull : formatSpecNormal;
148
+ if (detail === "normal") {
149
+ process.stdout.write("name kind description\n");
150
+ }
151
+ for (const spec of specs) {
152
+ process.stdout.write(formatter(spec) + "\n");
153
+ }
154
+ await hub.shutdown();
155
+ return 0;
156
+ }
157
+ async function main(argv = process.argv) {
158
+ const { command, configPath, detail, help } = parseArgv(argv);
159
+ if (help || command === "help") {
160
+ printHelp();
161
+ return 0;
162
+ }
163
+ const configExists = await ensureConfig(configPath);
164
+ if (!configExists) {
165
+ process.stderr.write(`Error: config file not found: ${configPath}
166
+ `);
167
+ return 1;
168
+ }
169
+ switch (command) {
170
+ case "scan":
171
+ return cmdScan(configPath);
172
+ case "verify":
173
+ return cmdVerify(configPath);
174
+ case "list":
175
+ return cmdList(configPath, detail);
176
+ default:
177
+ printHelp();
178
+ return command === "help" ? 0 : 1;
179
+ }
180
+ }
181
+ async function run(argv) {
182
+ return main(argv);
183
+ }
184
+ var isMain = typeof process !== "undefined" && process.argv[1] !== void 0 && process.argv[1] === url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli.cjs', document.baseURI).href)));
185
+ if (isMain) {
186
+ main().then((code) => process.exit(code)).catch((err) => {
187
+ process.stderr.write(String(err?.message ?? err) + "\n");
188
+ process.exit(1);
189
+ });
190
+ }
191
+
192
+ exports.run = run;
193
+ //# sourceMappingURL=cli.cjs.map
194
+ //# sourceMappingURL=cli.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli.ts"],"names":["path","fs","loadToolHubConfig","createToolHub","fileURLToPath"],"mappings":";;;;;;;;;;;;;;;AAeA,IAAM,cAAA,GAAiB,cAAA;AAWvB,SAAS,UAAU,IAAA,EAAyB;AAC1C,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,CAAC,CAAA;AACzB,EAAA,IAAI,OAAA,GAA8B,MAAA;AAClC,EAAA,IAAI,aAAaA,qBAAA,CAAK,OAAA,CAAQ,OAAA,CAAQ,GAAA,IAAO,cAAc,CAAA;AAC3D,EAAA,IAAI,MAAA,GAAsB,QAAA;AAC1B,EAAA,IAAI,IAAA,GAAO,KAAA;AAEX,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,IAAA,CAAK,QAAQ,CAAA,EAAA,EAAK;AACpC,IAAA,MAAM,GAAA,GAAM,KAAK,CAAC,CAAA;AAClB,IAAA,IAAI,GAAA,KAAQ,QAAA,IAAY,GAAA,KAAQ,IAAA,EAAM;AACpC,MAAA,IAAA,GAAO,IAAA;AAAA,IACT,CAAA,MAAA,IAAW,GAAA,KAAQ,UAAA,IAAc,GAAA,KAAQ,IAAA,EAAM;AAC7C,MAAA,UAAA,GAAaA,qBAAA,CAAK,QAAQ,OAAA,CAAQ,GAAA,IAAO,IAAA,CAAK,EAAE,CAAC,CAAA,IAAK,EAAE,CAAA;AAAA,IAC1D,CAAA,MAAA,IAAW,GAAA,KAAQ,UAAA,IAAc,GAAA,KAAQ,IAAA,EAAM;AAC7C,MAAA,MAAM,KAAK,IAAA,CAAK,EAAE,CAAC,CAAA,IAAK,UAAU,WAAA,EAAY;AAC9C,MAAA,MAAA,GAAS,CAAA,KAAM,OAAA,IAAW,CAAA,KAAM,MAAA,GAAS,CAAA,GAAI,QAAA;AAAA,IAC/C,CAAA,MAAA,IAAW,GAAA,IAAO,CAAC,GAAA,CAAI,WAAW,GAAG,CAAA,KAAM,GAAA,KAAQ,MAAA,IAAU,GAAA,KAAQ,QAAA,IAAY,GAAA,KAAQ,MAAA,IAAU,QAAQ,MAAA,CAAA,EAAS;AAClH,MAAA,OAAA,GAAU,GAAA;AAAA,IACZ;AAAA,EACF;AAEA,EAAA,OAAO,EAAE,OAAA,EAAS,UAAA,EAAY,MAAA,EAAQ,IAAA,EAAK;AAC7C;AAEA,SAAS,SAAA,GAAkB;AACzB,EAAA,MAAM,GAAA,GAAM,gBAAA;AACZ,EAAA,OAAA,CAAQ,OAAO,KAAA,CAAM;AAAA,OAAA,EACd,GAAG,CAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA,qDAAA,EAQ2C,cAAc,CAAA;AAAA;AAAA;;AAAA;AAAA,EAAA,EAKjE,GAAG,CAAA;AAAA,EAAA,EACH,GAAG,CAAA;AAAA,EAAA,EACH,GAAG,CAAA;AAAA,EAAA,EACH,GAAG,CAAA;AAAA,CACN,CAAA;AACD;AAEA,eAAe,aAAa,UAAA,EAAsC;AAChE,EAAA,IAAI;AACF,IAAA,MAAMC,mBAAA,CAAG,OAAO,UAAU,CAAA;AAC1B,IAAA,OAAO,IAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAA;AAAA,EACT;AACF;AAEA,eAAe,UAAA,CACb,YACA,aAAA,EACiH;AACjH,EAAA,MAAM,SAAkD,EAAC;AACzD,EAAA,MAAM,EAAE,OAAA,EAAQ,GAAI,MAAMC,oCAAkB,UAAU,CAAA;AACtD,EAAA,MAAM,uBAAA,GAA8C;AAAA,IAClD,GAAG,OAAA;AAAA,IACH,GACI;AAAA,MACE,eAAA,CAAgB,KAAa,GAAA,EAAY;AACvC,QAAA,MAAA,CAAO,KAAK,EAAE,GAAA,EAAK,OAAA,EAAS,GAAA,CAAI,SAAS,CAAA;AAAA,MAC3C;AAAA;AAED,GACP;AACA,EAAA,MAAM,GAAA,GAAM,MAAM,gBAAA,CAAiB,uBAAuB,CAAA;AAC1D,EAAA,OAAO,EAAE,KAAK,MAAA,EAAO;AACvB;AAEA,eAAe,iBAAiB,OAAA,EAA6B;AAC3D,EAAA,MAAM,GAAA,GAAMC,gCAAc,OAAO,CAAA;AACjC,EAAA,MAAM,IAAI,YAAA,EAAa;AACvB,EAAA,OAAO,GAAA;AACT;AAEA,SAAS,WAAW,IAAA,EAA6D;AAC/E,EAAA,IAAI,OAAO,IAAA,KAAS,QAAA,EAAU,OAAO,IAAA;AACrC,EAAA,OAAO,IAAA,CAAK,YAAY,CAAA,EAAG,IAAA,CAAK,IAAI,CAAA,EAAA,EAAK,IAAA,CAAK,SAAS,CAAA,CAAA,CAAA,GAAM,IAAA,CAAK,IAAA;AACpE;AAEA,eAAe,QAAQ,UAAA,EAAqC;AAC1D,EAAA,MAAM,EAAE,OAAA,EAAQ,GAAI,MAAMD,oCAAkB,UAAU,CAAA;AACtD,EAAA,MAAM,GAAA,GAAM,MAAM,gBAAA,CAAiB,OAAO,CAAA;AAC1C,EAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,WAAA,EAAY,CAAE,QAAA,EAAS;AACzC,EAAA,MAAM,KAAA,GAA8D,OAAA,CAAQ,KAAA,IAAS,EAAC;AACtF,EAAA,OAAA,CAAQ,OAAO,KAAA,CAAM,CAAA,QAAA,EAAW,MAAM,MAAM,CAAA,cAAA,EAAiB,MAAM,MAAM,CAAA;AAAA,CAAa,CAAA;AACtF,EAAA,OAAA,CAAQ,MAAA,CAAO,MAAM,CAAA,OAAA,EAAU,KAAA,CAAM,IAAI,UAAU,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC;AAAA,CAAI,CAAA;AACnE,EAAA,MAAM,IAAI,QAAA,EAAS;AACnB,EAAA,OAAO,CAAA;AACT;AAEA,eAAe,UAAU,UAAA,EAAqC;AAC5D,EAAA,MAAM,EAAE,GAAA,EAAK,MAAA,KAAW,MAAM,UAAA,CAAW,UAAgB,CAAA;AACzD,EAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,WAAA,EAAY,CAAE,QAAA,EAAS;AACzC,EAAA,MAAM,IAAI,QAAA,EAAS;AACnB,EAAA,IAAI,MAAA,CAAO,SAAS,CAAA,EAAG;AACrB,IAAA,OAAA,CAAQ,MAAA,CAAO,KAAA,CAAM,CAAA,eAAA,EAAkB,MAAA,CAAO,MAAM,CAAA;AAAA,CAA+B,CAAA;AACnF,IAAA,KAAA,MAAW,KAAK,MAAA,EAAQ;AACtB,MAAA,OAAA,CAAQ,OAAO,KAAA,CAAM,CAAA,EAAA,EAAK,EAAE,GAAG,CAAA,EAAA,EAAK,EAAE,OAAO;AAAA,CAAI,CAAA;AAAA,IACnD;AACA,IAAA,OAAO,CAAA;AAAA,EACT;AACA,EAAA,OAAA,CAAQ,MAAA,CAAO,KAAA,CAAM,CAAA,SAAA,EAAY,KAAA,CAAM,MAAM,CAAA;AAAA,CAAwB,CAAA;AACrE,EAAA,OAAO,CAAA;AACT;AAEA,SAAS,gBAAgB,IAAA,EAAwB;AAC/C,EAAA,OAAO,IAAA,CAAK,IAAA;AACd;AAEA,SAAS,iBAAiB,IAAA,EAAwB;AAChD,EAAA,MAAM,IAAA,GAAA,CAAQ,IAAA,CAAK,WAAA,IAAe,EAAA,EAAI,OAAA,CAAQ,OAAO,GAAG,CAAA,CAAE,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA;AACrE,EAAA,OAAO,CAAA,EAAG,IAAA,CAAK,IAAI,CAAA,CAAA,EAAK,IAAA,CAAK,IAAI,CAAA,CAAA,EAAK,IAAI,CAAA,EAAG,IAAA,CAAK,MAAA,IAAU,EAAA,GAAK,WAAM,EAAE,CAAA,CAAA;AAC3E;AAEA,SAAS,eAAe,IAAA,EAAwB;AAC9C,EAAA,OAAO,IAAA,CAAK,SAAA;AAAA,IACV;AAAA,MACE,MAAM,IAAA,CAAK,IAAA;AAAA,MACX,MAAM,IAAA,CAAK,IAAA;AAAA,MACX,SAAS,IAAA,CAAK,OAAA;AAAA,MACd,aAAa,IAAA,CAAK,WAAA;AAAA,MAClB,MAAM,IAAA,CAAK,IAAA;AAAA,MACX,cAAc,IAAA,CAAK,YAAA;AAAA,MACnB,UAAU,IAAA,CAAK,QAAA;AAAA,MACf,YAAY,IAAA,CAAK;AAAA,KACnB;AAAA,IACA,IAAA;AAAA,IACA;AAAA,GACF;AACF;AAEA,eAAe,OAAA,CAAQ,YAAoB,MAAA,EAAsC;AAC/E,EAAA,MAAM,EAAE,OAAA,EAAQ,GAAI,MAAMA,oCAAkB,UAAU,CAAA;AACtD,EAAA,MAAM,GAAA,GAAM,MAAM,gBAAA,CAAiB,OAAO,CAAA;AAC1C,EAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,WAAA,EAAY,CAAE,QAAA,EAAS;AACzC,EAAA,MAAM,YAAY,MAAA,KAAW,OAAA,GAAU,eAAA,GAAkB,MAAA,KAAW,SAAS,cAAA,GAAiB,gBAAA;AAC9F,EAAA,IAAI,WAAW,QAAA,EAAU;AACvB,IAAA,OAAA,CAAQ,MAAA,CAAO,MAAM,yBAA2B,CAAA;AAAA,EAClD;AACA,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,IAAA,OAAA,CAAQ,MAAA,CAAO,KAAA,CAAM,SAAA,CAAU,IAAI,IAAI,IAAI,CAAA;AAAA,EAC7C;AACA,EAAA,MAAM,IAAI,QAAA,EAAS;AACnB,EAAA,OAAO,CAAA;AACT;AAEA,eAAe,IAAA,CAAK,IAAA,GAAiB,OAAA,CAAQ,IAAA,EAAuB;AAClE,EAAA,MAAM,EAAE,OAAA,EAAS,UAAA,EAAY,QAAQ,IAAA,EAAK,GAAI,UAAU,IAAI,CAAA;AAE5D,EAAA,IAAI,IAAA,IAAQ,YAAY,MAAA,EAAQ;AAC9B,IAAA,SAAA,EAAU;AACV,IAAA,OAAO,CAAA;AAAA,EACT;AAEA,EAAA,MAAM,YAAA,GAAe,MAAM,YAAA,CAAa,UAAU,CAAA;AAClD,EAAA,IAAI,CAAC,YAAA,EAAc;AACjB,IAAA,OAAA,CAAQ,MAAA,CAAO,KAAA,CAAM,CAAA,8BAAA,EAAiC,UAAU;AAAA,CAAI,CAAA;AACpE,IAAA,OAAO,CAAA;AAAA,EACT;AAEA,EAAA,QAAQ,OAAA;AAAS,IACf,KAAK,MAAA;AACH,MAAA,OAAO,QAAQ,UAAU,CAAA;AAAA,IAC3B,KAAK,QAAA;AACH,MAAA,OAAO,UAAU,UAAU,CAAA;AAAA,IAC7B,KAAK,MAAA;AACH,MAAA,OAAO,OAAA,CAAQ,YAAY,MAAM,CAAA;AAAA,IACnC;AACE,MAAA,SAAA,EAAU;AACV,MAAA,OAAO,OAAA,KAAY,SAAS,CAAA,GAAI,CAAA;AAAA;AAEtC;AAGA,eAAsB,IAAI,IAAA,EAAiC;AACzD,EAAA,OAAO,KAAK,IAAI,CAAA;AAClB;AAEA,IAAM,MAAA,GACJ,OAAO,OAAA,KAAY,WAAA,IACnB,QAAQ,IAAA,CAAK,CAAC,CAAA,KAAM,MAAA,IACpB,QAAQ,IAAA,CAAK,CAAC,CAAA,KAAME,iBAAA,CAAc,yPAAe,CAAA;AAEnD,IAAI,MAAA,EAAQ;AACV,EAAA,IAAA,EAAK,CACF,IAAA,CAAK,CAAC,IAAA,KAAS,OAAA,CAAQ,IAAA,CAAK,IAAI,CAAC,CAAA,CACjC,KAAA,CAAM,CAAC,GAAA,KAAQ;AACd,IAAA,OAAA,CAAQ,OAAO,KAAA,CAAM,MAAA,CAAO,KAAK,OAAA,IAAW,GAAG,IAAI,IAAI,CAAA;AACvD,IAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAChB,CAAC,CAAA;AACL","file":"cli.cjs","sourcesContent":["#!/usr/bin/env node\n/**\n * CLI for @easynet/agent-tool-hub: scan tools folders, verify tools, list tools.\n * Usage: agent-tool-hub <command> [options]\n * Commands: scan | verify | list\n */\n\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport fs from \"node:fs/promises\";\nimport { loadToolHubConfig } from \"./config/ToolHubConfig.js\";\nimport { createToolHub } from \"./tool-hub/ToolHub.js\";\nimport type { ToolHubInitOptions } from \"./tool-hub/ToolHub.js\";\nimport type { ToolSpec } from \"./types/ToolSpec.js\";\n\nconst DEFAULT_CONFIG = \"toolhub.yaml\";\n\ntype DetailLevel = \"short\" | \"normal\" | \"full\";\n\ninterface CliArgs {\n command: \"scan\" | \"verify\" | \"list\" | \"help\";\n configPath: string;\n detail: DetailLevel;\n help: boolean;\n}\n\nfunction parseArgv(argv: string[]): CliArgs {\n const args = argv.slice(2);\n let command: CliArgs[\"command\"] = \"help\";\n let configPath = path.resolve(process.cwd(), DEFAULT_CONFIG);\n let detail: DetailLevel = \"normal\";\n let help = false;\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n if (arg === \"--help\" || arg === \"-h\") {\n help = true;\n } else if (arg === \"--config\" || arg === \"-c\") {\n configPath = path.resolve(process.cwd(), args[++i] ?? \"\");\n } else if (arg === \"--detail\" || arg === \"-d\") {\n const v = (args[++i] ?? \"normal\").toLowerCase();\n detail = v === \"short\" || v === \"full\" ? v : \"normal\";\n } else if (arg && !arg.startsWith(\"-\") && (arg === \"scan\" || arg === \"verify\" || arg === \"list\" || arg === \"help\")) {\n command = arg;\n }\n }\n\n return { command, configPath, detail, help };\n}\n\nfunction printHelp(): void {\n const bin = \"agent-tool-hub\";\n process.stdout.write(`\nUsage: ${bin} <command> [options]\n\nCommands:\n scan Scan configured tool roots and load tools into the hub.\n verify Scan and verify tools; exit with code 1 if any discovery errors.\n list List discovered tools (use --detail to control output).\n\nOptions:\n --config, -c <path> Config file path (default: ./${DEFAULT_CONFIG}).\n --detail, -d <level> For 'list': short | normal | full (default: normal).\n --help, -h Show this help.\n\nExamples:\n ${bin} scan\n ${bin} verify -c ./toolhub.yaml\n ${bin} list --detail short\n ${bin} list --detail full\n`);\n}\n\nasync function ensureConfig(configPath: string): Promise<boolean> {\n try {\n await fs.access(configPath);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function runWithHub(\n configPath: string,\n collectErrors: boolean,\n): Promise<{ hub: Awaited<ReturnType<typeof createHubAndInit>>; errors: Array<{ dir: string; message: string }> }> {\n const errors: Array<{ dir: string; message: string }> = [];\n const { options } = await loadToolHubConfig(configPath);\n const optionsWithErrorHandler: ToolHubInitOptions = {\n ...options,\n ...(collectErrors\n ? {\n onDiscoverError(dir: string, err: Error) {\n errors.push({ dir, message: err.message });\n },\n }\n : {}),\n };\n const hub = await createHubAndInit(optionsWithErrorHandler);\n return { hub, errors };\n}\n\nasync function createHubAndInit(options: ToolHubInitOptions) {\n const hub = createToolHub(options);\n await hub.initAllTools();\n return hub;\n}\n\nfunction formatRoot(root: string | { path: string; namespace?: string }): string {\n if (typeof root === \"string\") return root;\n return root.namespace ? `${root.path} (${root.namespace})` : root.path;\n}\n\nasync function cmdScan(configPath: string): Promise<number> {\n const { options } = await loadToolHubConfig(configPath);\n const hub = await createHubAndInit(options);\n const specs = hub.getRegistry().snapshot();\n const roots: Array<string | { path: string; namespace?: string }> = options.roots ?? [];\n process.stdout.write(`Scanned ${specs.length} tool(s) from ${roots.length} root(s).\\n`);\n process.stdout.write(`Roots: ${roots.map(formatRoot).join(\", \")}\\n`);\n await hub.shutdown();\n return 0;\n}\n\nasync function cmdVerify(configPath: string): Promise<number> {\n const { hub, errors } = await runWithHub(configPath, true);\n const specs = hub.getRegistry().snapshot();\n await hub.shutdown();\n if (errors.length > 0) {\n process.stderr.write(`Verify failed: ${errors.length} error(s) during discovery.\\n`);\n for (const e of errors) {\n process.stderr.write(` ${e.dir}: ${e.message}\\n`);\n }\n return 1;\n }\n process.stdout.write(`Verified ${specs.length} tool(s). No errors.\\n`);\n return 0;\n}\n\nfunction formatSpecShort(spec: ToolSpec): string {\n return spec.name;\n}\n\nfunction formatSpecNormal(spec: ToolSpec): string {\n const desc = (spec.description ?? \"\").replace(/\\n/g, \" \").slice(0, 60);\n return `${spec.name}\\t${spec.kind}\\t${desc}${desc.length >= 60 ? \"…\" : \"\"}`;\n}\n\nfunction formatSpecFull(spec: ToolSpec): string {\n return JSON.stringify(\n {\n name: spec.name,\n kind: spec.kind,\n version: spec.version,\n description: spec.description,\n tags: spec.tags,\n capabilities: spec.capabilities,\n endpoint: spec.endpoint,\n resourceId: spec.resourceId,\n },\n null,\n 2,\n );\n}\n\nasync function cmdList(configPath: string, detail: DetailLevel): Promise<number> {\n const { options } = await loadToolHubConfig(configPath);\n const hub = await createHubAndInit(options);\n const specs = hub.getRegistry().snapshot();\n const formatter = detail === \"short\" ? formatSpecShort : detail === \"full\" ? formatSpecFull : formatSpecNormal;\n if (detail === \"normal\") {\n process.stdout.write(\"name\\tkind\\tdescription\\n\");\n }\n for (const spec of specs) {\n process.stdout.write(formatter(spec) + \"\\n\");\n }\n await hub.shutdown();\n return 0;\n}\n\nasync function main(argv: string[] = process.argv): Promise<number> {\n const { command, configPath, detail, help } = parseArgv(argv);\n\n if (help || command === \"help\") {\n printHelp();\n return 0;\n }\n\n const configExists = await ensureConfig(configPath);\n if (!configExists) {\n process.stderr.write(`Error: config file not found: ${configPath}\\n`);\n return 1;\n }\n\n switch (command) {\n case \"scan\":\n return cmdScan(configPath);\n case \"verify\":\n return cmdVerify(configPath);\n case \"list\":\n return cmdList(configPath, detail);\n default:\n printHelp();\n return command === \"help\" ? 0 : 1;\n }\n}\n\n/** Run CLI with the given argv (same shape as process.argv). Exported for tests. */\nexport async function run(argv: string[]): Promise<number> {\n return main(argv);\n}\n\nconst isMain =\n typeof process !== \"undefined\" &&\n process.argv[1] !== undefined &&\n process.argv[1] === fileURLToPath(import.meta.url);\n\nif (isMain) {\n main()\n .then((code) => process.exit(code))\n .catch((err) => {\n process.stderr.write(String(err?.message ?? err) + \"\\n\");\n process.exit(1);\n });\n}\n"]}
package/dist/cli.d.cts ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * CLI for @easynet/agent-tool-hub: scan tools folders, verify tools, list tools.
4
+ * Usage: agent-tool-hub <command> [options]
5
+ * Commands: scan | verify | list
6
+ */
7
+ /** Run CLI with the given argv (same shape as process.argv). Exported for tests. */
8
+ declare function run(argv: string[]): Promise<number>;
9
+
10
+ export { run };
package/dist/cli.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * CLI for @easynet/agent-tool-hub: scan tools folders, verify tools, list tools.
4
+ * Usage: agent-tool-hub <command> [options]
5
+ * Commands: scan | verify | list
6
+ */
7
+ /** Run CLI with the given argv (same shape as process.argv). Exported for tests. */
8
+ declare function run(argv: string[]): Promise<number>;
9
+
10
+ export { run };