@neverinfamous/mysql-mcp 2.3.0 → 3.0.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/.dockerignore +1 -0
- package/.gitattributes +18 -0
- package/.github/workflows/codeql.yml +2 -10
- package/.github/workflows/docker-publish.yml +15 -13
- package/CHANGELOG.md +287 -1
- package/DOCKER_README.md +100 -265
- package/Dockerfile +5 -0
- package/README.md +124 -59
- package/VERSION +1 -1
- package/dist/__tests__/mocks/adapter.d.ts.map +1 -1
- package/dist/__tests__/mocks/adapter.js +2 -0
- package/dist/__tests__/mocks/adapter.js.map +1 -1
- package/dist/adapters/DatabaseAdapter.d.ts.map +1 -1
- package/dist/adapters/DatabaseAdapter.js +50 -9
- package/dist/adapters/DatabaseAdapter.js.map +1 -1
- package/dist/adapters/mysql/MySQLAdapter.d.ts +6 -0
- package/dist/adapters/mysql/MySQLAdapter.d.ts.map +1 -1
- package/dist/adapters/mysql/MySQLAdapter.js +8 -0
- package/dist/adapters/mysql/MySQLAdapter.js.map +1 -1
- package/dist/adapters/mysql/SchemaManager.js +16 -15
- package/dist/adapters/mysql/SchemaManager.js.map +1 -1
- package/dist/adapters/mysql/prompts/index.js +10 -20
- package/dist/adapters/mysql/prompts/index.js.map +1 -1
- package/dist/adapters/mysql/prompts/proxysqlSetup.js +1 -1
- package/dist/adapters/mysql/resources/docstore.d.ts.map +1 -1
- package/dist/adapters/mysql/resources/docstore.js +10 -7
- package/dist/adapters/mysql/resources/docstore.js.map +1 -1
- package/dist/adapters/mysql/resources/events.js +11 -8
- package/dist/adapters/mysql/resources/events.js.map +1 -1
- package/dist/adapters/mysql/resources/indexes.d.ts.map +1 -1
- package/dist/adapters/mysql/resources/indexes.js +12 -15
- package/dist/adapters/mysql/resources/indexes.js.map +1 -1
- package/dist/adapters/mysql/resources/innodb.d.ts.map +1 -1
- package/dist/adapters/mysql/resources/innodb.js +20 -17
- package/dist/adapters/mysql/resources/innodb.js.map +1 -1
- package/dist/adapters/mysql/resources/locks.d.ts.map +1 -1
- package/dist/adapters/mysql/resources/locks.js +9 -6
- package/dist/adapters/mysql/resources/locks.js.map +1 -1
- package/dist/adapters/mysql/resources/performance.d.ts.map +1 -1
- package/dist/adapters/mysql/resources/performance.js +15 -15
- package/dist/adapters/mysql/resources/performance.js.map +1 -1
- package/dist/adapters/mysql/resources/spatial.d.ts.map +1 -1
- package/dist/adapters/mysql/resources/spatial.js +9 -6
- package/dist/adapters/mysql/resources/spatial.js.map +1 -1
- package/dist/adapters/mysql/resources/sysschema.d.ts.map +1 -1
- package/dist/adapters/mysql/resources/sysschema.js +12 -9
- package/dist/adapters/mysql/resources/sysschema.js.map +1 -1
- package/dist/adapters/mysql/tools/admin/backup.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/admin/backup.js +170 -121
- package/dist/adapters/mysql/tools/admin/backup.js.map +1 -1
- package/dist/adapters/mysql/tools/admin/maintenance.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/admin/maintenance.js +106 -57
- package/dist/adapters/mysql/tools/admin/maintenance.js.map +1 -1
- package/dist/adapters/mysql/tools/admin/monitoring.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/admin/monitoring.js +183 -101
- package/dist/adapters/mysql/tools/admin/monitoring.js.map +1 -1
- package/dist/adapters/mysql/tools/cluster/group-replication.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/cluster/group-replication.js +164 -120
- package/dist/adapters/mysql/tools/cluster/group-replication.js.map +1 -1
- package/dist/adapters/mysql/tools/cluster/innodb-cluster.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/cluster/innodb-cluster.js +212 -145
- package/dist/adapters/mysql/tools/cluster/innodb-cluster.js.map +1 -1
- package/dist/adapters/mysql/tools/codemode/index.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/codemode/index.js +6 -4
- package/dist/adapters/mysql/tools/codemode/index.js.map +1 -1
- package/dist/adapters/mysql/tools/core.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/core.js +152 -29
- package/dist/adapters/mysql/tools/core.js.map +1 -1
- package/dist/adapters/mysql/tools/docstore.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/docstore.js +340 -163
- package/dist/adapters/mysql/tools/docstore.js.map +1 -1
- package/dist/adapters/mysql/tools/events.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/events.js +284 -198
- package/dist/adapters/mysql/tools/events.js.map +1 -1
- package/dist/adapters/mysql/tools/json/core.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/json/core.js +11 -39
- package/dist/adapters/mysql/tools/json/core.js.map +1 -1
- package/dist/adapters/mysql/tools/json/enhanced.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/json/enhanced.js +15 -33
- package/dist/adapters/mysql/tools/json/enhanced.js.map +1 -1
- package/dist/adapters/mysql/tools/json/helpers.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/json/helpers.js +13 -24
- package/dist/adapters/mysql/tools/json/helpers.js.map +1 -1
- package/dist/adapters/mysql/tools/partitioning.js +3 -0
- package/dist/adapters/mysql/tools/partitioning.js.map +1 -1
- package/dist/adapters/mysql/tools/performance/analysis.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/performance/analysis.js +89 -60
- package/dist/adapters/mysql/tools/performance/analysis.js.map +1 -1
- package/dist/adapters/mysql/tools/performance/optimization.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/performance/optimization.js +151 -127
- package/dist/adapters/mysql/tools/performance/optimization.js.map +1 -1
- package/dist/adapters/mysql/tools/proxysql.d.ts +1 -1
- package/dist/adapters/mysql/tools/proxysql.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/proxysql.js +289 -176
- package/dist/adapters/mysql/tools/proxysql.js.map +1 -1
- package/dist/adapters/mysql/tools/replication.js +75 -49
- package/dist/adapters/mysql/tools/replication.js.map +1 -1
- package/dist/adapters/mysql/tools/roles.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/roles.js +224 -182
- package/dist/adapters/mysql/tools/roles.js.map +1 -1
- package/dist/adapters/mysql/tools/router.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/router.js +168 -67
- package/dist/adapters/mysql/tools/router.js.map +1 -1
- package/dist/adapters/mysql/tools/schema/constraints.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/schema/constraints.js +21 -3
- package/dist/adapters/mysql/tools/schema/constraints.js.map +1 -1
- package/dist/adapters/mysql/tools/schema/management.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/schema/management.js +61 -14
- package/dist/adapters/mysql/tools/schema/management.js.map +1 -1
- package/dist/adapters/mysql/tools/schema/routines.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/schema/routines.js +27 -4
- package/dist/adapters/mysql/tools/schema/routines.js.map +1 -1
- package/dist/adapters/mysql/tools/schema/scheduled_events.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/schema/scheduled_events.js +24 -3
- package/dist/adapters/mysql/tools/schema/scheduled_events.js.map +1 -1
- package/dist/adapters/mysql/tools/schema/triggers.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/schema/triggers.js +23 -2
- package/dist/adapters/mysql/tools/schema/triggers.js.map +1 -1
- package/dist/adapters/mysql/tools/schema/views.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/schema/views.js +47 -7
- package/dist/adapters/mysql/tools/schema/views.js.map +1 -1
- package/dist/adapters/mysql/tools/security/audit.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/security/audit.js +102 -34
- package/dist/adapters/mysql/tools/security/audit.js.map +1 -1
- package/dist/adapters/mysql/tools/security/data-protection.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/security/data-protection.js +264 -205
- package/dist/adapters/mysql/tools/security/data-protection.js.map +1 -1
- package/dist/adapters/mysql/tools/security/encryption.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/security/encryption.js +137 -104
- package/dist/adapters/mysql/tools/security/encryption.js.map +1 -1
- package/dist/adapters/mysql/tools/shell/backup.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/shell/backup.js +71 -59
- package/dist/adapters/mysql/tools/shell/backup.js.map +1 -1
- package/dist/adapters/mysql/tools/shell/restore.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/shell/restore.js +61 -47
- package/dist/adapters/mysql/tools/shell/restore.js.map +1 -1
- package/dist/adapters/mysql/tools/spatial/geometry.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/spatial/geometry.js +19 -5
- package/dist/adapters/mysql/tools/spatial/geometry.js.map +1 -1
- package/dist/adapters/mysql/tools/spatial/operations.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/spatial/operations.js +42 -17
- package/dist/adapters/mysql/tools/spatial/operations.js.map +1 -1
- package/dist/adapters/mysql/tools/spatial/queries.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/spatial/queries.js +109 -57
- package/dist/adapters/mysql/tools/spatial/queries.js.map +1 -1
- package/dist/adapters/mysql/tools/spatial/setup.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/spatial/setup.js +103 -50
- package/dist/adapters/mysql/tools/spatial/setup.js.map +1 -1
- package/dist/adapters/mysql/tools/stats/comparative.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/stats/comparative.js +128 -79
- package/dist/adapters/mysql/tools/stats/comparative.js.map +1 -1
- package/dist/adapters/mysql/tools/stats/descriptive.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/stats/descriptive.js +174 -102
- package/dist/adapters/mysql/tools/stats/descriptive.js.map +1 -1
- package/dist/adapters/mysql/tools/sysschema/activity.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/sysschema/activity.js +50 -25
- package/dist/adapters/mysql/tools/sysschema/activity.js.map +1 -1
- package/dist/adapters/mysql/tools/sysschema/performance.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/sysschema/performance.js +121 -66
- package/dist/adapters/mysql/tools/sysschema/performance.js.map +1 -1
- package/dist/adapters/mysql/tools/sysschema/resources.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/sysschema/resources.js +101 -64
- package/dist/adapters/mysql/tools/sysschema/resources.js.map +1 -1
- package/dist/adapters/mysql/tools/text/fulltext.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/text/fulltext.js +18 -32
- package/dist/adapters/mysql/tools/text/fulltext.js.map +1 -1
- package/dist/adapters/mysql/tools/transactions.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/transactions.js +48 -23
- package/dist/adapters/mysql/tools/transactions.js.map +1 -1
- package/dist/adapters/mysql/types/proxysql-types.d.ts +15 -0
- package/dist/adapters/mysql/types/proxysql-types.d.ts.map +1 -1
- package/dist/adapters/mysql/types/proxysql-types.js +33 -1
- package/dist/adapters/mysql/types/proxysql-types.js.map +1 -1
- package/dist/adapters/mysql/types/router-types.d.ts +1 -1
- package/dist/adapters/mysql/types/router-types.js +1 -1
- package/dist/adapters/mysql/types/router-types.js.map +1 -1
- package/dist/adapters/mysql/types/shell-types.js +2 -2
- package/dist/adapters/mysql/types/shell-types.js.map +1 -1
- package/dist/adapters/mysql/types.d.ts +485 -21
- package/dist/adapters/mysql/types.d.ts.map +1 -1
- package/dist/adapters/mysql/types.js +546 -19
- package/dist/adapters/mysql/types.js.map +1 -1
- package/dist/auth/scopes.js +1 -1
- package/dist/auth/scopes.js.map +1 -1
- package/dist/codemode/api.d.ts +3 -2
- package/dist/codemode/api.d.ts.map +1 -1
- package/dist/codemode/api.js +80 -5
- package/dist/codemode/api.js.map +1 -1
- package/dist/codemode/sandbox-factory.js +1 -1
- package/dist/codemode/sandbox-factory.js.map +1 -1
- package/dist/codemode/types.d.ts +26 -0
- package/dist/codemode/types.d.ts.map +1 -1
- package/dist/codemode/types.js +2 -0
- package/dist/codemode/types.js.map +1 -1
- package/dist/codemode/worker-sandbox.d.ts +4 -2
- package/dist/codemode/worker-sandbox.d.ts.map +1 -1
- package/dist/codemode/worker-sandbox.js +66 -7
- package/dist/codemode/worker-sandbox.js.map +1 -1
- package/dist/codemode/worker-script.d.ts +3 -0
- package/dist/codemode/worker-script.d.ts.map +1 -1
- package/dist/codemode/worker-script.js +128 -75
- package/dist/codemode/worker-script.js.map +1 -1
- package/dist/constants/ServerInstructions.d.ts +1 -1
- package/dist/constants/ServerInstructions.d.ts.map +1 -1
- package/dist/constants/ServerInstructions.js +37 -31
- package/dist/constants/ServerInstructions.js.map +1 -1
- package/dist/filtering/ToolConstants.d.ts +1 -1
- package/dist/filtering/ToolConstants.d.ts.map +1 -1
- package/dist/filtering/ToolConstants.js +1 -2
- package/dist/filtering/ToolConstants.js.map +1 -1
- package/dist/pool/ConnectionPool.d.ts.map +1 -1
- package/dist/pool/ConnectionPool.js.map +1 -1
- package/dist/transports/http.d.ts.map +1 -1
- package/dist/transports/http.js +6 -0
- package/dist/transports/http.js.map +1 -1
- package/dist/utils/validators.d.ts +1 -1
- package/dist/utils/validators.d.ts.map +1 -1
- package/dist/utils/validators.js.map +1 -1
- package/package.json +4 -4
- package/releases/v2.3.0-release-notes.md +20 -20
- package/releases/v2.3.1-release-notes.md +34 -0
- package/releases/v3.0.0-release-notes.md +81 -0
- package/src/__tests__/mocks/adapter.ts +3 -0
- package/src/__tests__/perf.test.ts +6 -6
- package/src/adapters/DatabaseAdapter.ts +58 -9
- package/src/adapters/__tests__/DatabaseAdapter.test.ts +89 -8
- package/src/adapters/mysql/MySQLAdapter.ts +17 -2
- package/src/adapters/mysql/SchemaManager.ts +21 -21
- package/src/adapters/mysql/__tests__/MySQLAdapter.test.ts +1 -1
- package/src/adapters/mysql/prompts/index.ts +12 -22
- package/src/adapters/mysql/prompts/proxysqlSetup.ts +1 -1
- package/src/adapters/mysql/resources/docstore.ts +13 -10
- package/src/adapters/mysql/resources/events.ts +12 -12
- package/src/adapters/mysql/resources/indexes.ts +17 -19
- package/src/adapters/mysql/resources/innodb.ts +23 -22
- package/src/adapters/mysql/resources/locks.ts +9 -7
- package/src/adapters/mysql/resources/performance.ts +23 -18
- package/src/adapters/mysql/resources/spatial.ts +9 -7
- package/src/adapters/mysql/resources/sysschema.ts +12 -11
- package/src/adapters/mysql/tools/__tests__/core.test.ts +126 -55
- package/src/adapters/mysql/tools/__tests__/docstore.test.ts +459 -88
- package/src/adapters/mysql/tools/__tests__/events.test.ts +281 -103
- package/src/adapters/mysql/tools/__tests__/proxysql.test.ts +128 -28
- package/src/adapters/mysql/tools/__tests__/replication.test.ts +48 -2
- package/src/adapters/mysql/tools/__tests__/roles.test.ts +15 -18
- package/src/adapters/mysql/tools/__tests__/router.test.ts +32 -5
- package/src/adapters/mysql/tools/__tests__/security.test.ts +126 -2
- package/src/adapters/mysql/tools/__tests__/security_injection.test.ts +84 -76
- package/src/adapters/mysql/tools/__tests__/security_integration.test.ts +47 -50
- package/src/adapters/mysql/tools/__tests__/spatial.test.ts +11 -10
- package/src/adapters/mysql/tools/__tests__/spatial_handler.test.ts +54 -38
- package/src/adapters/mysql/tools/__tests__/stats.test.ts +285 -152
- package/src/adapters/mysql/tools/__tests__/transactions.test.ts +13 -13
- package/src/adapters/mysql/tools/admin/__tests__/backup.test.ts +171 -25
- package/src/adapters/mysql/tools/admin/__tests__/maintenance.test.ts +240 -4
- package/src/adapters/mysql/tools/admin/__tests__/monitoring-summary.test.ts +274 -0
- package/src/adapters/mysql/tools/admin/__tests__/monitoring.test.ts +94 -5
- package/src/adapters/mysql/tools/admin/backup.ts +193 -143
- package/src/adapters/mysql/tools/admin/maintenance.ts +118 -69
- package/src/adapters/mysql/tools/admin/monitoring.ts +201 -125
- package/src/adapters/mysql/tools/cluster/__tests__/group-replication.test.ts +69 -0
- package/src/adapters/mysql/tools/cluster/__tests__/innodb-cluster.test.ts +141 -0
- package/src/adapters/mysql/tools/cluster/group-replication.ts +172 -132
- package/src/adapters/mysql/tools/cluster/innodb-cluster.ts +231 -157
- package/src/adapters/mysql/tools/codemode/__tests__/codemode-tool.test.ts +227 -0
- package/src/adapters/mysql/tools/codemode/index.ts +5 -3
- package/src/adapters/mysql/tools/core.ts +152 -38
- package/src/adapters/mysql/tools/docstore.ts +422 -205
- package/src/adapters/mysql/tools/events.ts +334 -233
- package/src/adapters/mysql/tools/json/__tests__/core.test.ts +20 -0
- package/src/adapters/mysql/tools/json/__tests__/enhanced.test.ts +82 -50
- package/src/adapters/mysql/tools/json/__tests__/helpers.test.ts +42 -3
- package/src/adapters/mysql/tools/json/core.ts +21 -42
- package/src/adapters/mysql/tools/json/enhanced.ts +22 -37
- package/src/adapters/mysql/tools/json/helpers.ts +21 -25
- package/src/adapters/mysql/tools/partitioning.ts +3 -0
- package/src/adapters/mysql/tools/performance/__tests__/analysis.test.ts +98 -5
- package/src/adapters/mysql/tools/performance/__tests__/optimization-coverage.test.ts +515 -0
- package/src/adapters/mysql/tools/performance/__tests__/optimization.test.ts +187 -0
- package/src/adapters/mysql/tools/performance/analysis.ts +95 -69
- package/src/adapters/mysql/tools/performance/optimization.ts +182 -153
- package/src/adapters/mysql/tools/proxysql.ts +314 -209
- package/src/adapters/mysql/tools/replication.ts +84 -57
- package/src/adapters/mysql/tools/roles.ts +274 -226
- package/src/adapters/mysql/tools/router.ts +181 -85
- package/src/adapters/mysql/tools/schema/__tests__/constraints.test.ts +13 -0
- package/src/adapters/mysql/tools/schema/__tests__/management.test.ts +60 -25
- package/src/adapters/mysql/tools/schema/__tests__/scheduled_events.test.ts +11 -0
- package/src/adapters/mysql/tools/schema/__tests__/triggers.test.ts +25 -4
- package/src/adapters/mysql/tools/schema/__tests__/views.test.ts +46 -14
- package/src/adapters/mysql/tools/schema/constraints.ts +22 -3
- package/src/adapters/mysql/tools/schema/management.ts +60 -15
- package/src/adapters/mysql/tools/schema/routines.ts +26 -4
- package/src/adapters/mysql/tools/schema/scheduled_events.ts +25 -3
- package/src/adapters/mysql/tools/schema/triggers.ts +27 -2
- package/src/adapters/mysql/tools/schema/views.ts +46 -8
- package/src/adapters/mysql/tools/security/__tests__/audit.test.ts +90 -4
- package/src/adapters/mysql/tools/security/audit.ts +113 -39
- package/src/adapters/mysql/tools/security/data-protection.ts +293 -233
- package/src/adapters/mysql/tools/security/encryption.ts +172 -139
- package/src/adapters/mysql/tools/shell/__tests__/backup.test.ts +29 -0
- package/src/adapters/mysql/tools/shell/backup.ts +90 -73
- package/src/adapters/mysql/tools/shell/restore.ts +62 -48
- package/src/adapters/mysql/tools/spatial/__tests__/operations.test.ts +22 -14
- package/src/adapters/mysql/tools/spatial/__tests__/queries.test.ts +65 -51
- package/src/adapters/mysql/tools/spatial/geometry.ts +23 -7
- package/src/adapters/mysql/tools/spatial/operations.ts +60 -31
- package/src/adapters/mysql/tools/spatial/queries.ts +142 -65
- package/src/adapters/mysql/tools/spatial/setup.ts +121 -55
- package/src/adapters/mysql/tools/stats/__tests__/comparative.test.ts +12 -10
- package/src/adapters/mysql/tools/stats/comparative.ts +150 -98
- package/src/adapters/mysql/tools/stats/descriptive.ts +204 -127
- package/src/adapters/mysql/tools/sysschema/__tests__/error-paths.test.ts +222 -0
- package/src/adapters/mysql/tools/sysschema/__tests__/performance.test.ts +45 -0
- package/src/adapters/mysql/tools/sysschema/__tests__/resources.test.ts +6 -3
- package/src/adapters/mysql/tools/sysschema/activity.ts +52 -27
- package/src/adapters/mysql/tools/sysschema/performance.ts +132 -68
- package/src/adapters/mysql/tools/sysschema/resources.ts +105 -67
- package/src/adapters/mysql/tools/text/__tests__/fulltext.test.ts +45 -17
- package/src/adapters/mysql/tools/text/fulltext.ts +27 -38
- package/src/adapters/mysql/tools/transactions.ts +49 -24
- package/src/adapters/mysql/types/proxysql-types.ts +38 -1
- package/src/adapters/mysql/types/router-types.ts +1 -1
- package/src/adapters/mysql/types/shell-types.ts +2 -2
- package/src/adapters/mysql/types.ts +632 -19
- package/src/auth/__tests__/scopes.test.ts +2 -2
- package/src/auth/scopes.ts +1 -1
- package/src/codemode/__tests__/api.test.ts +417 -0
- package/src/codemode/__tests__/sandbox-factory.test.ts +158 -0
- package/src/codemode/__tests__/sandbox.test.ts +301 -0
- package/src/codemode/__tests__/security.test.ts +368 -0
- package/src/codemode/__tests__/worker-sandbox.test.ts +179 -0
- package/src/codemode/__tests__/worker-script.test.ts +226 -0
- package/src/codemode/api.ts +89 -5
- package/src/codemode/sandbox-factory.ts +1 -1
- package/src/codemode/types.ts +34 -0
- package/src/codemode/worker-sandbox.ts +74 -7
- package/src/codemode/worker-script.ts +157 -86
- package/src/constants/ServerInstructions.ts +37 -31
- package/src/filtering/ToolConstants.ts +1 -2
- package/src/filtering/__tests__/ToolFilter.test.ts +9 -9
- package/src/pool/ConnectionPool.ts +4 -1
- package/src/transports/__tests__/http.test.ts +15 -3
- package/src/transports/http.ts +12 -0
- package/src/utils/validators.ts +2 -1
- package/vitest.config.ts +3 -1
- package/CODE_MODE.md +0 -245
|
@@ -435,6 +435,27 @@ describe("Performance Optimization Tools", () => {
|
|
|
435
435
|
);
|
|
436
436
|
});
|
|
437
437
|
|
|
438
|
+
it("should strip adapter prefix from query execution error", async () => {
|
|
439
|
+
mockAdapter.executeReadQuery.mockRejectedValue(
|
|
440
|
+
new Error(
|
|
441
|
+
"Query failed: Execute failed: Table 'testdb.ghost' doesn't exist",
|
|
442
|
+
),
|
|
443
|
+
);
|
|
444
|
+
|
|
445
|
+
const tool = createOptimizerTraceTool(
|
|
446
|
+
mockAdapter as unknown as MySQLAdapter,
|
|
447
|
+
);
|
|
448
|
+
|
|
449
|
+
const result = (await tool.handler(
|
|
450
|
+
{ query: "SELECT * FROM ghost" },
|
|
451
|
+
mockContext,
|
|
452
|
+
)) as { query: string; trace: null; error: string };
|
|
453
|
+
|
|
454
|
+
expect(result.query).toBe("SELECT * FROM ghost");
|
|
455
|
+
expect(result.trace).toBeNull();
|
|
456
|
+
expect(result.error).toBe("Table 'testdb.ghost' doesn't exist");
|
|
457
|
+
});
|
|
458
|
+
|
|
438
459
|
it("should accept sql alias for query parameter", async () => {
|
|
439
460
|
mockAdapter.executeReadQuery
|
|
440
461
|
.mockResolvedValueOnce(createMockQueryResult([])) // The query
|
|
@@ -454,5 +475,171 @@ describe("Performance Optimization Tools", () => {
|
|
|
454
475
|
);
|
|
455
476
|
expect(result).toHaveProperty("trace");
|
|
456
477
|
});
|
|
478
|
+
|
|
479
|
+
it("should return structured error when trace fetch fails", async () => {
|
|
480
|
+
mockAdapter.executeReadQuery
|
|
481
|
+
.mockResolvedValueOnce(createMockQueryResult([])) // The query succeeds
|
|
482
|
+
.mockRejectedValueOnce(new Error("Access denied for OPTIMIZER_TRACE")); // The trace fetch fails
|
|
483
|
+
|
|
484
|
+
const tool = createOptimizerTraceTool(
|
|
485
|
+
mockAdapter as unknown as MySQLAdapter,
|
|
486
|
+
);
|
|
487
|
+
const result = (await tool.handler(
|
|
488
|
+
{ query: "SELECT * FROM users" },
|
|
489
|
+
mockContext,
|
|
490
|
+
)) as { success: boolean; error: string };
|
|
491
|
+
|
|
492
|
+
expect(result.success).toBe(false);
|
|
493
|
+
expect(result.error).toBe("Access denied for OPTIMIZER_TRACE");
|
|
494
|
+
|
|
495
|
+
// Verify optimizer trace is still disabled in finally block
|
|
496
|
+
expect(mockAdapter.executeQuery).toHaveBeenCalledWith(
|
|
497
|
+
'SET optimizer_trace="enabled=off"',
|
|
498
|
+
);
|
|
499
|
+
});
|
|
500
|
+
});
|
|
501
|
+
|
|
502
|
+
describe("alias support", () => {
|
|
503
|
+
it("mysql_index_recommendation should accept tableName alias", async () => {
|
|
504
|
+
const mockTableInfo = createMockTableInfo("orders");
|
|
505
|
+
mockTableInfo.columns = [
|
|
506
|
+
{ name: "id", type: "int", nullable: false, primaryKey: true },
|
|
507
|
+
];
|
|
508
|
+
mockAdapter.describeTable.mockResolvedValue(mockTableInfo);
|
|
509
|
+
mockAdapter.getTableIndexes.mockResolvedValue([
|
|
510
|
+
{
|
|
511
|
+
name: "PRIMARY",
|
|
512
|
+
tableName: "orders",
|
|
513
|
+
columns: ["id"],
|
|
514
|
+
unique: true,
|
|
515
|
+
type: "BTREE",
|
|
516
|
+
},
|
|
517
|
+
]);
|
|
518
|
+
|
|
519
|
+
const tool = createIndexRecommendationTool(
|
|
520
|
+
mockAdapter as unknown as MySQLAdapter,
|
|
521
|
+
);
|
|
522
|
+
const result = (await tool.handler(
|
|
523
|
+
{ tableName: "orders" },
|
|
524
|
+
mockContext,
|
|
525
|
+
)) as { exists: boolean; table: string };
|
|
526
|
+
|
|
527
|
+
expect(result.exists).toBe(true);
|
|
528
|
+
expect(result.table).toBe("orders");
|
|
529
|
+
expect(mockAdapter.describeTable).toHaveBeenCalledWith("orders");
|
|
530
|
+
});
|
|
531
|
+
|
|
532
|
+
it("mysql_force_index should accept tableName alias", async () => {
|
|
533
|
+
const mockTableInfo = createMockTableInfo("users");
|
|
534
|
+
mockTableInfo.columns = [
|
|
535
|
+
{ name: "id", type: "int", nullable: false, primaryKey: true },
|
|
536
|
+
];
|
|
537
|
+
mockAdapter.describeTable.mockResolvedValue(mockTableInfo);
|
|
538
|
+
mockAdapter.getTableIndexes.mockResolvedValue([
|
|
539
|
+
{
|
|
540
|
+
name: "idx_name",
|
|
541
|
+
tableName: "users",
|
|
542
|
+
columns: ["name"],
|
|
543
|
+
unique: false,
|
|
544
|
+
type: "BTREE",
|
|
545
|
+
},
|
|
546
|
+
]);
|
|
547
|
+
|
|
548
|
+
const tool = createForceIndexTool(mockAdapter as unknown as MySQLAdapter);
|
|
549
|
+
const result = (await tool.handler(
|
|
550
|
+
{
|
|
551
|
+
tableName: "users",
|
|
552
|
+
query: "SELECT * FROM users WHERE name = 'test'",
|
|
553
|
+
indexName: "idx_name",
|
|
554
|
+
},
|
|
555
|
+
mockContext,
|
|
556
|
+
)) as { rewrittenQuery: string };
|
|
557
|
+
|
|
558
|
+
expect(result.rewrittenQuery).toContain("FORCE INDEX");
|
|
559
|
+
expect(mockAdapter.describeTable).toHaveBeenCalledWith("users");
|
|
560
|
+
});
|
|
561
|
+
});
|
|
562
|
+
|
|
563
|
+
describe("try/catch error handling", () => {
|
|
564
|
+
it("mysql_index_recommendation should return structured error on adapter throw", async () => {
|
|
565
|
+
mockAdapter.describeTable.mockRejectedValue(new Error("Connection lost"));
|
|
566
|
+
|
|
567
|
+
const tool = createIndexRecommendationTool(
|
|
568
|
+
mockAdapter as unknown as MySQLAdapter,
|
|
569
|
+
);
|
|
570
|
+
const result = (await tool.handler({ table: "users" }, mockContext)) as {
|
|
571
|
+
success: boolean;
|
|
572
|
+
error: string;
|
|
573
|
+
};
|
|
574
|
+
|
|
575
|
+
expect(result.success).toBe(false);
|
|
576
|
+
expect(result.error).toBe("Connection lost");
|
|
577
|
+
});
|
|
578
|
+
|
|
579
|
+
it("mysql_force_index should return structured error on adapter throw", async () => {
|
|
580
|
+
mockAdapter.describeTable.mockRejectedValue(new Error("Connection lost"));
|
|
581
|
+
|
|
582
|
+
const tool = createForceIndexTool(mockAdapter as unknown as MySQLAdapter);
|
|
583
|
+
const result = (await tool.handler(
|
|
584
|
+
{
|
|
585
|
+
table: "users",
|
|
586
|
+
query: "SELECT * FROM users",
|
|
587
|
+
indexName: "idx_name",
|
|
588
|
+
},
|
|
589
|
+
mockContext,
|
|
590
|
+
)) as { success: boolean; error: string };
|
|
591
|
+
|
|
592
|
+
expect(result.success).toBe(false);
|
|
593
|
+
expect(result.error).toBe("Connection lost");
|
|
594
|
+
});
|
|
595
|
+
|
|
596
|
+
it("mysql_query_rewrite should return structured error on parse failure", async () => {
|
|
597
|
+
const tool = createQueryRewriteTool(
|
|
598
|
+
mockAdapter as unknown as MySQLAdapter,
|
|
599
|
+
);
|
|
600
|
+
const result = (await tool.handler({}, mockContext)) as {
|
|
601
|
+
success: boolean;
|
|
602
|
+
error: string;
|
|
603
|
+
};
|
|
604
|
+
|
|
605
|
+
expect(result.success).toBe(false);
|
|
606
|
+
expect(result.error).toBeDefined();
|
|
607
|
+
});
|
|
608
|
+
|
|
609
|
+
it("mysql_optimizer_trace should return structured error on missing query", async () => {
|
|
610
|
+
const tool = createOptimizerTraceTool(
|
|
611
|
+
mockAdapter as unknown as MySQLAdapter,
|
|
612
|
+
);
|
|
613
|
+
const result = (await tool.handler({}, mockContext)) as {
|
|
614
|
+
success: boolean;
|
|
615
|
+
error: string;
|
|
616
|
+
};
|
|
617
|
+
|
|
618
|
+
expect(result.success).toBe(false);
|
|
619
|
+
expect(result.error).toBeDefined();
|
|
620
|
+
// Verify optimizer trace was never enabled (parse failed before SET)
|
|
621
|
+
expect(mockAdapter.executeQuery).not.toHaveBeenCalledWith(
|
|
622
|
+
'SET optimizer_trace="enabled=on"',
|
|
623
|
+
);
|
|
624
|
+
});
|
|
625
|
+
|
|
626
|
+
it("mysql_query_rewrite should strip adapter prefix from explainError", async () => {
|
|
627
|
+
mockAdapter.executeReadQuery.mockRejectedValue(
|
|
628
|
+
new Error(
|
|
629
|
+
"Query failed: Execute failed: Table 'testdb.ghost' doesn't exist",
|
|
630
|
+
),
|
|
631
|
+
);
|
|
632
|
+
|
|
633
|
+
const tool = createQueryRewriteTool(
|
|
634
|
+
mockAdapter as unknown as MySQLAdapter,
|
|
635
|
+
);
|
|
636
|
+
const result = (await tool.handler(
|
|
637
|
+
{ query: "SELECT * FROM ghost" },
|
|
638
|
+
mockContext,
|
|
639
|
+
)) as { explainPlan: unknown; explainError: string };
|
|
640
|
+
|
|
641
|
+
expect(result.explainPlan).toBeNull();
|
|
642
|
+
expect(result.explainError).toBe("Table 'testdb.ghost' doesn't exist");
|
|
643
|
+
});
|
|
457
644
|
});
|
|
458
645
|
});
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
ExplainAnalyzeSchema,
|
|
17
17
|
ExplainAnalyzeSchemaBase,
|
|
18
18
|
SlowQuerySchema,
|
|
19
|
+
QueryStatsSchema,
|
|
19
20
|
IndexUsageSchema,
|
|
20
21
|
IndexUsageSchemaBase,
|
|
21
22
|
TableStatsSchema,
|
|
@@ -163,7 +164,8 @@ export function createSlowQueriesTool(adapter: MySQLAdapter): ToolDefinition {
|
|
|
163
164
|
handler: async (params: unknown, _context: RequestContext) => {
|
|
164
165
|
const { limit, minTime } = SlowQuerySchema.parse(params);
|
|
165
166
|
|
|
166
|
-
|
|
167
|
+
try {
|
|
168
|
+
let sql = `
|
|
167
169
|
SELECT
|
|
168
170
|
LEFT(DIGEST_TEXT, 200) as query,
|
|
169
171
|
COUNT_STAR as executions,
|
|
@@ -174,53 +176,50 @@ export function createSlowQueriesTool(adapter: MySQLAdapter): ToolDefinition {
|
|
|
174
176
|
FROM performance_schema.events_statements_summary_by_digest
|
|
175
177
|
`;
|
|
176
178
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
179
|
+
if (minTime !== undefined) {
|
|
180
|
+
sql += ` WHERE AVG_TIMER_WAIT > ${minTime * 1000000000000}`;
|
|
181
|
+
}
|
|
180
182
|
|
|
181
|
-
|
|
183
|
+
sql += ` ORDER BY AVG_TIMER_WAIT DESC LIMIT ${limit}`;
|
|
182
184
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
185
|
+
const result = await adapter.executeReadQuery(sql);
|
|
186
|
+
return {
|
|
187
|
+
slowQueries: sanitizeTimerRows(result.rows, [
|
|
188
|
+
"avg_time_ms",
|
|
189
|
+
"total_time_ms",
|
|
190
|
+
]),
|
|
191
|
+
};
|
|
192
|
+
} catch (error) {
|
|
193
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
194
|
+
return { success: false, error: msg };
|
|
195
|
+
}
|
|
190
196
|
},
|
|
191
197
|
};
|
|
192
198
|
}
|
|
193
199
|
|
|
194
200
|
export function createQueryStatsTool(adapter: MySQLAdapter): ToolDefinition {
|
|
195
|
-
const schema = z.object({
|
|
196
|
-
orderBy: z
|
|
197
|
-
.enum(["total_time", "avg_time", "executions"])
|
|
198
|
-
.optional()
|
|
199
|
-
.default("total_time"),
|
|
200
|
-
limit: z.number().optional().default(10),
|
|
201
|
-
});
|
|
202
|
-
|
|
203
201
|
return {
|
|
204
202
|
name: "mysql_query_stats",
|
|
205
203
|
title: "MySQL Query Stats",
|
|
206
204
|
description: "Get query statistics from performance_schema.",
|
|
207
205
|
group: "performance",
|
|
208
|
-
inputSchema:
|
|
206
|
+
inputSchema: QueryStatsSchema,
|
|
209
207
|
requiredScopes: ["read"],
|
|
210
208
|
annotations: {
|
|
211
209
|
readOnlyHint: true,
|
|
212
210
|
idempotentHint: true,
|
|
213
211
|
},
|
|
214
212
|
handler: async (params: unknown, _context: RequestContext) => {
|
|
215
|
-
const { orderBy, limit } =
|
|
213
|
+
const { orderBy, limit } = QueryStatsSchema.parse(params);
|
|
216
214
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
215
|
+
try {
|
|
216
|
+
const orderColumn = {
|
|
217
|
+
total_time: "SUM_TIMER_WAIT",
|
|
218
|
+
avg_time: "AVG_TIMER_WAIT",
|
|
219
|
+
executions: "COUNT_STAR",
|
|
220
|
+
}[orderBy];
|
|
222
221
|
|
|
223
|
-
|
|
222
|
+
const sql = `
|
|
224
223
|
SELECT
|
|
225
224
|
SCHEMA_NAME as database_name,
|
|
226
225
|
LEFT(DIGEST_TEXT, 200) as query_text,
|
|
@@ -238,14 +237,18 @@ export function createQueryStatsTool(adapter: MySQLAdapter): ToolDefinition {
|
|
|
238
237
|
LIMIT ${limit}
|
|
239
238
|
`;
|
|
240
239
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
240
|
+
const result = await adapter.executeReadQuery(sql);
|
|
241
|
+
return {
|
|
242
|
+
queries: sanitizeTimerRows(result.rows, [
|
|
243
|
+
"avg_time_ms",
|
|
244
|
+
"max_time_ms",
|
|
245
|
+
"total_time_ms",
|
|
246
|
+
]),
|
|
247
|
+
};
|
|
248
|
+
} catch (error) {
|
|
249
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
250
|
+
return { success: false, error: msg };
|
|
251
|
+
}
|
|
249
252
|
},
|
|
250
253
|
};
|
|
251
254
|
}
|
|
@@ -263,22 +266,23 @@ export function createIndexUsageTool(adapter: MySQLAdapter): ToolDefinition {
|
|
|
263
266
|
idempotentHint: true,
|
|
264
267
|
},
|
|
265
268
|
handler: async (params: unknown, _context: RequestContext) => {
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
269
|
+
try {
|
|
270
|
+
const { table, limit } = IndexUsageSchema.parse(params);
|
|
271
|
+
|
|
272
|
+
// P154: Check table existence when a specific table is requested
|
|
273
|
+
if (table) {
|
|
274
|
+
const check = await adapter.executeReadQuery(
|
|
275
|
+
`SELECT 1 FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?`,
|
|
276
|
+
[table],
|
|
277
|
+
);
|
|
278
|
+
if (!check.rows || check.rows.length === 0) {
|
|
279
|
+
return { exists: false, table };
|
|
280
|
+
}
|
|
276
281
|
}
|
|
277
|
-
}
|
|
278
282
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
283
|
+
// Always filter to current database to avoid returning thousands of
|
|
284
|
+
// MySQL internal indexes with zero counts
|
|
285
|
+
let sql = `
|
|
282
286
|
SELECT
|
|
283
287
|
object_schema as database_name,
|
|
284
288
|
object_name as table_name,
|
|
@@ -294,14 +298,21 @@ export function createIndexUsageTool(adapter: MySQLAdapter): ToolDefinition {
|
|
|
294
298
|
AND object_schema = DATABASE()
|
|
295
299
|
`;
|
|
296
300
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
301
|
+
if (table) {
|
|
302
|
+
sql += ` AND object_name = ?`;
|
|
303
|
+
}
|
|
300
304
|
|
|
301
|
-
|
|
305
|
+
sql += ` ORDER BY count_read + count_write DESC LIMIT ${limit}`;
|
|
302
306
|
|
|
303
|
-
|
|
304
|
-
|
|
307
|
+
const result = await adapter.executeReadQuery(
|
|
308
|
+
sql,
|
|
309
|
+
table ? [table] : [],
|
|
310
|
+
);
|
|
311
|
+
return { indexUsage: result.rows };
|
|
312
|
+
} catch (error) {
|
|
313
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
314
|
+
return { success: false, error: msg };
|
|
315
|
+
}
|
|
305
316
|
},
|
|
306
317
|
};
|
|
307
318
|
}
|
|
@@ -320,9 +331,10 @@ export function createTableStatsTool(adapter: MySQLAdapter): ToolDefinition {
|
|
|
320
331
|
idempotentHint: true,
|
|
321
332
|
},
|
|
322
333
|
handler: async (params: unknown, _context: RequestContext) => {
|
|
323
|
-
|
|
334
|
+
try {
|
|
335
|
+
const { table } = TableStatsSchema.parse(params);
|
|
324
336
|
|
|
325
|
-
|
|
337
|
+
const sql = `
|
|
326
338
|
SELECT
|
|
327
339
|
TABLE_NAME as table_name,
|
|
328
340
|
ENGINE as engine,
|
|
@@ -341,13 +353,17 @@ export function createTableStatsTool(adapter: MySQLAdapter): ToolDefinition {
|
|
|
341
353
|
AND TABLE_NAME = ?
|
|
342
354
|
`;
|
|
343
355
|
|
|
344
|
-
|
|
356
|
+
const result = await adapter.executeReadQuery(sql, [table]);
|
|
345
357
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
358
|
+
if (!result.rows || result.rows.length === 0) {
|
|
359
|
+
return { exists: false, table };
|
|
360
|
+
}
|
|
349
361
|
|
|
350
|
-
|
|
362
|
+
return { stats: result.rows[0] };
|
|
363
|
+
} catch (error) {
|
|
364
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
365
|
+
return { success: false, error: msg };
|
|
366
|
+
}
|
|
351
367
|
},
|
|
352
368
|
};
|
|
353
369
|
}
|
|
@@ -369,8 +385,9 @@ export function createBufferPoolStatsTool(
|
|
|
369
385
|
idempotentHint: true,
|
|
370
386
|
},
|
|
371
387
|
handler: async (_params: unknown, _context: RequestContext) => {
|
|
372
|
-
|
|
373
|
-
|
|
388
|
+
try {
|
|
389
|
+
const result = await adapter.executeReadQuery(
|
|
390
|
+
`SELECT POOL_ID, POOL_SIZE, FREE_BUFFERS, DATABASE_PAGES,
|
|
374
391
|
OLD_DATABASE_PAGES, MODIFIED_DATABASE_PAGES, PENDING_DECOMPRESS,
|
|
375
392
|
PENDING_READS, PENDING_FLUSH_LRU, PENDING_FLUSH_LIST,
|
|
376
393
|
PAGES_MADE_YOUNG, PAGES_NOT_MADE_YOUNG,
|
|
@@ -380,9 +397,13 @@ export function createBufferPoolStatsTool(
|
|
|
380
397
|
HIT_RATE, YOUNG_MAKE_PER_THOUSAND_GETS,
|
|
381
398
|
NOT_YOUNG_MAKE_PER_THOUSAND_GETS
|
|
382
399
|
FROM information_schema.INNODB_BUFFER_POOL_STATS`,
|
|
383
|
-
|
|
400
|
+
);
|
|
384
401
|
|
|
385
|
-
|
|
402
|
+
return { bufferPoolStats: result.rows };
|
|
403
|
+
} catch (error) {
|
|
404
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
405
|
+
return { success: false, error: msg };
|
|
406
|
+
}
|
|
386
407
|
},
|
|
387
408
|
};
|
|
388
409
|
}
|
|
@@ -402,7 +423,8 @@ export function createThreadStatsTool(adapter: MySQLAdapter): ToolDefinition {
|
|
|
402
423
|
idempotentHint: true,
|
|
403
424
|
},
|
|
404
425
|
handler: async (_params: unknown, _context: RequestContext) => {
|
|
405
|
-
|
|
426
|
+
try {
|
|
427
|
+
const result = await adapter.executeReadQuery(`
|
|
406
428
|
SELECT
|
|
407
429
|
THREAD_ID,
|
|
408
430
|
NAME,
|
|
@@ -420,7 +442,11 @@ export function createThreadStatsTool(adapter: MySQLAdapter): ToolDefinition {
|
|
|
420
442
|
ORDER BY PROCESSLIST_TIME DESC
|
|
421
443
|
`);
|
|
422
444
|
|
|
423
|
-
|
|
445
|
+
return { threads: result.rows };
|
|
446
|
+
} catch (error) {
|
|
447
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
448
|
+
return { success: false, error: msg };
|
|
449
|
+
}
|
|
424
450
|
},
|
|
425
451
|
};
|
|
426
452
|
}
|