Convert four hal modules: lidarr, mongodb, mssql, mosquitto
Mirrors the proven catalog patterns field-for-field: - lidarr -> the Servarr twin of radarr/sonarr (API v1, artist content); no provisioner (it is a consumer app). - mongodb -> postgres shape: mongodb-database provider, provisioner mints a per-consumer db+user (ADR 0053), client shells to mongosh (no npm driver, the psql convention). - mssql -> postgres shape: mssql-database provider, sqlcmd client. - mosquitto -> redis shape: mqtt-topic provider via the Dynamic Security plugin, deliberately avoiding hal's password_file (that file is nox issue 011 exactly); provisioner mints a per-consumer MQTT client+role. All four typecheck (strict, NodeNext) against the built @novox/mesh-sdk, and their service images are digest-pinned to resolved registry digests. The mesh-runtime-<mod> images keep the all-zeros placeholder the pipeline pins, as postgres/redis do, and must bundle each module's CLI (mongosh/sqlcmd/ mosquitto_ctrl) as mesh-runtime-postgres bundles psql. Not yet lab-verified: each module lists in-code what an integration test must prove (auth model, provisioner reconcile, mosquitto dynsec bootstrap ordering). Claude-Session: https://claude.ai/code/session_01LrgweAeERJYBg88c5cKDzF
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
// mssql's tools — mssql's own code (novox/hq ADR 0044), importing mssql's own client. They return
|
||||
// structured data; the mesh serves them through the sdk's tool harness. Both call through
|
||||
// MssqlClient, the module's one pending execution boundary (see client.ts): the tool shapes are
|
||||
// fixed and correct, and surface the work honestly through that boundary.
|
||||
|
||||
import { registerModuleTools, type ToolDefinition } from "@novox/mesh-sdk/tools";
|
||||
import { MssqlClient } from "../client.js";
|
||||
|
||||
export function getMssqlTools(mssql: MssqlClient): ToolDefinition[] {
|
||||
return [
|
||||
{
|
||||
name: "mssql_list_databases",
|
||||
description: "List the user databases on the mssql server, with their on-disk size and state.",
|
||||
input: {},
|
||||
run: async () => ({ databases: await mssql.listDatabases() }),
|
||||
},
|
||||
{
|
||||
name: "mssql_query",
|
||||
description: "Run a read-only SELECT against a named database (wrapped in a rolled-back transaction).",
|
||||
input: {
|
||||
database: { type: "string", description: "the database to query" },
|
||||
sql: { type: "string", description: "a single SELECT statement" },
|
||||
},
|
||||
run: async (args) => {
|
||||
const database = String(args.database ?? "");
|
||||
const sql = String(args.sql ?? "");
|
||||
if (!database) throw new Error("mssql_query: database is required");
|
||||
if (!sql) throw new Error("mssql_query: sql is required");
|
||||
const result = await mssql.readOnlyQuery(database, sql);
|
||||
return { database, command: result.command, rows: result.rows };
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
// The tools exist only when the server can be reached from the environment; without it, mssql
|
||||
// contributes none rather than failing the whole tool runtime.
|
||||
registerModuleTools("mssql", (env) => {
|
||||
try {
|
||||
return getMssqlTools(MssqlClient.fromEnv(env));
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user