@ibm/ibmi-mcp-server 0.3.1 → 0.4.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/README.md +29 -0
- package/dist/cli/commands/columns.d.ts +7 -0
- package/dist/cli/commands/columns.d.ts.map +1 -0
- package/dist/cli/commands/columns.js +29 -0
- package/dist/cli/commands/columns.js.map +1 -0
- package/dist/cli/commands/completion.d.ts +10 -0
- package/dist/cli/commands/completion.d.ts.map +1 -0
- package/dist/cli/commands/completion.js +225 -0
- package/dist/cli/commands/completion.js.map +1 -0
- package/dist/cli/commands/related.d.ts +7 -0
- package/dist/cli/commands/related.d.ts.map +1 -0
- package/dist/cli/commands/related.js +32 -0
- package/dist/cli/commands/related.js.map +1 -0
- package/dist/cli/commands/schemas.d.ts +7 -0
- package/dist/cli/commands/schemas.d.ts.map +1 -0
- package/dist/cli/commands/schemas.js +49 -0
- package/dist/cli/commands/schemas.js.map +1 -0
- package/dist/cli/commands/sql.d.ts +8 -0
- package/dist/cli/commands/sql.d.ts.map +1 -0
- package/dist/cli/commands/sql.js +106 -0
- package/dist/cli/commands/sql.js.map +1 -0
- package/dist/cli/commands/system.d.ts +11 -0
- package/dist/cli/commands/system.d.ts.map +1 -0
- package/dist/cli/commands/system.js +263 -0
- package/dist/cli/commands/system.js.map +1 -0
- package/dist/cli/commands/tables.d.ts +7 -0
- package/dist/cli/commands/tables.d.ts.map +1 -0
- package/dist/cli/commands/tables.js +48 -0
- package/dist/cli/commands/tables.js.map +1 -0
- package/dist/cli/commands/tool.d.ts +18 -0
- package/dist/cli/commands/tool.d.ts.map +1 -0
- package/dist/cli/commands/tool.js +194 -0
- package/dist/cli/commands/tool.js.map +1 -0
- package/dist/cli/commands/tools-list.d.ts +20 -0
- package/dist/cli/commands/tools-list.d.ts.map +1 -0
- package/dist/cli/commands/tools-list.js +209 -0
- package/dist/cli/commands/tools-list.js.map +1 -0
- package/dist/cli/commands/validate.d.ts +7 -0
- package/dist/cli/commands/validate.d.ts.map +1 -0
- package/dist/cli/commands/validate.js +77 -0
- package/dist/cli/commands/validate.js.map +1 -0
- package/dist/cli/config/credentials.d.ts +21 -0
- package/dist/cli/config/credentials.d.ts.map +1 -0
- package/dist/cli/config/credentials.js +96 -0
- package/dist/cli/config/credentials.js.map +1 -0
- package/dist/cli/config/index.d.ts +10 -0
- package/dist/cli/config/index.d.ts.map +1 -0
- package/dist/cli/config/index.js +9 -0
- package/dist/cli/config/index.js.map +1 -0
- package/dist/cli/config/loader.d.ts +36 -0
- package/dist/cli/config/loader.d.ts.map +1 -0
- package/dist/cli/config/loader.js +206 -0
- package/dist/cli/config/loader.js.map +1 -0
- package/dist/cli/config/resolver.d.ts +26 -0
- package/dist/cli/config/resolver.d.ts.map +1 -0
- package/dist/cli/config/resolver.js +102 -0
- package/dist/cli/config/resolver.js.map +1 -0
- package/dist/cli/config/schema.d.ts +128 -0
- package/dist/cli/config/schema.d.ts.map +1 -0
- package/dist/cli/config/schema.js +37 -0
- package/dist/cli/config/schema.js.map +1 -0
- package/dist/cli/config/types.d.ts +59 -0
- package/dist/cli/config/types.d.ts.map +1 -0
- package/dist/cli/config/types.js +6 -0
- package/dist/cli/config/types.js.map +1 -0
- package/dist/cli/formatters/output.d.ts +60 -0
- package/dist/cli/formatters/output.d.ts.map +1 -0
- package/dist/cli/formatters/output.js +190 -0
- package/dist/cli/formatters/output.js.map +1 -0
- package/dist/cli/index.d.ts +13 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +98 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/utils/command-helpers.d.ts +47 -0
- package/dist/cli/utils/command-helpers.d.ts.map +1 -0
- package/dist/cli/utils/command-helpers.js +211 -0
- package/dist/cli/utils/command-helpers.js.map +1 -0
- package/dist/cli/utils/connection.d.ts +20 -0
- package/dist/cli/utils/connection.d.ts.map +1 -0
- package/dist/cli/utils/connection.js +37 -0
- package/dist/cli/utils/connection.js.map +1 -0
- package/dist/cli/utils/exit-codes.d.ts +48 -0
- package/dist/cli/utils/exit-codes.d.ts.map +1 -0
- package/dist/cli/utils/exit-codes.js +111 -0
- package/dist/cli/utils/exit-codes.js.map +1 -0
- package/dist/cli/utils/yaml-loader.d.ts +69 -0
- package/dist/cli/utils/yaml-loader.d.ts.map +1 -0
- package/dist/cli/utils/yaml-loader.js +135 -0
- package/dist/cli/utils/yaml-loader.js.map +1 -0
- package/dist/cli/utils/yaml-to-commander.d.ts +26 -0
- package/dist/cli/utils/yaml-to-commander.d.ts.map +1 -0
- package/dist/cli/utils/yaml-to-commander.js +156 -0
- package/dist/cli/utils/yaml-to-commander.js.map +1 -0
- package/dist/config/index.d.ts +6 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +28 -10
- package/dist/config/index.js.map +1 -1
- package/dist/ibmi-mcp-server/services/authenticatedPoolManager.d.ts +1 -1
- package/dist/ibmi-mcp-server/services/authenticatedPoolManager.d.ts.map +1 -1
- package/dist/ibmi-mcp-server/services/authenticatedPoolManager.js +8 -7
- package/dist/ibmi-mcp-server/services/authenticatedPoolManager.js.map +1 -1
- package/dist/ibmi-mcp-server/services/baseConnectionPool.d.ts +52 -9
- package/dist/ibmi-mcp-server/services/baseConnectionPool.d.ts.map +1 -1
- package/dist/ibmi-mcp-server/services/baseConnectionPool.js +177 -17
- package/dist/ibmi-mcp-server/services/baseConnectionPool.js.map +1 -1
- package/dist/ibmi-mcp-server/services/sourceManager.d.ts +12 -4
- package/dist/ibmi-mcp-server/services/sourceManager.d.ts.map +1 -1
- package/dist/ibmi-mcp-server/services/sourceManager.js +16 -5
- package/dist/ibmi-mcp-server/services/sourceManager.js.map +1 -1
- package/dist/ibmi-mcp-server/tools/executeSql.tool.d.ts.map +1 -1
- package/dist/ibmi-mcp-server/tools/executeSql.tool.js +6 -2
- package/dist/ibmi-mcp-server/tools/executeSql.tool.js.map +1 -1
- package/dist/ibmi-mcp-server/tools/generateSql.tool.js +1 -1
- package/dist/ibmi-mcp-server/tools/generateSql.tool.js.map +1 -1
- package/dist/ibmi-mcp-server/tools/getRelatedObjects.tool.d.ts +93 -0
- package/dist/ibmi-mcp-server/tools/getRelatedObjects.tool.d.ts.map +1 -0
- package/dist/ibmi-mcp-server/tools/getRelatedObjects.tool.js +198 -0
- package/dist/ibmi-mcp-server/tools/getRelatedObjects.tool.js.map +1 -0
- package/dist/ibmi-mcp-server/tools/getTableColumns.tool.d.ts +87 -0
- package/dist/ibmi-mcp-server/tools/getTableColumns.tool.d.ts.map +1 -0
- package/dist/ibmi-mcp-server/tools/getTableColumns.tool.js +163 -0
- package/dist/ibmi-mcp-server/tools/getTableColumns.tool.js.map +1 -0
- package/dist/ibmi-mcp-server/tools/index.d.ts +175 -0
- package/dist/ibmi-mcp-server/tools/index.d.ts.map +1 -1
- package/dist/ibmi-mcp-server/tools/index.js +27 -1
- package/dist/ibmi-mcp-server/tools/index.js.map +1 -1
- package/dist/ibmi-mcp-server/tools/listSchemas.tool.d.ts +107 -0
- package/dist/ibmi-mcp-server/tools/listSchemas.tool.d.ts.map +1 -0
- package/dist/ibmi-mcp-server/tools/listSchemas.tool.js +195 -0
- package/dist/ibmi-mcp-server/tools/listSchemas.tool.js.map +1 -0
- package/dist/ibmi-mcp-server/tools/listTablesInSchema.tool.d.ts +107 -0
- package/dist/ibmi-mcp-server/tools/listTablesInSchema.tool.d.ts.map +1 -0
- package/dist/ibmi-mcp-server/tools/listTablesInSchema.tool.js +198 -0
- package/dist/ibmi-mcp-server/tools/listTablesInSchema.tool.js.map +1 -0
- package/dist/ibmi-mcp-server/tools/validateQuery.tool.d.ts +229 -0
- package/dist/ibmi-mcp-server/tools/validateQuery.tool.d.ts.map +1 -0
- package/dist/ibmi-mcp-server/tools/validateQuery.tool.js +401 -0
- package/dist/ibmi-mcp-server/tools/validateQuery.tool.js.map +1 -0
- package/dist/ibmi-mcp-server/utils/config/toolProcessor.d.ts.map +1 -1
- package/dist/ibmi-mcp-server/utils/config/toolProcessor.js +1 -1
- package/dist/ibmi-mcp-server/utils/config/toolProcessor.js.map +1 -1
- package/dist/ibmi-mcp-server/utils/security/sqlSecurityValidator.js +1 -1
- package/dist/ibmi-mcp-server/utils/security/sqlSecurityValidator.js.map +1 -1
- package/dist/index.js +30 -19
- package/dist/index.js.map +1 -1
- package/dist/mcp-server/transports/http/httpTransport.d.ts.map +1 -1
- package/dist/mcp-server/transports/http/httpTransport.js +5 -1
- package/dist/mcp-server/transports/http/httpTransport.js.map +1 -1
- package/package.json +6 -4
package/README.md
CHANGED
|
@@ -1380,6 +1380,35 @@ MCP_RATE_LIMIT_ENABLED=false
|
|
|
1380
1380
|
|
|
1381
1381
|
</details>
|
|
1382
1382
|
|
|
1383
|
+
<details>
|
|
1384
|
+
<summary><strong>🔄 Connection Pool Timeouts</strong></summary>
|
|
1385
|
+
|
|
1386
|
+
Controls automatic cleanup of idle Mapepire connection pools and query execution timeouts. Essential for cloud deployments (Railway, Heroku, etc.) where reverse proxies silently kill idle TCP connections, causing queries on stale WebSocket connections to hang indefinitely.
|
|
1387
|
+
|
|
1388
|
+
| Variable | Description | Default | Required |
|
|
1389
|
+
|----------|-------------|---------|----------|
|
|
1390
|
+
| `MCP_POOL_IDLE_TIMEOUT_MS` | Idle timeout for connection pools (ms). Pools closed after inactivity. Fresh connections established automatically on next request. Set to `0` to disable. | `300000` (5 min) | No |
|
|
1391
|
+
| `MCP_POOL_QUERY_TIMEOUT_MS` | Query execution timeout (ms). Queries aborted after this period. Pool re-initialized on next request after timeout. Set to `0` to disable. | `30000` (30s) | No |
|
|
1392
|
+
|
|
1393
|
+
**Examples:**
|
|
1394
|
+
```bash
|
|
1395
|
+
# Default: 5-minute idle timeout, 30-second query timeout
|
|
1396
|
+
MCP_POOL_IDLE_TIMEOUT_MS=300000
|
|
1397
|
+
MCP_POOL_QUERY_TIMEOUT_MS=30000
|
|
1398
|
+
|
|
1399
|
+
# Cloud deployment: shorter idle timeout for aggressive proxies
|
|
1400
|
+
MCP_POOL_IDLE_TIMEOUT_MS=60000
|
|
1401
|
+
MCP_POOL_QUERY_TIMEOUT_MS=30000
|
|
1402
|
+
|
|
1403
|
+
# Disable both timeouts (stable network environments only)
|
|
1404
|
+
MCP_POOL_IDLE_TIMEOUT_MS=0
|
|
1405
|
+
MCP_POOL_QUERY_TIMEOUT_MS=0
|
|
1406
|
+
```
|
|
1407
|
+
|
|
1408
|
+
> **How it works:** The idle timer checks pools at an interval of `max(10s, timeout/2)`. When a pool exceeds the idle timeout, it is closed — the next query triggers transparent re-initialization via the existing lazy-init path. The query timeout wraps `pool.execute()` with `Promise.race()`, so dead connections fail fast instead of hanging. On timeout, the pool is marked unhealthy and closed for re-initialization.
|
|
1409
|
+
|
|
1410
|
+
</details>
|
|
1411
|
+
|
|
1383
1412
|
<details>
|
|
1384
1413
|
<summary><strong>🔐 Authentication & Authorization</strong></summary>
|
|
1385
1414
|
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview `ibmi columns <schema> <table>` command — get column metadata.
|
|
3
|
+
* @module cli/commands/columns
|
|
4
|
+
*/
|
|
5
|
+
import { Command } from "commander";
|
|
6
|
+
export declare function registerColumnsCommand(program: Command): void;
|
|
7
|
+
//# sourceMappingURL=columns.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"columns.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/columns.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA+B7D"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview `ibmi columns <schema> <table>` command — get column metadata.
|
|
3
|
+
* @module cli/commands/columns
|
|
4
|
+
*/
|
|
5
|
+
import { withConnection } from "../utils/command-helpers.js";
|
|
6
|
+
export function registerColumnsCommand(program) {
|
|
7
|
+
program
|
|
8
|
+
.command("columns <schema> <table>")
|
|
9
|
+
.description("Get column metadata for a table")
|
|
10
|
+
.action(async (schema, table, _opts, cmd) => {
|
|
11
|
+
await withConnection(cmd, "get_table_columns", async (_resolved, ctx) => {
|
|
12
|
+
const { getTableColumnsLogic } = await import("../../ibmi-mcp-server/tools/getTableColumns.tool.js");
|
|
13
|
+
const result = await getTableColumnsLogic({
|
|
14
|
+
schema_name: schema,
|
|
15
|
+
table_name: table,
|
|
16
|
+
}, ctx, {});
|
|
17
|
+
if (!result.success) {
|
|
18
|
+
throw new Error(result.error?.message ?? "Failed to get table columns");
|
|
19
|
+
}
|
|
20
|
+
return {
|
|
21
|
+
data: (result.data ?? []),
|
|
22
|
+
meta: {
|
|
23
|
+
rowCount: result.rowCount ?? 0,
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=columns.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"columns.js","sourceRoot":"","sources":["../../../src/cli/commands/columns.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAG7D,MAAM,UAAU,sBAAsB,CAAC,OAAgB;IACrD,OAAO;SACJ,OAAO,CAAC,0BAA0B,CAAC;SACnC,WAAW,CAAC,iCAAiC,CAAC;SAC9C,MAAM,CAAC,KAAK,EAAE,MAAc,EAAE,KAAa,EAAE,KAAK,EAAE,GAAY,EAAE,EAAE;QACnE,MAAM,cAAc,CAAC,GAAG,EAAE,mBAAmB,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,EAAE;YACtE,MAAM,EAAE,oBAAoB,EAAE,GAAG,MAAM,MAAM,CAC3C,qDAAqD,CACtD,CAAC;YAEF,MAAM,MAAM,GAAG,MAAM,oBAAoB,CACvC;gBACE,WAAW,EAAE,MAAM;gBACnB,UAAU,EAAE,KAAK;aAClB,EACD,GAAG,EACH,EAAgB,CACjB,CAAC;YAEF,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpB,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,IAAI,6BAA6B,CAAC,CAAC;YAC1E,CAAC;YAED,OAAO;gBACL,IAAI,EAAE,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAA8B;gBACtD,IAAI,EAAE;oBACJ,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,CAAC;iBAC/B;aACF,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview `ibmi completion bash|zsh|fish` — generate shell completion scripts.
|
|
3
|
+
* @module cli/commands/completion
|
|
4
|
+
*/
|
|
5
|
+
import { Command } from "commander";
|
|
6
|
+
/**
|
|
7
|
+
* Register `ibmi completion bash|zsh|fish`.
|
|
8
|
+
*/
|
|
9
|
+
export declare function registerCompletionCommand(program: Command): void;
|
|
10
|
+
//# sourceMappingURL=completion.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"completion.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/completion.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkNpC;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAwBhE"}
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview `ibmi completion bash|zsh|fish` — generate shell completion scripts.
|
|
3
|
+
* @module cli/commands/completion
|
|
4
|
+
*/
|
|
5
|
+
import { ExitCode } from "../utils/exit-codes.js";
|
|
6
|
+
/** Top-level commands. */
|
|
7
|
+
const COMMANDS = [
|
|
8
|
+
"system",
|
|
9
|
+
"schemas",
|
|
10
|
+
"tables",
|
|
11
|
+
"columns",
|
|
12
|
+
"related",
|
|
13
|
+
"validate",
|
|
14
|
+
"sql",
|
|
15
|
+
"tool",
|
|
16
|
+
"tools",
|
|
17
|
+
"toolsets",
|
|
18
|
+
"completion",
|
|
19
|
+
];
|
|
20
|
+
/** System subcommands. */
|
|
21
|
+
const SYSTEM_SUBCOMMANDS = [
|
|
22
|
+
"list",
|
|
23
|
+
"show",
|
|
24
|
+
"add",
|
|
25
|
+
"remove",
|
|
26
|
+
"default",
|
|
27
|
+
"test",
|
|
28
|
+
"config-path",
|
|
29
|
+
];
|
|
30
|
+
/** Global options. */
|
|
31
|
+
const GLOBAL_OPTIONS = [
|
|
32
|
+
"--system",
|
|
33
|
+
"--format",
|
|
34
|
+
"--raw",
|
|
35
|
+
"--stream",
|
|
36
|
+
"--tools",
|
|
37
|
+
"--output",
|
|
38
|
+
"--watch",
|
|
39
|
+
"--no-color",
|
|
40
|
+
"--version",
|
|
41
|
+
"--help",
|
|
42
|
+
];
|
|
43
|
+
/** Format choices. */
|
|
44
|
+
const FORMAT_CHOICES = ["table", "json", "csv", "markdown"];
|
|
45
|
+
/**
|
|
46
|
+
* Generate a bash completion script.
|
|
47
|
+
*/
|
|
48
|
+
function generateBash() {
|
|
49
|
+
return `# bash completion for ibmi
|
|
50
|
+
# Add to ~/.bashrc: eval "$(ibmi completion bash)"
|
|
51
|
+
|
|
52
|
+
_ibmi_completions() {
|
|
53
|
+
local cur prev commands system_commands global_opts format_choices
|
|
54
|
+
COMPREPLY=()
|
|
55
|
+
cur="\${COMP_WORDS[COMP_CWORD]}"
|
|
56
|
+
prev="\${COMP_WORDS[COMP_CWORD-1]}"
|
|
57
|
+
|
|
58
|
+
commands="${COMMANDS.join(" ")}"
|
|
59
|
+
system_commands="${SYSTEM_SUBCOMMANDS.join(" ")}"
|
|
60
|
+
global_opts="${GLOBAL_OPTIONS.join(" ")}"
|
|
61
|
+
format_choices="${FORMAT_CHOICES.join(" ")}"
|
|
62
|
+
|
|
63
|
+
# Complete --format values
|
|
64
|
+
if [[ "\${prev}" == "--format" ]]; then
|
|
65
|
+
COMPREPLY=( $(compgen -W "\${format_choices}" -- "\${cur}") )
|
|
66
|
+
return 0
|
|
67
|
+
fi
|
|
68
|
+
|
|
69
|
+
# Complete --system from config
|
|
70
|
+
if [[ "\${prev}" == "--system" ]]; then
|
|
71
|
+
local systems
|
|
72
|
+
if command -v yq &>/dev/null && [[ -f ~/.ibmi/config.yaml ]]; then
|
|
73
|
+
systems=$(yq -r '.systems | keys | .[]' ~/.ibmi/config.yaml 2>/dev/null)
|
|
74
|
+
elif command -v python3 &>/dev/null && [[ -f ~/.ibmi/config.yaml ]]; then
|
|
75
|
+
systems=$(python3 -c "import yaml; c=yaml.safe_load(open('$HOME/.ibmi/config.yaml')); print(' '.join(c.get('systems',{}).keys()))" 2>/dev/null)
|
|
76
|
+
fi
|
|
77
|
+
COMPREPLY=( $(compgen -W "\${systems}" -- "\${cur}") )
|
|
78
|
+
return 0
|
|
79
|
+
fi
|
|
80
|
+
|
|
81
|
+
# Complete file paths for --file, --tools, --output
|
|
82
|
+
if [[ "\${prev}" == "--file" || "\${prev}" == "--tools" || "\${prev}" == "--output" ]]; then
|
|
83
|
+
COMPREPLY=( $(compgen -f -- "\${cur}") )
|
|
84
|
+
return 0
|
|
85
|
+
fi
|
|
86
|
+
|
|
87
|
+
# Complete system subcommands
|
|
88
|
+
if [[ "\${COMP_WORDS[1]}" == "system" && \${COMP_CWORD} -eq 2 ]]; then
|
|
89
|
+
COMPREPLY=( $(compgen -W "\${system_commands}" -- "\${cur}") )
|
|
90
|
+
return 0
|
|
91
|
+
fi
|
|
92
|
+
|
|
93
|
+
# Complete top-level commands
|
|
94
|
+
if [[ \${COMP_CWORD} -eq 1 ]]; then
|
|
95
|
+
COMPREPLY=( $(compgen -W "\${commands}" -- "\${cur}") )
|
|
96
|
+
return 0
|
|
97
|
+
fi
|
|
98
|
+
|
|
99
|
+
# Complete global options
|
|
100
|
+
if [[ "\${cur}" == -* ]]; then
|
|
101
|
+
COMPREPLY=( $(compgen -W "\${global_opts}" -- "\${cur}") )
|
|
102
|
+
return 0
|
|
103
|
+
fi
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
complete -F _ibmi_completions ibmi
|
|
107
|
+
`;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Generate a zsh completion script.
|
|
111
|
+
*/
|
|
112
|
+
function generateZsh() {
|
|
113
|
+
return `#compdef ibmi
|
|
114
|
+
# zsh completion for ibmi
|
|
115
|
+
# Add to ~/.zshrc: eval "$(ibmi completion zsh)"
|
|
116
|
+
|
|
117
|
+
_ibmi() {
|
|
118
|
+
local -a commands system_commands format_choices global_opts
|
|
119
|
+
|
|
120
|
+
commands=(
|
|
121
|
+
${COMMANDS.map((c) => ` '${c}:${c} command'`).join("\n")}
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
system_commands=(
|
|
125
|
+
${SYSTEM_SUBCOMMANDS.map((c) => ` '${c}:${c}'`).join("\n")}
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
format_choices=(table json csv markdown)
|
|
129
|
+
|
|
130
|
+
global_opts=(
|
|
131
|
+
'--system[Target system name]:system name:'
|
|
132
|
+
'--format[Output format]:format:(table json csv markdown)'
|
|
133
|
+
'--raw[Output as JSON]'
|
|
134
|
+
'--stream[Stream results as NDJSON]'
|
|
135
|
+
'--tools[Path to YAML tool files]:file:_files'
|
|
136
|
+
'--output[Write output to file]:file:_files'
|
|
137
|
+
'--watch[Re-run at interval]:seconds:'
|
|
138
|
+
'--no-color[Disable colored output]'
|
|
139
|
+
'--help[Show help]'
|
|
140
|
+
'--version[Show version]'
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
_arguments -C \\
|
|
144
|
+
$global_opts \\
|
|
145
|
+
'1:command:->command' \\
|
|
146
|
+
'*::arg:->args'
|
|
147
|
+
|
|
148
|
+
case $state in
|
|
149
|
+
command)
|
|
150
|
+
_describe -t commands 'ibmi commands' commands
|
|
151
|
+
;;
|
|
152
|
+
args)
|
|
153
|
+
case $words[1] in
|
|
154
|
+
system)
|
|
155
|
+
_describe -t system_commands 'system subcommands' system_commands
|
|
156
|
+
;;
|
|
157
|
+
esac
|
|
158
|
+
;;
|
|
159
|
+
esac
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
_ibmi "$@"
|
|
163
|
+
`;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Generate a fish completion script.
|
|
167
|
+
*/
|
|
168
|
+
function generateFish() {
|
|
169
|
+
const lines = [
|
|
170
|
+
"# fish completion for ibmi",
|
|
171
|
+
"# Add to fish config: ibmi completion fish | source",
|
|
172
|
+
"",
|
|
173
|
+
"# Disable file completions by default",
|
|
174
|
+
"complete -c ibmi -f",
|
|
175
|
+
"",
|
|
176
|
+
"# Top-level commands",
|
|
177
|
+
];
|
|
178
|
+
for (const cmd of COMMANDS) {
|
|
179
|
+
lines.push(`complete -c ibmi -n '__fish_use_subcommand' -a '${cmd}' -d '${cmd} command'`);
|
|
180
|
+
}
|
|
181
|
+
lines.push("", "# System subcommands");
|
|
182
|
+
for (const sub of SYSTEM_SUBCOMMANDS) {
|
|
183
|
+
lines.push(`complete -c ibmi -n '__fish_seen_subcommand_from system' -a '${sub}' -d '${sub}'`);
|
|
184
|
+
}
|
|
185
|
+
lines.push("", "# Global options");
|
|
186
|
+
lines.push("complete -c ibmi -l system -d 'Target system name' -x", "complete -c ibmi -l format -d 'Output format' -x -a 'table json csv markdown'", "complete -c ibmi -l raw -d 'Output as JSON'", "complete -c ibmi -l stream -d 'Stream results as NDJSON'", "complete -c ibmi -l tools -d 'Path to YAML tool files' -r -F", "complete -c ibmi -l output -d 'Write output to file' -r -F", "complete -c ibmi -l watch -d 'Re-run at interval (seconds)' -x", "complete -c ibmi -l no-color -d 'Disable colored output'");
|
|
187
|
+
return lines.join("\n") + "\n";
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Register `ibmi completion bash|zsh|fish`.
|
|
191
|
+
*/
|
|
192
|
+
export function registerCompletionCommand(program) {
|
|
193
|
+
program
|
|
194
|
+
.command("completion [shell]")
|
|
195
|
+
.description("Generate shell completion script (bash, zsh, fish)")
|
|
196
|
+
.action((shell) => {
|
|
197
|
+
const target = shell?.toLowerCase() ?? detectShell();
|
|
198
|
+
switch (target) {
|
|
199
|
+
case "bash":
|
|
200
|
+
process.stdout.write(generateBash());
|
|
201
|
+
break;
|
|
202
|
+
case "zsh":
|
|
203
|
+
process.stdout.write(generateZsh());
|
|
204
|
+
break;
|
|
205
|
+
case "fish":
|
|
206
|
+
process.stdout.write(generateFish());
|
|
207
|
+
break;
|
|
208
|
+
default:
|
|
209
|
+
process.stderr.write(`Unknown shell: ${target}. Supported: bash, zsh, fish\n`);
|
|
210
|
+
process.exitCode = ExitCode.USAGE;
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Auto-detect the current shell from the SHELL environment variable.
|
|
216
|
+
*/
|
|
217
|
+
function detectShell() {
|
|
218
|
+
const shell = process.env.SHELL ?? "";
|
|
219
|
+
if (shell.includes("zsh"))
|
|
220
|
+
return "zsh";
|
|
221
|
+
if (shell.includes("fish"))
|
|
222
|
+
return "fish";
|
|
223
|
+
return "bash";
|
|
224
|
+
}
|
|
225
|
+
//# sourceMappingURL=completion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"completion.js","sourceRoot":"","sources":["../../../src/cli/commands/completion.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview `ibmi related <library> <object>` command — find dependent objects.
|
|
3
|
+
* @module cli/commands/related
|
|
4
|
+
*/
|
|
5
|
+
import { Command } from "commander";
|
|
6
|
+
export declare function registerRelatedCommand(program: Command): void;
|
|
7
|
+
//# sourceMappingURL=related.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"related.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/related.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAqC7D"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview `ibmi related <library> <object>` command — find dependent objects.
|
|
3
|
+
* @module cli/commands/related
|
|
4
|
+
*/
|
|
5
|
+
import { withConnection } from "../utils/command-helpers.js";
|
|
6
|
+
export function registerRelatedCommand(program) {
|
|
7
|
+
program
|
|
8
|
+
.command("related <library> <object>")
|
|
9
|
+
.description("Find objects that depend on a database file")
|
|
10
|
+
.option("--type <type>", "Filter by object type (e.g. INDEX, VIEW, TRIGGER, FOREIGN KEY)")
|
|
11
|
+
.action(async (library, object, opts, cmd) => {
|
|
12
|
+
await withConnection(cmd, "get_related_objects", async (_resolved, ctx) => {
|
|
13
|
+
const { getRelatedObjectsLogic } = await import("../../ibmi-mcp-server/tools/getRelatedObjects.tool.js");
|
|
14
|
+
const result = await getRelatedObjectsLogic({
|
|
15
|
+
library_name: library,
|
|
16
|
+
file_name: object,
|
|
17
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
18
|
+
object_type_filter: opts["type"],
|
|
19
|
+
}, ctx, {});
|
|
20
|
+
if (!result.success) {
|
|
21
|
+
throw new Error(result.error?.message ?? "Failed to get related objects");
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
data: (result.data ?? []),
|
|
25
|
+
meta: {
|
|
26
|
+
rowCount: result.rowCount ?? 0,
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=related.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"related.js","sourceRoot":"","sources":["../../../src/cli/commands/related.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAG7D,MAAM,UAAU,sBAAsB,CAAC,OAAgB;IACrD,OAAO;SACJ,OAAO,CAAC,4BAA4B,CAAC;SACrC,WAAW,CAAC,6CAA6C,CAAC;SAC1D,MAAM,CACL,eAAe,EACf,gEAAgE,CACjE;SACA,MAAM,CAAC,KAAK,EAAE,OAAe,EAAE,MAAc,EAAE,IAAI,EAAE,GAAY,EAAE,EAAE;QACpE,MAAM,cAAc,CAAC,GAAG,EAAE,qBAAqB,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,EAAE;YACxE,MAAM,EAAE,sBAAsB,EAAE,GAAG,MAAM,MAAM,CAC7C,uDAAuD,CACxD,CAAC;YAEF,MAAM,MAAM,GAAG,MAAM,sBAAsB,CACzC;gBACE,YAAY,EAAE,OAAO;gBACrB,SAAS,EAAE,MAAM;gBACjB,8DAA8D;gBAC9D,kBAAkB,EAAE,IAAI,CAAC,MAAM,CAAQ;aACxC,EACD,GAAG,EACH,EAAgB,CACjB,CAAC;YAEF,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpB,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,IAAI,+BAA+B,CAAC,CAAC;YAC5E,CAAC;YAED,OAAO;gBACL,IAAI,EAAE,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAA8B;gBACtD,IAAI,EAAE;oBACJ,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,CAAC;iBAC/B;aACF,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview `ibmi schemas` command — list available schemas/libraries.
|
|
3
|
+
* @module cli/commands/schemas
|
|
4
|
+
*/
|
|
5
|
+
import { Command } from "commander";
|
|
6
|
+
export declare function registerSchemasCommand(program: Command): void;
|
|
7
|
+
//# sourceMappingURL=schemas.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/schemas.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAmD7D"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview `ibmi schemas` command — list available schemas/libraries.
|
|
3
|
+
* @module cli/commands/schemas
|
|
4
|
+
*/
|
|
5
|
+
import { withConnection } from "../utils/command-helpers.js";
|
|
6
|
+
import { ExitCode } from "../utils/exit-codes.js";
|
|
7
|
+
export function registerSchemasCommand(program) {
|
|
8
|
+
program
|
|
9
|
+
.command("schemas")
|
|
10
|
+
.description("List schemas/libraries on the target system")
|
|
11
|
+
.option("--filter <pattern>", "Filter by schema name (SQL LIKE pattern, e.g. 'MY%')")
|
|
12
|
+
.option("--system-schemas", "Include system schemas (Q* and SYS*)", false)
|
|
13
|
+
.option("--limit <n>", "Maximum rows to return", "50")
|
|
14
|
+
.option("--offset <n>", "Rows to skip for pagination", "0")
|
|
15
|
+
.action(async (opts, cmd) => {
|
|
16
|
+
const limit = parseInt(opts["limit"], 10);
|
|
17
|
+
const offset = parseInt(opts["offset"], 10);
|
|
18
|
+
if (isNaN(limit) || limit < 0) {
|
|
19
|
+
process.stderr.write(`Error: Invalid --limit value: "${opts["limit"]}". Must be a positive integer.\n`);
|
|
20
|
+
process.exitCode = ExitCode.USAGE;
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
if (isNaN(offset) || offset < 0) {
|
|
24
|
+
process.stderr.write(`Error: Invalid --offset value: "${opts["offset"]}". Must be a non-negative integer.\n`);
|
|
25
|
+
process.exitCode = ExitCode.USAGE;
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
await withConnection(cmd, "list_schemas", async (_resolved, ctx) => {
|
|
29
|
+
const { listSchemasLogic } = await import("../../ibmi-mcp-server/tools/listSchemas.tool.js");
|
|
30
|
+
const result = await listSchemasLogic({
|
|
31
|
+
filter: opts["filter"],
|
|
32
|
+
include_system: opts["systemSchemas"],
|
|
33
|
+
limit,
|
|
34
|
+
offset,
|
|
35
|
+
}, ctx, {});
|
|
36
|
+
if (!result.success) {
|
|
37
|
+
throw new Error(result.error?.message ?? "Failed to list schemas");
|
|
38
|
+
}
|
|
39
|
+
return {
|
|
40
|
+
data: (result.data ?? []),
|
|
41
|
+
meta: {
|
|
42
|
+
rowCount: result.rowCount ?? 0,
|
|
43
|
+
hasMore: result.hasMore,
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=schemas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../../src/cli/commands/schemas.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAGlD,MAAM,UAAU,sBAAsB,CAAC,OAAgB;IACrD,OAAO;SACJ,OAAO,CAAC,SAAS,CAAC;SAClB,WAAW,CAAC,6CAA6C,CAAC;SAC1D,MAAM,CAAC,oBAAoB,EAAE,sDAAsD,CAAC;SACpF,MAAM,CAAC,kBAAkB,EAAE,sCAAsC,EAAE,KAAK,CAAC;SACzE,MAAM,CAAC,aAAa,EAAE,wBAAwB,EAAE,IAAI,CAAC;SACrD,MAAM,CAAC,cAAc,EAAE,6BAA6B,EAAE,GAAG,CAAC;SAC1D,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,GAAY,EAAE,EAAE;QACnC,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAW,EAAE,EAAE,CAAC,CAAC;QACpD,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAW,EAAE,EAAE,CAAC,CAAC;QACtD,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YAC9B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,kCAAkC,IAAI,CAAC,OAAO,CAAC,kCAAkC,CAAC,CAAC;YACxG,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC;YAClC,OAAO;QACT,CAAC;QACD,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;YAChC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,mCAAmC,IAAI,CAAC,QAAQ,CAAC,sCAAsC,CAAC,CAAC;YAC9G,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC;YAClC,OAAO;QACT,CAAC;QAED,MAAM,cAAc,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,EAAE;YACjE,MAAM,EAAE,gBAAgB,EAAE,GAAG,MAAM,MAAM,CACvC,iDAAiD,CAClD,CAAC;YAEF,MAAM,MAAM,GAAG,MAAM,gBAAgB,CACnC;gBACE,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAuB;gBAC5C,cAAc,EAAE,IAAI,CAAC,eAAe,CAAY;gBAChD,KAAK;gBACL,MAAM;aACP,EACD,GAAG,EACH,EAAgB,CACjB,CAAC;YAEF,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpB,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,IAAI,wBAAwB,CAAC,CAAC;YACrE,CAAC;YAED,OAAO;gBACL,IAAI,EAAE,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAA8B;gBACtD,IAAI,EAAE;oBACJ,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,CAAC;oBAC9B,OAAO,EAAE,MAAM,CAAC,OAAO;iBACxB;aACF,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview `ibmi sql "<sql>"` command — execute SQL queries.
|
|
3
|
+
* Supports inline SQL, --file, and stdin piping.
|
|
4
|
+
* @module cli/commands/sql
|
|
5
|
+
*/
|
|
6
|
+
import { Command } from "commander";
|
|
7
|
+
export declare function registerSqlCommand(program: Command): void;
|
|
8
|
+
//# sourceMappingURL=sql.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sql.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/sql.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAoBpC,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAgHzD"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview `ibmi sql "<sql>"` command — execute SQL queries.
|
|
3
|
+
* Supports inline SQL, --file, and stdin piping.
|
|
4
|
+
* @module cli/commands/sql
|
|
5
|
+
*/
|
|
6
|
+
import { readFileSync } from "fs";
|
|
7
|
+
import { withConnection, getFormat } from "../utils/command-helpers.js";
|
|
8
|
+
import { renderMessage } from "../formatters/output.js";
|
|
9
|
+
import { ExitCode } from "../utils/exit-codes.js";
|
|
10
|
+
/**
|
|
11
|
+
* Read SQL from stdin (piped input).
|
|
12
|
+
* Returns null if stdin is a TTY (interactive).
|
|
13
|
+
*/
|
|
14
|
+
function readStdin() {
|
|
15
|
+
if (process.stdin.isTTY)
|
|
16
|
+
return null;
|
|
17
|
+
try {
|
|
18
|
+
return readFileSync(0, "utf-8").trim();
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export function registerSqlCommand(program) {
|
|
25
|
+
program
|
|
26
|
+
.command("sql [statement]")
|
|
27
|
+
.description("Execute a SQL query against the target system")
|
|
28
|
+
.option("--file <path>", "Read SQL from a file")
|
|
29
|
+
.option("--limit <n>", "Maximum rows to return")
|
|
30
|
+
.option("--read-only", "Enforce read-only mode (default: true)", true)
|
|
31
|
+
.option("--no-read-only", "Allow mutation queries")
|
|
32
|
+
.option("--dry-run", "Print SQL without executing", false)
|
|
33
|
+
.action(async (statement, opts, cmd) => {
|
|
34
|
+
// Resolve SQL source: argument > --file > stdin
|
|
35
|
+
let sql = statement;
|
|
36
|
+
if (!sql && opts["file"]) {
|
|
37
|
+
try {
|
|
38
|
+
sql = readFileSync(opts["file"], "utf-8").trim();
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
process.stderr.write(`Error reading file: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
42
|
+
process.exitCode = ExitCode.USAGE;
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if (!sql) {
|
|
47
|
+
sql = readStdin() ?? undefined;
|
|
48
|
+
}
|
|
49
|
+
if (!sql) {
|
|
50
|
+
process.stderr.write("Error: No SQL provided. Pass as argument, use --file, or pipe via stdin.\n");
|
|
51
|
+
process.exitCode = ExitCode.USAGE;
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
// Dry run: print SQL and exit
|
|
55
|
+
if (opts["dryRun"]) {
|
|
56
|
+
const format = getFormat(cmd);
|
|
57
|
+
renderMessage(sql, format);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
await withConnection(cmd, "execute_sql", async (resolved, ctx) => {
|
|
61
|
+
// Configure read-only mode based on CLI flag and system config
|
|
62
|
+
const readOnly = opts["readOnly"] || resolved.config.readOnly;
|
|
63
|
+
// Confirm execution if system requires it
|
|
64
|
+
if (resolved.config.confirm && process.stdin.isTTY) {
|
|
65
|
+
const { promptPassword } = await import("../config/credentials.js");
|
|
66
|
+
const answer = await promptPassword(`Execute on [${resolved.name}]? (y/N) `);
|
|
67
|
+
if (answer.toLowerCase() !== "y") {
|
|
68
|
+
throw new Error("Execution cancelled by user");
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
// Apply maxRows limit if not already in the query
|
|
72
|
+
let execSql = sql;
|
|
73
|
+
let maxRows = resolved.config.maxRows;
|
|
74
|
+
if (opts["limit"]) {
|
|
75
|
+
maxRows = parseInt(opts["limit"], 10);
|
|
76
|
+
if (isNaN(maxRows) || maxRows < 0) {
|
|
77
|
+
throw new Error(`Invalid --limit value: "${opts["limit"]}". Must be a positive integer.`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (maxRows &&
|
|
81
|
+
!execSql.toUpperCase().includes("FETCH FIRST") &&
|
|
82
|
+
!execSql.toUpperCase().includes("FETCH NEXT")) {
|
|
83
|
+
execSql = `${execSql.replace(/;\s*$/, "")} FETCH FIRST ${maxRows} ROWS ONLY`;
|
|
84
|
+
}
|
|
85
|
+
// Configure execute_sql tool security before importing
|
|
86
|
+
const { configureExecuteSqlTool } = await import("../../ibmi-mcp-server/tools/executeSql.tool.js");
|
|
87
|
+
configureExecuteSqlTool({
|
|
88
|
+
enabled: true,
|
|
89
|
+
security: { readOnly },
|
|
90
|
+
});
|
|
91
|
+
const { executeSqlTool } = await import("../../ibmi-mcp-server/tools/executeSql.tool.js");
|
|
92
|
+
const logicFn = executeSqlTool.logic;
|
|
93
|
+
const result = await logicFn({ sql: execSql }, ctx, {});
|
|
94
|
+
if (!result.success) {
|
|
95
|
+
throw new Error(result.error?.message ?? "SQL execution failed");
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
data: (result.data ?? []),
|
|
99
|
+
meta: {
|
|
100
|
+
rowCount: result.rowCount ?? 0,
|
|
101
|
+
},
|
|
102
|
+
};
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=sql.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sql.js","sourceRoot":"","sources":["../../../src/cli/commands/sql.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview `ibmi system` commands for managing IBM i system configurations.
|
|
3
|
+
* Provides list, show, add, remove, default, and test subcommands.
|
|
4
|
+
* @module cli/commands/system
|
|
5
|
+
*/
|
|
6
|
+
import { Command } from "commander";
|
|
7
|
+
/**
|
|
8
|
+
* Register all `ibmi system` subcommands.
|
|
9
|
+
*/
|
|
10
|
+
export declare function registerSystemCommand(program: Command): void;
|
|
11
|
+
//# sourceMappingURL=system.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"system.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/system.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA0DpC;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAoQ5D"}
|