proofscan 0.9.1 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +10 -6
- package/dist/cli.js.map +1 -1
- package/dist/commands/index.d.ts +2 -0
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +4 -0
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/proxy.d.ts +11 -0
- package/dist/commands/proxy.d.ts.map +1 -0
- package/dist/commands/proxy.js +119 -0
- package/dist/commands/proxy.js.map +1 -0
- package/dist/commands/tool.d.ts +13 -0
- package/dist/commands/tool.d.ts.map +1 -0
- package/dist/commands/tool.js +376 -0
- package/dist/commands/tool.js.map +1 -0
- package/dist/proxy/index.d.ts +9 -0
- package/dist/proxy/index.d.ts.map +1 -0
- package/dist/proxy/index.js +9 -0
- package/dist/proxy/index.js.map +1 -0
- package/dist/proxy/logger.d.ts +36 -0
- package/dist/proxy/logger.d.ts.map +1 -0
- package/dist/proxy/logger.js +72 -0
- package/dist/proxy/logger.js.map +1 -0
- package/dist/proxy/mcp-server.d.ts +93 -0
- package/dist/proxy/mcp-server.d.ts.map +1 -0
- package/dist/proxy/mcp-server.js +311 -0
- package/dist/proxy/mcp-server.js.map +1 -0
- package/dist/proxy/request-router.d.ts +26 -0
- package/dist/proxy/request-router.d.ts.map +1 -0
- package/dist/proxy/request-router.js +90 -0
- package/dist/proxy/request-router.js.map +1 -0
- package/dist/proxy/tool-aggregator.d.ts +46 -0
- package/dist/proxy/tool-aggregator.d.ts.map +1 -0
- package/dist/proxy/tool-aggregator.js +112 -0
- package/dist/proxy/tool-aggregator.js.map +1 -0
- package/dist/proxy/types.d.ts +117 -0
- package/dist/proxy/types.d.ts.map +1 -0
- package/dist/proxy/types.js +21 -0
- package/dist/proxy/types.js.map +1 -0
- package/dist/shell/repl.d.ts.map +1 -1
- package/dist/shell/repl.js +11 -0
- package/dist/shell/repl.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -25,7 +25,7 @@ import { setOutputOptions } from './utils/output.js';
|
|
|
25
25
|
const require = createRequire(import.meta.url);
|
|
26
26
|
const packageJson = require('../package.json');
|
|
27
27
|
const VERSION = packageJson.version;
|
|
28
|
-
import { createConfigCommand, createConnectorsCommand, createScanCommand, createMonitorCommand, createSessionsCommand, createArchiveCommand, createViewCommand, createTreeCommand, createExploreCommand, createStatusCommand, createEventsCommand, createRpcCommand, createSummaryCommand, createPermissionsCommand, createRecordCommand, createDoctorCommand, createShellCommand, createSecretsCommand, } from './commands/index.js';
|
|
28
|
+
import { createConfigCommand, createConnectorsCommand, createScanCommand, createMonitorCommand, createSessionsCommand, createArchiveCommand, createViewCommand, createTreeCommand, createExploreCommand, createStatusCommand, createEventsCommand, createRpcCommand, createSummaryCommand, createPermissionsCommand, createRecordCommand, createDoctorCommand, createShellCommand, createSecretsCommand, createToolCommand, createProxyCommand, } from './commands/index.js';
|
|
29
29
|
const program = new Command();
|
|
30
30
|
// Global state for config path
|
|
31
31
|
let globalConfigPath;
|
|
@@ -47,6 +47,7 @@ Common Commands:
|
|
|
47
47
|
rpc View RPC call details (list, show)
|
|
48
48
|
summary Show session summary
|
|
49
49
|
permissions Show permission stats per category
|
|
50
|
+
tool MCP tool operations (ls, show, call)
|
|
50
51
|
|
|
51
52
|
Management:
|
|
52
53
|
archive, a Archive and prune old data
|
|
@@ -55,9 +56,6 @@ Management:
|
|
|
55
56
|
secrets Secret management (list, set, edit, prune, export, import)
|
|
56
57
|
doctor Diagnose and fix database issues
|
|
57
58
|
|
|
58
|
-
Shell-only Commands (run: pfscan shell):
|
|
59
|
-
tool ls | tool show <name> | send <name>
|
|
60
|
-
|
|
61
59
|
Shortcuts:
|
|
62
60
|
v=view t=tree e=explore s=scan st=status a=archive c=config
|
|
63
61
|
|
|
@@ -68,6 +66,8 @@ Examples:
|
|
|
68
66
|
pfscan view --pairs # View request/response pairs
|
|
69
67
|
pfscan tree # Show structure overview
|
|
70
68
|
pfscan scan start mcp # Start scanning connector 'mcp'
|
|
69
|
+
pfscan tool ls mcp # List tools on connector
|
|
70
|
+
pfscan tool call mcp echo --args '{"msg":"hi"}'
|
|
71
71
|
`;
|
|
72
72
|
program
|
|
73
73
|
.name('pfscan')
|
|
@@ -170,6 +170,10 @@ program.addCommand(createSecretsCommand(getConfigPath));
|
|
|
170
170
|
const secretCmd = createSecretsCommand(getConfigPath);
|
|
171
171
|
secretCmd.name('secret').description('Alias for secrets');
|
|
172
172
|
program.addCommand(secretCmd);
|
|
173
|
+
// tool (Phase 4.4: CLI tool commands - ls, show, call)
|
|
174
|
+
program.addCommand(createToolCommand(getConfigPath));
|
|
175
|
+
// proxy (Phase 5.0: MCP Proxy server)
|
|
176
|
+
program.addCommand(createProxyCommand(getConfigPath));
|
|
173
177
|
// ============================================================
|
|
174
178
|
// Default action: pfscan → pfscan view
|
|
175
179
|
// ============================================================
|
|
@@ -181,10 +185,10 @@ function hasHelpFlag() {
|
|
|
181
185
|
const KNOWN_COMMANDS = new Set([
|
|
182
186
|
'view', 'v', 'tree', 't', 'explore', 'e', 'status', 'st',
|
|
183
187
|
'scan', 's', 'archive', 'a', 'config', 'c',
|
|
184
|
-
'connectors', 'connector', 'sessions', 'monitor', 'events', 'rpc', 'summary', 'permissions', 'record', 'doctor', 'shell', 'secrets', 'secret', 'help'
|
|
188
|
+
'connectors', 'connector', 'sessions', 'monitor', 'events', 'rpc', 'summary', 'permissions', 'record', 'doctor', 'shell', 'secrets', 'secret', 'tool', 'proxy', 'help'
|
|
185
189
|
]);
|
|
186
190
|
// Shell-only commands (not available as CLI commands)
|
|
187
|
-
const SHELL_ONLY_COMMANDS = new Set(['
|
|
191
|
+
const SHELL_ONLY_COMMANDS = new Set(['send']);
|
|
188
192
|
/**
|
|
189
193
|
* Check if no subcommand is provided (only options like --config, --json)
|
|
190
194
|
* Returns: { hasCommand: boolean, unknownCommand?: string }
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErD,iCAAiC;AACjC,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,WAAW,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAC/C,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC;AACpC,OAAO,EACL,mBAAmB,EACnB,uBAAuB,EACvB,iBAAiB,EACjB,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,EACjB,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,EACnB,gBAAgB,EAChB,oBAAoB,EACpB,wBAAwB,EACxB,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErD,iCAAiC;AACjC,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,WAAW,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAC/C,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC;AACpC,OAAO,EACL,mBAAmB,EACnB,uBAAuB,EACvB,iBAAiB,EACjB,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,EACjB,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,EACnB,gBAAgB,EAChB,oBAAoB,EACpB,wBAAwB,EACxB,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,EACpB,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAE7B,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,+BAA+B;AAC/B,IAAI,gBAAoC,CAAC;AAEzC,SAAS,aAAa;IACpB,OAAO,iBAAiB,CAAC,EAAE,UAAU,EAAE,gBAAgB,EAAE,CAAC,CAAC;AAC7D,CAAC;AAED,yBAAyB;AACzB,MAAM,WAAW,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmCnB,CAAC;AAEF,OAAO;KACJ,IAAI,CAAC,QAAQ,CAAC;KACd,WAAW,CAAC,kEAAkE,CAAC;KAC/E,OAAO,CAAC,OAAO,CAAC;KAChB,MAAM,CAAC,qBAAqB,EAAE,qBAAqB,CAAC;KACpD,MAAM,CAAC,QAAQ,EAAE,uBAAuB,CAAC;KACzC,MAAM,CAAC,eAAe,EAAE,gBAAgB,CAAC;KACzC,WAAW,CAAC,QAAQ,EAAE,WAAW,CAAC;KAClC,IAAI,CAAC,WAAW,EAAE,CAAC,WAAW,EAAE,EAAE;IACjC,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC;IAChC,gBAAgB,GAAG,IAAI,CAAC,MAAM,CAAC;IAC/B,gBAAgB,CAAC;QACf,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,OAAO,EAAE,IAAI,CAAC,OAAO;KACtB,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEL,+DAA+D;AAC/D,2CAA2C;AAC3C,+DAA+D;AAE/D,yBAAyB;AACzB,MAAM,OAAO,GAAG,iBAAiB,CAAC,aAAa,CAAC,CAAC;AACjD,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;AAE5B,kBAAkB;AAClB,MAAM,IAAI,GAAG,iBAAiB,CAAC,aAAa,CAAC,CAAC;AAC9C,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,CAAC,gBAAgB,CAAC,CAAC;AAC7C,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;AAEzB,OAAO;AACP,MAAM,OAAO,GAAG,iBAAiB,CAAC,aAAa,CAAC,CAAC;AACjD,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;AAE5B,kBAAkB;AAClB,MAAM,IAAI,GAAG,iBAAiB,CAAC,aAAa,CAAC,CAAC;AAC9C,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,CAAC,gBAAgB,CAAC,CAAC;AAC7C,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;AAEzB,UAAU;AACV,MAAM,UAAU,GAAG,oBAAoB,CAAC,aAAa,CAAC,CAAC;AACvD,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;AAE/B,qBAAqB;AACrB,MAAM,IAAI,GAAG,oBAAoB,CAAC,aAAa,CAAC,CAAC;AACjD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,CAAC,mBAAmB,CAAC,CAAC;AAChD,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;AAEzB,SAAS;AACT,MAAM,SAAS,GAAG,mBAAmB,CAAC,aAAa,CAAC,CAAC;AACrD,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;AAE9B,qBAAqB;AACrB,MAAM,KAAK,GAAG,mBAAmB,CAAC,aAAa,CAAC,CAAC;AACjD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,kBAAkB,CAAC,CAAC;AACjD,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;AAE1B,+DAA+D;AAC/D,mDAAmD;AACnD,+DAA+D;AAE/D,OAAO;AACP,MAAM,OAAO,GAAG,iBAAiB,CAAC,aAAa,CAAC,CAAC;AACjD,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;AAE5B,kBAAkB;AAClB,MAAM,IAAI,GAAG,iBAAiB,CAAC,aAAa,CAAC,CAAC;AAC9C,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,CAAC,gBAAgB,CAAC,CAAC;AAC7C,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;AAEzB,UAAU;AACV,MAAM,UAAU,GAAG,oBAAoB,CAAC,aAAa,CAAC,CAAC;AACvD,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;AAE/B,qBAAqB;AACrB,MAAM,IAAI,GAAG,oBAAoB,CAAC,aAAa,CAAC,CAAC;AACjD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,CAAC,mBAAmB,CAAC,CAAC;AAChD,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;AAEzB,SAAS;AACT,MAAM,SAAS,GAAG,mBAAmB,CAAC,aAAa,CAAC,CAAC;AACrD,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;AAE9B,oBAAoB;AACpB,MAAM,IAAI,GAAG,mBAAmB,CAAC,aAAa,CAAC,CAAC;AAChD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,CAAC,kBAAkB,CAAC,CAAC;AAC/C,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;AAEzB,aAAa;AACb,OAAO,CAAC,UAAU,CAAC,uBAAuB,CAAC,aAAa,CAAC,CAAC,CAAC;AAE3D,8CAA8C;AAC9C,MAAM,YAAY,GAAG,uBAAuB,CAAC,aAAa,CAAC,CAAC;AAC5D,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,WAAW,CAAC,sBAAsB,CAAC,CAAC;AACnE,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AAEjC,8EAA8E;AAC9E,OAAO,CAAC,UAAU,CAAC,qBAAqB,CAAC,aAAa,CAAC,CAAC,CAAC;AAEzD,4DAA4D;AAC5D,OAAO,CAAC,UAAU,CAAC,oBAAoB,CAAC,aAAa,CAAC,CAAC,CAAC;AAExD,+CAA+C;AAC/C,OAAO,CAAC,UAAU,CAAC,mBAAmB,CAAC,aAAa,CAAC,CAAC,CAAC;AAEvD,sCAAsC;AACtC,OAAO,CAAC,UAAU,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAC,CAAC;AAEpD,wDAAwD;AACxD,OAAO,CAAC,UAAU,CAAC,oBAAoB,CAAC,aAAa,CAAC,CAAC,CAAC;AAExD,mDAAmD;AACnD,OAAO,CAAC,UAAU,CAAC,wBAAwB,CAAC,aAAa,CAAC,CAAC,CAAC;AAE5D,mCAAmC;AACnC,OAAO,CAAC,UAAU,CAAC,mBAAmB,CAAC,aAAa,CAAC,CAAC,CAAC;AAEvD,6CAA6C;AAC7C,OAAO,CAAC,UAAU,CAAC,mBAAmB,CAAC,aAAa,CAAC,CAAC,CAAC;AAEvD,oCAAoC;AACpC,OAAO,CAAC,UAAU,CAAC,kBAAkB,CAAC,aAAa,CAAC,CAAC,CAAC;AAEtD,yCAAyC;AACzC,OAAO,CAAC,UAAU,CAAC,oBAAoB,CAAC,aAAa,CAAC,CAAC,CAAC;AAExD,sDAAsD;AACtD,MAAM,SAAS,GAAG,oBAAoB,CAAC,aAAa,CAAC,CAAC;AACtD,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,WAAW,CAAC,mBAAmB,CAAC,CAAC;AAC1D,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;AAE9B,uDAAuD;AACvD,OAAO,CAAC,UAAU,CAAC,iBAAiB,CAAC,aAAa,CAAC,CAAC,CAAC;AAErD,sCAAsC;AACtC,OAAO,CAAC,UAAU,CAAC,kBAAkB,CAAC,aAAa,CAAC,CAAC,CAAC;AAEtD,+DAA+D;AAC/D,uCAAuC;AACvC,+DAA+D;AAE/D,uEAAuE;AACvE,SAAS,WAAW;IAClB,OAAO,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACxE,CAAC;AAED,iDAAiD;AACjD,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC;IAC7B,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI;IACxD,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG;IAC1C,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CACvK,CAAC,CAAC;AAEH,sDAAsD;AACtD,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AAE9C;;;GAGG;AACH,SAAS,eAAe;IACtB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC7C,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC5B,qCAAqC;QACrC,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACxB,8DAA8D;YAC9D,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,UAAU,EAAE,CAAC;gBACvC,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM;oBAAE,CAAC,EAAE,CAAC;YACvC,CAAC;YACD,SAAS;QACX,CAAC;QACD,gEAAgE;QAChE,IAAI,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAC5B,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;QAC9B,CAAC;QACD,gDAAgD;QAChD,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,cAAc,EAAE,GAAG,EAAE,CAAC;IACpD,CAAC;IACD,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;AAC/B,CAAC;AAED,4EAA4E;AAC5E,uEAAuE;AACvE,MAAM,eAAe,GAAG,eAAe,EAAE,CAAC;AAE1C,IAAI,eAAe,CAAC,cAAc,EAAE,CAAC;IACnC,iDAAiD;IACjD,MAAM,GAAG,GAAG,eAAe,CAAC,cAAc,CAAC;IAC3C,MAAM,WAAW,GAAG,mBAAmB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAEjD,OAAO,CAAC,KAAK,CAAC,sBAAsB,GAAG,EAAE,CAAC,CAAC;IAC3C,IAAI,WAAW,EAAE,CAAC;QAChB,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,8CAA8C,CAAC,CAAC;IACzE,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,+CAA+C,CAAC,CAAC;IAC/D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,IAAI,CAAC,eAAe,CAAC,UAAU,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;IAClD,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;AACpC,CAAC;AAED,gBAAgB;AAChB,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
package/dist/commands/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AACA,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAG7B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAG5B,cAAc,UAAU,CAAC;AAGzB,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAG5B,cAAc,YAAY,CAAC;AAG3B,cAAc,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AACA,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAG7B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAG5B,cAAc,UAAU,CAAC;AAGzB,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAG5B,cAAc,YAAY,CAAC;AAG3B,cAAc,cAAc,CAAC;AAG7B,cAAc,WAAW,CAAC;AAG1B,cAAc,YAAY,CAAC"}
|
package/dist/commands/index.js
CHANGED
|
@@ -22,4 +22,8 @@ export * from './doctor.js';
|
|
|
22
22
|
export * from './shell.js';
|
|
23
23
|
// Phase 3.6: Secrets management
|
|
24
24
|
export * from './secrets.js';
|
|
25
|
+
// Phase 4.4: Tool CLI commands
|
|
26
|
+
export * from './tool.js';
|
|
27
|
+
// Phase 5.0: MCP Proxy
|
|
28
|
+
export * from './proxy.js';
|
|
25
29
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA,oBAAoB;AACpB,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAE7B,yBAAyB;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAE5B,yBAAyB;AACzB,cAAc,UAAU,CAAC;AAEzB,uBAAuB;AACvB,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAE5B,sBAAsB;AACtB,cAAc,YAAY,CAAC;AAE3B,gCAAgC;AAChC,cAAc,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA,oBAAoB;AACpB,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAE7B,yBAAyB;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAE5B,yBAAyB;AACzB,cAAc,UAAU,CAAC;AAEzB,uBAAuB;AACvB,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAE5B,sBAAsB;AACtB,cAAc,YAAY,CAAC;AAE3B,gCAAgC;AAChC,cAAc,cAAc,CAAC;AAE7B,+BAA+B;AAC/B,cAAc,WAAW,CAAC;AAE1B,uBAAuB;AACvB,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Proxy Command (Phase 5.0)
|
|
3
|
+
*
|
|
4
|
+
* pfscan proxy start [options]
|
|
5
|
+
*
|
|
6
|
+
* Starts an MCP proxy server that aggregates tools from multiple
|
|
7
|
+
* backend connectors.
|
|
8
|
+
*/
|
|
9
|
+
import { Command } from 'commander';
|
|
10
|
+
export declare function createProxyCommand(getConfigPath: () => string): Command;
|
|
11
|
+
//# sourceMappingURL=proxy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../../src/commands/proxy.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,wBAAgB,kBAAkB,CAAC,aAAa,EAAE,MAAM,MAAM,GAAG,OAAO,CAgIvE"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Proxy Command (Phase 5.0)
|
|
3
|
+
*
|
|
4
|
+
* pfscan proxy start [options]
|
|
5
|
+
*
|
|
6
|
+
* Starts an MCP proxy server that aggregates tools from multiple
|
|
7
|
+
* backend connectors.
|
|
8
|
+
*/
|
|
9
|
+
import { Command } from 'commander';
|
|
10
|
+
import { ConfigManager } from '../config/index.js';
|
|
11
|
+
import { McpProxyServer, setVerbose, logger } from '../proxy/index.js';
|
|
12
|
+
import { getOutputOptions } from '../utils/output.js';
|
|
13
|
+
export function createProxyCommand(getConfigPath) {
|
|
14
|
+
const cmd = new Command('proxy')
|
|
15
|
+
.description('MCP proxy server operations');
|
|
16
|
+
cmd
|
|
17
|
+
.command('start')
|
|
18
|
+
.description('Start MCP proxy server (stdio)')
|
|
19
|
+
.option('--connectors <ids>', 'Connector IDs to expose (comma-separated)')
|
|
20
|
+
.option('--all', 'Expose all enabled connectors')
|
|
21
|
+
.option('--timeout <seconds>', 'Timeout for backend calls in seconds (default: 30)', '30')
|
|
22
|
+
.action(async (options) => {
|
|
23
|
+
// Set up logging - use global verbose option from CLI
|
|
24
|
+
const globalOpts = getOutputOptions();
|
|
25
|
+
if (globalOpts.verbose) {
|
|
26
|
+
setVerbose(true);
|
|
27
|
+
}
|
|
28
|
+
// Validate mutually exclusive options
|
|
29
|
+
if (options.connectors && options.all) {
|
|
30
|
+
logger.error('Cannot use --connectors and --all together');
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
if (!options.connectors && !options.all) {
|
|
34
|
+
logger.error('Must specify --connectors <ids> or --all');
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
// Load config
|
|
38
|
+
const configPath = getConfigPath();
|
|
39
|
+
const manager = new ConfigManager(configPath);
|
|
40
|
+
const configDir = manager.getConfigDir();
|
|
41
|
+
let config;
|
|
42
|
+
try {
|
|
43
|
+
config = await manager.load();
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
47
|
+
logger.error(`Failed to load config: ${msg}`);
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
// Resolve connectors
|
|
51
|
+
let connectors;
|
|
52
|
+
if (options.all) {
|
|
53
|
+
// All enabled connectors
|
|
54
|
+
connectors = config.connectors.filter((c) => c.enabled);
|
|
55
|
+
if (connectors.length === 0) {
|
|
56
|
+
logger.error('No enabled connectors found');
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
logger.info(`Using ${connectors.length} enabled connector(s)`);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
// Specific connectors
|
|
63
|
+
const ids = options.connectors.split(',').map((id) => id.trim());
|
|
64
|
+
connectors = [];
|
|
65
|
+
for (const id of ids) {
|
|
66
|
+
const connector = config.connectors.find((c) => c.id === id);
|
|
67
|
+
if (!connector) {
|
|
68
|
+
logger.error(`Connector not found: ${id}`);
|
|
69
|
+
process.exit(1);
|
|
70
|
+
}
|
|
71
|
+
if (!connector.enabled) {
|
|
72
|
+
logger.warn(`Connector disabled, skipping: ${id}`);
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
connectors.push(connector);
|
|
76
|
+
}
|
|
77
|
+
if (connectors.length === 0) {
|
|
78
|
+
logger.error('No valid connectors to expose');
|
|
79
|
+
process.exit(1);
|
|
80
|
+
}
|
|
81
|
+
logger.info(`Using ${connectors.length} connector(s): ${connectors.map(c => c.id).join(', ')}`);
|
|
82
|
+
}
|
|
83
|
+
// Parse timeout
|
|
84
|
+
const timeout = parseInt(options.timeout, 10);
|
|
85
|
+
if (isNaN(timeout) || timeout < 1 || timeout > 300) {
|
|
86
|
+
logger.error('Invalid timeout: must be 1-300 seconds');
|
|
87
|
+
process.exit(1);
|
|
88
|
+
}
|
|
89
|
+
// Create and start server
|
|
90
|
+
const server = new McpProxyServer({
|
|
91
|
+
connectors,
|
|
92
|
+
configDir,
|
|
93
|
+
verbose: globalOpts.verbose,
|
|
94
|
+
timeout,
|
|
95
|
+
});
|
|
96
|
+
// Handle signals for graceful shutdown
|
|
97
|
+
const shutdown = () => {
|
|
98
|
+
logger.info('Received shutdown signal');
|
|
99
|
+
server.stop();
|
|
100
|
+
process.exit(0);
|
|
101
|
+
};
|
|
102
|
+
process.on('SIGINT', shutdown);
|
|
103
|
+
process.on('SIGTERM', shutdown);
|
|
104
|
+
// Handle server stop
|
|
105
|
+
server.on('stopped', () => {
|
|
106
|
+
process.exit(0);
|
|
107
|
+
});
|
|
108
|
+
try {
|
|
109
|
+
await server.start();
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
113
|
+
logger.error(`Failed to start server: ${msg}`);
|
|
114
|
+
process.exit(1);
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
return cmd;
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=proxy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy.js","sourceRoot":"","sources":["../../src/commands/proxy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool command - MCP tool operations (Phase 4.4)
|
|
3
|
+
*
|
|
4
|
+
* pfscan tool ls <connector> # List tools
|
|
5
|
+
* pfscan tool show <connector> <tool-name> # Show tool details
|
|
6
|
+
* pfscan tool call <connector> <tool-name> # Call a tool
|
|
7
|
+
*
|
|
8
|
+
* Stateless design: Each command spawns a fresh MCP connection.
|
|
9
|
+
* 1 command = 1 session (initialize → execute → disconnect)
|
|
10
|
+
*/
|
|
11
|
+
import { Command } from 'commander';
|
|
12
|
+
export declare function createToolCommand(getConfigPath: () => string): Command;
|
|
13
|
+
//# sourceMappingURL=tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../src/commands/tool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA2IpC,wBAAgB,iBAAiB,CAAC,aAAa,EAAE,MAAM,MAAM,GAAG,OAAO,CAuStE"}
|
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool command - MCP tool operations (Phase 4.4)
|
|
3
|
+
*
|
|
4
|
+
* pfscan tool ls <connector> # List tools
|
|
5
|
+
* pfscan tool show <connector> <tool-name> # Show tool details
|
|
6
|
+
* pfscan tool call <connector> <tool-name> # Call a tool
|
|
7
|
+
*
|
|
8
|
+
* Stateless design: Each command spawns a fresh MCP connection.
|
|
9
|
+
* 1 command = 1 session (initialize → execute → disconnect)
|
|
10
|
+
*/
|
|
11
|
+
import { Command } from 'commander';
|
|
12
|
+
import * as fs from 'fs';
|
|
13
|
+
import { ConfigManager } from '../config/index.js';
|
|
14
|
+
import { getConnector, listTools, getTool, callTool, formatInputSchema, } from '../tools/adapter.js';
|
|
15
|
+
import { output, getOutputOptions } from '../utils/output.js';
|
|
16
|
+
/** Default stdin read timeout in milliseconds */
|
|
17
|
+
const STDIN_TIMEOUT_MS = 5000;
|
|
18
|
+
/** Minimum allowed timeout in seconds */
|
|
19
|
+
const MIN_TIMEOUT_SEC = 1;
|
|
20
|
+
/** Maximum allowed timeout in seconds */
|
|
21
|
+
const MAX_TIMEOUT_SEC = 300;
|
|
22
|
+
/**
|
|
23
|
+
* Parse and validate timeout value
|
|
24
|
+
*/
|
|
25
|
+
function parseTimeout(timeoutStr) {
|
|
26
|
+
const timeout = parseInt(timeoutStr, 10);
|
|
27
|
+
if (isNaN(timeout) || timeout < MIN_TIMEOUT_SEC || timeout > MAX_TIMEOUT_SEC) {
|
|
28
|
+
throw new Error(`Invalid timeout: must be ${MIN_TIMEOUT_SEC}-${MAX_TIMEOUT_SEC} seconds`);
|
|
29
|
+
}
|
|
30
|
+
return timeout;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Validate and get connector, with proper error messages
|
|
34
|
+
*/
|
|
35
|
+
async function validateConnector(getConfigPath, connectorId) {
|
|
36
|
+
const manager = new ConfigManager(getConfigPath());
|
|
37
|
+
const configDir = manager.getConfigDir();
|
|
38
|
+
const connector = await getConnector(getConfigPath(), connectorId);
|
|
39
|
+
if (!connector) {
|
|
40
|
+
console.error(`Connector not found: ${connectorId}`);
|
|
41
|
+
process.exit(1);
|
|
42
|
+
}
|
|
43
|
+
if (!connector.enabled) {
|
|
44
|
+
console.error(`Connector is disabled: ${connectorId}`);
|
|
45
|
+
console.error(`Enable it with: pfscan connectors enable --id ${connectorId}`);
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
return { connector, configDir };
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Read arguments from various sources
|
|
52
|
+
*/
|
|
53
|
+
async function resolveArgs(options) {
|
|
54
|
+
// Priority: --args > --args-file > --stdin
|
|
55
|
+
if (options.args) {
|
|
56
|
+
try {
|
|
57
|
+
return JSON.parse(options.args);
|
|
58
|
+
}
|
|
59
|
+
catch (e) {
|
|
60
|
+
throw new Error(`Invalid JSON in --args: ${e instanceof Error ? e.message : e}`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (options.argsFile) {
|
|
64
|
+
// Validate file exists and is readable
|
|
65
|
+
if (!fs.existsSync(options.argsFile)) {
|
|
66
|
+
throw new Error(`File not found: ${options.argsFile}`);
|
|
67
|
+
}
|
|
68
|
+
const stat = fs.statSync(options.argsFile);
|
|
69
|
+
if (!stat.isFile()) {
|
|
70
|
+
throw new Error(`Not a file: ${options.argsFile}`);
|
|
71
|
+
}
|
|
72
|
+
try {
|
|
73
|
+
const content = fs.readFileSync(options.argsFile, 'utf-8');
|
|
74
|
+
return JSON.parse(content);
|
|
75
|
+
}
|
|
76
|
+
catch (e) {
|
|
77
|
+
if (e instanceof SyntaxError) {
|
|
78
|
+
throw new Error(`Invalid JSON in file ${options.argsFile}: ${e.message}`);
|
|
79
|
+
}
|
|
80
|
+
throw new Error(`Failed to read --args-file: ${e instanceof Error ? e.message : e}`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
if (options.stdin) {
|
|
84
|
+
// Check if stdin is a TTY (no pipe)
|
|
85
|
+
if (process.stdin.isTTY) {
|
|
86
|
+
throw new Error('--stdin requires piped input (e.g., echo \'{"key":"value"}\' | pfscan tool call ...)');
|
|
87
|
+
}
|
|
88
|
+
return new Promise((resolve, reject) => {
|
|
89
|
+
let data = '';
|
|
90
|
+
const timeoutId = setTimeout(() => {
|
|
91
|
+
process.stdin.destroy();
|
|
92
|
+
reject(new Error(`Timeout reading from stdin after ${STDIN_TIMEOUT_MS}ms`));
|
|
93
|
+
}, STDIN_TIMEOUT_MS);
|
|
94
|
+
process.stdin.setEncoding('utf-8');
|
|
95
|
+
process.stdin.on('data', (chunk) => { data += chunk; });
|
|
96
|
+
process.stdin.on('end', () => {
|
|
97
|
+
clearTimeout(timeoutId);
|
|
98
|
+
try {
|
|
99
|
+
resolve(JSON.parse(data || '{}'));
|
|
100
|
+
}
|
|
101
|
+
catch (e) {
|
|
102
|
+
reject(new Error(`Invalid JSON from stdin: ${e instanceof Error ? e.message : e}`));
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
process.stdin.on('error', (err) => {
|
|
106
|
+
clearTimeout(timeoutId);
|
|
107
|
+
reject(err);
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
// Default: empty args
|
|
112
|
+
return {};
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Truncate string to max length
|
|
116
|
+
*/
|
|
117
|
+
function truncate(str, maxLen) {
|
|
118
|
+
if (maxLen < 4)
|
|
119
|
+
return str.slice(0, maxLen);
|
|
120
|
+
if (str.length <= maxLen)
|
|
121
|
+
return str;
|
|
122
|
+
return str.slice(0, maxLen - 3) + '...';
|
|
123
|
+
}
|
|
124
|
+
export function createToolCommand(getConfigPath) {
|
|
125
|
+
const cmd = new Command('tool')
|
|
126
|
+
.description('MCP tool operations');
|
|
127
|
+
// ─────────────────────────────────────────────────────────────────
|
|
128
|
+
// tool ls <connector>
|
|
129
|
+
// ─────────────────────────────────────────────────────────────────
|
|
130
|
+
cmd
|
|
131
|
+
.command('ls <connector>')
|
|
132
|
+
.description('List tools available on a connector')
|
|
133
|
+
.option('--timeout <sec>', 'Timeout in seconds', '30')
|
|
134
|
+
.action(async (connectorId, options) => {
|
|
135
|
+
try {
|
|
136
|
+
const timeout = parseTimeout(options.timeout);
|
|
137
|
+
const { connector, configDir } = await validateConnector(getConfigPath, connectorId);
|
|
138
|
+
const ctx = {
|
|
139
|
+
connectorId,
|
|
140
|
+
configDir,
|
|
141
|
+
};
|
|
142
|
+
const result = await listTools(ctx, connector, {
|
|
143
|
+
timeout,
|
|
144
|
+
});
|
|
145
|
+
if (result.error) {
|
|
146
|
+
console.error(`Failed to list tools: ${result.error}`);
|
|
147
|
+
if (result.sessionId) {
|
|
148
|
+
console.error(`Session: ${result.sessionId.slice(0, 8)} (recorded as failure)`);
|
|
149
|
+
}
|
|
150
|
+
process.exit(1);
|
|
151
|
+
}
|
|
152
|
+
if (getOutputOptions().json) {
|
|
153
|
+
output({
|
|
154
|
+
tools: result.tools,
|
|
155
|
+
sessionId: result.sessionId,
|
|
156
|
+
});
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
if (result.tools.length === 0) {
|
|
160
|
+
console.log('No tools available on this connector');
|
|
161
|
+
console.log(`Session: ${result.sessionId.slice(0, 8)}`);
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
// Table format
|
|
165
|
+
const maxName = Math.max(12, ...result.tools.map(t => t.name.length));
|
|
166
|
+
console.log();
|
|
167
|
+
console.log('Tool'.padEnd(maxName) + ' ' +
|
|
168
|
+
'Required'.padEnd(8) + ' ' +
|
|
169
|
+
'Description');
|
|
170
|
+
console.log('-'.repeat(maxName + 50));
|
|
171
|
+
for (const tool of result.tools) {
|
|
172
|
+
const schema = formatInputSchema(tool.inputSchema);
|
|
173
|
+
const requiredCount = schema.required.length;
|
|
174
|
+
const desc = tool.description
|
|
175
|
+
? truncate(tool.description.split('\n')[0], 40)
|
|
176
|
+
: '-';
|
|
177
|
+
console.log(tool.name.padEnd(maxName) + ' ' +
|
|
178
|
+
String(requiredCount).padEnd(8) + ' ' +
|
|
179
|
+
desc);
|
|
180
|
+
}
|
|
181
|
+
console.log();
|
|
182
|
+
console.log(`Found ${result.tools.length} tool(s)`);
|
|
183
|
+
console.log(`Session: ${result.sessionId.slice(0, 8)}`);
|
|
184
|
+
}
|
|
185
|
+
catch (error) {
|
|
186
|
+
console.error(`Error: ${error instanceof Error ? error.message : error}`);
|
|
187
|
+
process.exit(1);
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
// ─────────────────────────────────────────────────────────────────
|
|
191
|
+
// tool show <connector> <tool-name>
|
|
192
|
+
// ─────────────────────────────────────────────────────────────────
|
|
193
|
+
cmd
|
|
194
|
+
.command('show <connector> <tool-name>')
|
|
195
|
+
.description('Show tool details including input schema')
|
|
196
|
+
.option('--timeout <sec>', 'Timeout in seconds', '30')
|
|
197
|
+
.action(async (connectorId, toolName, options) => {
|
|
198
|
+
try {
|
|
199
|
+
const timeout = parseTimeout(options.timeout);
|
|
200
|
+
const { connector, configDir } = await validateConnector(getConfigPath, connectorId);
|
|
201
|
+
const ctx = {
|
|
202
|
+
connectorId,
|
|
203
|
+
configDir,
|
|
204
|
+
};
|
|
205
|
+
const result = await getTool(ctx, connector, toolName, {
|
|
206
|
+
timeout,
|
|
207
|
+
});
|
|
208
|
+
if (result.error) {
|
|
209
|
+
console.error(`Error: ${result.error}`);
|
|
210
|
+
if (result.sessionId) {
|
|
211
|
+
console.error(`Session: ${result.sessionId.slice(0, 8)}`);
|
|
212
|
+
}
|
|
213
|
+
process.exit(1);
|
|
214
|
+
}
|
|
215
|
+
if (!result.tool) {
|
|
216
|
+
console.error(`Tool not found: ${toolName}`);
|
|
217
|
+
process.exit(1);
|
|
218
|
+
}
|
|
219
|
+
if (getOutputOptions().json) {
|
|
220
|
+
output({
|
|
221
|
+
tool: result.tool,
|
|
222
|
+
sessionId: result.sessionId,
|
|
223
|
+
});
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
const tool = result.tool;
|
|
227
|
+
const schema = formatInputSchema(tool.inputSchema);
|
|
228
|
+
console.log();
|
|
229
|
+
console.log(`Tool: ${tool.name}`);
|
|
230
|
+
console.log();
|
|
231
|
+
if (tool.description) {
|
|
232
|
+
console.log('Description:');
|
|
233
|
+
for (const line of tool.description.split('\n')) {
|
|
234
|
+
console.log(' ' + line);
|
|
235
|
+
}
|
|
236
|
+
console.log();
|
|
237
|
+
}
|
|
238
|
+
if (schema.required.length > 0) {
|
|
239
|
+
console.log('Required arguments:');
|
|
240
|
+
for (const arg of schema.required) {
|
|
241
|
+
const typeStr = arg.type ? ` (${arg.type})` : '';
|
|
242
|
+
console.log(` ${arg.name}${typeStr}`);
|
|
243
|
+
if (arg.description) {
|
|
244
|
+
console.log(` ${arg.description}`);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
console.log();
|
|
248
|
+
}
|
|
249
|
+
if (schema.optional.length > 0) {
|
|
250
|
+
console.log('Optional arguments:');
|
|
251
|
+
for (const arg of schema.optional) {
|
|
252
|
+
const typeStr = arg.type ? ` (${arg.type})` : '';
|
|
253
|
+
const defaultStr = arg.default !== undefined ? ` [default: ${JSON.stringify(arg.default)}]` : '';
|
|
254
|
+
console.log(` ${arg.name}${typeStr}${defaultStr}`);
|
|
255
|
+
if (arg.description) {
|
|
256
|
+
console.log(` ${arg.description}`);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
console.log();
|
|
260
|
+
}
|
|
261
|
+
console.log(`Session: ${result.sessionId.slice(0, 8)}`);
|
|
262
|
+
console.log(`Run with: pfscan tool call ${connectorId} ${toolName} --args '{...}'`);
|
|
263
|
+
}
|
|
264
|
+
catch (error) {
|
|
265
|
+
console.error(`Error: ${error instanceof Error ? error.message : error}`);
|
|
266
|
+
process.exit(1);
|
|
267
|
+
}
|
|
268
|
+
});
|
|
269
|
+
// ─────────────────────────────────────────────────────────────────
|
|
270
|
+
// tool call <connector> <tool-name>
|
|
271
|
+
// ─────────────────────────────────────────────────────────────────
|
|
272
|
+
cmd
|
|
273
|
+
.command('call <connector> <tool-name>')
|
|
274
|
+
.description('Call an MCP tool')
|
|
275
|
+
.option('--args <json>', 'Arguments as JSON string')
|
|
276
|
+
.option('--args-file <path>', 'Read arguments from JSON file')
|
|
277
|
+
.option('--stdin', 'Read arguments from stdin (JSON)')
|
|
278
|
+
.option('--timeout <sec>', 'Timeout in seconds', '30')
|
|
279
|
+
.option('--dry-run', 'Show what would be sent without executing')
|
|
280
|
+
.action(async (connectorId, toolName, options) => {
|
|
281
|
+
try {
|
|
282
|
+
const timeout = parseTimeout(options.timeout);
|
|
283
|
+
// Resolve arguments first (before connector validation for dry-run)
|
|
284
|
+
const args = await resolveArgs({
|
|
285
|
+
args: options.args,
|
|
286
|
+
argsFile: options.argsFile,
|
|
287
|
+
stdin: options.stdin,
|
|
288
|
+
});
|
|
289
|
+
// Dry run - show what would be sent (no connector validation needed)
|
|
290
|
+
if (options.dryRun) {
|
|
291
|
+
if (getOutputOptions().json) {
|
|
292
|
+
output({
|
|
293
|
+
dryRun: true,
|
|
294
|
+
connector: connectorId,
|
|
295
|
+
tool: toolName,
|
|
296
|
+
arguments: args,
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
else {
|
|
300
|
+
console.log('Dry run - would send:');
|
|
301
|
+
console.log(JSON.stringify({
|
|
302
|
+
connector: connectorId,
|
|
303
|
+
tool: toolName,
|
|
304
|
+
arguments: args,
|
|
305
|
+
}, null, 2));
|
|
306
|
+
}
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
const { connector, configDir } = await validateConnector(getConfigPath, connectorId);
|
|
310
|
+
const ctx = {
|
|
311
|
+
connectorId,
|
|
312
|
+
configDir,
|
|
313
|
+
};
|
|
314
|
+
const result = await callTool(ctx, connector, toolName, args, {
|
|
315
|
+
timeout,
|
|
316
|
+
});
|
|
317
|
+
if (getOutputOptions().json) {
|
|
318
|
+
output({
|
|
319
|
+
success: result.success,
|
|
320
|
+
sessionId: result.sessionId,
|
|
321
|
+
content: result.content,
|
|
322
|
+
isError: result.isError,
|
|
323
|
+
error: result.error,
|
|
324
|
+
});
|
|
325
|
+
if (!result.success) {
|
|
326
|
+
process.exit(1);
|
|
327
|
+
}
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
// Human-readable output
|
|
331
|
+
if (!result.success) {
|
|
332
|
+
console.error(`Error: ${result.error}`);
|
|
333
|
+
if (result.sessionId) {
|
|
334
|
+
console.error(`Session: ${result.sessionId.slice(0, 8)} (recorded as failure)`);
|
|
335
|
+
}
|
|
336
|
+
process.exit(1);
|
|
337
|
+
}
|
|
338
|
+
console.log();
|
|
339
|
+
if (result.isError) {
|
|
340
|
+
console.log('Tool returned error:');
|
|
341
|
+
}
|
|
342
|
+
else {
|
|
343
|
+
console.log('Result:');
|
|
344
|
+
}
|
|
345
|
+
// Format content for display
|
|
346
|
+
if (result.content && Array.isArray(result.content)) {
|
|
347
|
+
for (const item of result.content) {
|
|
348
|
+
if (typeof item === 'object' && item !== null) {
|
|
349
|
+
const content = item;
|
|
350
|
+
if (content.type === 'text' && content.text) {
|
|
351
|
+
console.log(' ' + content.text);
|
|
352
|
+
}
|
|
353
|
+
else {
|
|
354
|
+
console.log(JSON.stringify(item, null, 2));
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
else {
|
|
358
|
+
console.log(' ' + String(item));
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
else if (result.content) {
|
|
363
|
+
console.log(JSON.stringify(result.content, null, 2));
|
|
364
|
+
}
|
|
365
|
+
console.log();
|
|
366
|
+
console.log(`Session: ${result.sessionId.slice(0, 8)}`);
|
|
367
|
+
console.log(`View details: pfscan rpc list --session ${result.sessionId.slice(0, 8)}`);
|
|
368
|
+
}
|
|
369
|
+
catch (error) {
|
|
370
|
+
console.error(`Error: ${error instanceof Error ? error.message : error}`);
|
|
371
|
+
process.exit(1);
|
|
372
|
+
}
|
|
373
|
+
});
|
|
374
|
+
return cmd;
|
|
375
|
+
}
|
|
376
|
+
//# sourceMappingURL=tool.js.map
|