Skip to content

Commit fab6584

Browse files
Merge pull request #35 from actinon-com/release-1.6.1
release: v1.6.1 - Enforce runtime Zod schema parsing across all operational tools
2 parents 7ca006b + f7e7d6a commit fab6584

34 files changed

Lines changed: 136 additions & 54 deletions

dist/bundle/index.js

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -38886,16 +38886,17 @@ const SetupInstanceSchema = schemas_object({
3888638886
* @returns Success message with Odoo version detected.
3888738887
*/
3888838888
async function setupInstance(configStore, credentialStore, input) {
38889-
const { alias } = input;
38889+
const parsedInput = SetupInstanceSchema.parse(input);
38890+
const { alias } = parsedInput;
3889038891
// 1. Load existing state for surgical updates
3889138892
const existingMetadata = await configStore.getByAlias(alias);
3889238893
const existingApiKey = await credentialStore.getApiKey(alias);
3889338894
// 2. Merge inputs with existing data
3889438895
const finalConfig = {
38895-
url: input.url || existingMetadata?.url,
38896-
db: input.db || existingMetadata?.db,
38897-
username: input.username || existingMetadata?.username,
38898-
api_key: input.api_key || existingApiKey,
38896+
url: parsedInput.url || existingMetadata?.url,
38897+
db: parsedInput.db || existingMetadata?.db,
38898+
username: parsedInput.username || existingMetadata?.username,
38899+
api_key: parsedInput.api_key || existingApiKey,
3889938900
};
3890038901
// 3. Validation: Ensure we have a complete set of credentials
3890138902
if (!finalConfig.url || !finalConfig.db || !finalConfig.username || !finalConfig.api_key) {
@@ -39106,7 +39107,8 @@ const InspectModelSchema = schemas_object({
3910639107
* Fully optimized via in-memory MetadataCache.
3910739108
*/
3910839109
async function inspectModel(manager, input) {
39109-
const { model, instance_alias, ...flags } = input;
39110+
const parsedInput = InspectModelSchema.parse(input);
39111+
const { model, instance_alias, ...flags } = parsedInput;
3911039112
const client = await manager.getClient(instance_alias);
3911139113
const alias = instance_alias || 'default';
3911239114
// 1. Resolve and cache metadata (or load from cache)
@@ -39474,7 +39476,8 @@ const GetViewSchema = schemas_object({
3947439476
* @returns The view architecture (XML) and metadata.
3947539477
*/
3947639478
async function getView(manager, input) {
39477-
const { model, view_type, view_id, instance_alias } = input;
39479+
const parsedInput = GetViewSchema.parse(input);
39480+
const { model, view_type, view_id, instance_alias } = parsedInput;
3947839481
const client = await manager.getClient(instance_alias);
3947939482
// Odoo 16+ uses get_view, earlier versions use fields_view_get
3948039483
const method = (client.majorVersion || 0) >= 16 ? 'get_view' : 'fields_view_get';
@@ -40385,7 +40388,8 @@ const CreateRecordSchema = schemas_object({
4038540388
* @returns The database ID of the newly created record.
4038640389
*/
4038740390
async function createRecord(manager, input) {
40388-
const { model, values, justification, with_translations, instance_alias } = input;
40391+
const parsedInput = CreateRecordSchema.parse(input);
40392+
const { model, values, justification, with_translations, instance_alias } = parsedInput;
4038940393
const client = await manager.getClient(instance_alias);
4039040394
const audit = await manager.getAudit(instance_alias);
4039140395
const orchestrator = new OdooOrchestrator(client);
@@ -40443,7 +40447,8 @@ const WriteRecordSchema = schemas_object({
4044340447
* @returns Boolean true on success.
4044440448
*/
4044540449
async function writeRecord(manager, input) {
40446-
const { model, id, values, justification, with_translations, instance_alias } = input;
40450+
const parsedInput = WriteRecordSchema.parse(input);
40451+
const { model, id, values, justification, with_translations, instance_alias } = parsedInput;
4044740452
const client = await manager.getClient(instance_alias);
4044840453
const audit = await manager.getAudit(instance_alias);
4044940454
const orchestrator = new OdooOrchestrator(client);
@@ -40509,7 +40514,8 @@ const UnlinkRecordSchema = schemas_object({
4050940514
* @returns Boolean true on success.
4051040515
*/
4051140516
async function unlinkRecord(manager, input) {
40512-
const { model, id, justification, instance_alias } = input;
40517+
const parsedInput = UnlinkRecordSchema.parse(input);
40518+
const { model, id, justification, instance_alias } = parsedInput;
4051340519
const client = await manager.getClient(instance_alias);
4051440520
const audit = await manager.getAudit(instance_alias);
4051540521
const success = await client.executeKw(model, 'unlink', [[id]]);
@@ -40744,7 +40750,8 @@ const GetEnvironmentSchema = schemas_object({
4074440750
* Provides server, user, and organization context in one call.
4074540751
*/
4074640752
async function getEnvironment(manager, input) {
40747-
const { show_security, show_manifest, instance_alias } = input;
40753+
const parsedInput = GetEnvironmentSchema.parse(input);
40754+
const { show_security, show_manifest, instance_alias } = parsedInput;
4074840755
const client = await manager.getClient(instance_alias);
4074940756
// Ensure authenticated
4075040757
await client.authenticate();
@@ -40864,7 +40871,8 @@ const TraceUiPathSchema = schemas_object({
4086440871
* Helps the agent understand how a user visually accesses specific data.
4086540872
*/
4086640873
async function traceUiPath(manager, input) {
40867-
const { model, instance_alias } = input;
40874+
const parsedInput = TraceUiPathSchema.parse(input);
40875+
const { model, instance_alias } = parsedInput;
4086840876
const client = await manager.getClient(instance_alias);
4086940877
// 1. Find Window Actions for this model
4087040878
const actions = await client.executeKw('ir.actions.act_window', 'search_read', [[['res_model', '=', model]]], {
@@ -40987,7 +40995,8 @@ const GetAuditLogSchema = schemas_object({
4098740995
* Allows the agent to verify its own history and provide transparency.
4098840996
*/
4098940997
async function getAuditLog(manager, input) {
40990-
const { limit, instance_alias } = input;
40998+
const parsedInput = GetAuditLogSchema.parse(input);
40999+
const { limit, instance_alias } = parsedInput;
4099141000
const audit = await manager.getAudit(instance_alias);
4099241001
const logs = await audit.getLocalLogs(limit);
4099341002
if (logs.length === 0) {
@@ -41050,7 +41059,7 @@ async function getAuditLog(manager, input) {
4105041059

4105141060
const mcp_server_dirname = external_path_default().dirname((0,external_url_.fileURLToPath)(import.meta.url));
4105241061
// Read package.json for metadata
41053-
let mcp_server_version = "1.6.0";
41062+
let mcp_server_version = "1.6.1";
4105441063
try {
4105541064
// Try both possible locations (source vs bundled)
4105641065
const pkgPaths = [

dist/bundle/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"name":"brass-monkey","version":"1.6.0","type":"module","main":"dist/index.js","scripts":{"build":"tsc && npm run bundle","bundle":"ncc build src/mcp-server.ts -o dist/bundle","test":"vitest run","test:watch":"vitest","lint":"eslint src/**/*.ts"},"keywords":["odoo","gemini","gemini-cli","cli","extension","mcp","ai-agent","xml-rpc","erp","crm"],"author":"Actinon","license":"MIT","description":"A high-fidelity Gemini CLI extension and MCP bridge for Odoo ERP/CRM.","dependencies":{"@modelcontextprotocol/sdk":"^1.29.0","keytar":"^7.9.0","xmlrpc":"^1.3.2","zod":"^4.3.6","zod-to-json-schema":"^3.25.2"},"devDependencies":{"@types/keytar":"^4.4.0","@types/node":"^25.6.0","@types/xmlrpc":"^1.3.10","@vercel/ncc":"^0.38.4","esbuild":"^0.28.0","typescript":"^6.0.3","vitest":"^4.1.4"}}
1+
{"name":"brass-monkey","version":"1.6.1","type":"module","main":"dist/index.js","scripts":{"build":"tsc && npm run bundle","bundle":"ncc build src/mcp-server.ts -o dist/bundle","test":"vitest run","test:watch":"vitest","lint":"eslint src/**/*.ts"},"keywords":["odoo","gemini","gemini-cli","cli","extension","mcp","ai-agent","xml-rpc","erp","crm"],"author":"Actinon","license":"MIT","description":"A high-fidelity Gemini CLI extension and MCP bridge for Odoo ERP/CRM.","dependencies":{"@modelcontextprotocol/sdk":"^1.29.0","keytar":"^7.9.0","xmlrpc":"^1.3.2","zod":"^4.3.6","zod-to-json-schema":"^3.25.2"},"devDependencies":{"@types/keytar":"^4.4.0","@types/node":"^25.6.0","@types/xmlrpc":"^1.3.10","@vercel/ncc":"^0.38.4","esbuild":"^0.28.0","typescript":"^6.0.3","vitest":"^4.1.4"}}

dist/mcp-server.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/tools/create_record.js

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/tools/create_record.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/tools/get_audit_log.js

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/tools/get_audit_log.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/tools/get_environment.js

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)