@sonenta/mcp 0.30.0 → 0.31.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sonenta/mcp",
3
- "version": "0.30.0",
3
+ "version": "0.31.0",
4
4
  "description": "MCP server for Sonenta translation management \u2014 wires Claude Desktop and other MCP clients into your project's keys, missing-key feed, and translation drafts.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://sonenta.com",
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "sonenta-mcp"
3
- version = "0.30.0"
3
+ version = "0.31.0"
4
4
  description = "Model Context Protocol server for Sonenta — list projects, missing keys, propose translations from Claude Desktop and other MCP clients."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12,<3.14"
@@ -1,3 +1,3 @@
1
1
  """Sonenta MCP server (MIT)."""
2
2
 
3
- __version__ = "0.30.0"
3
+ __version__ = "0.31.0"
@@ -89,16 +89,20 @@ from .client import VerbumiaApiError, VerbumiaClient
89
89
  # visible text. `surfaceKinds` in the variants matrix tags each as a11y.
90
90
  A11Y_SURFACES = ("aria_label", "alt_text", "screen_reader", "plain_language")
91
91
 
92
- # RS1 (task 1367): audit trail of code edits an agent made while resolving a
93
- # duplicate group — passed on set_source_duplicate_merge_plan / set_duplicate_status,
94
- # persisted + surfaced in resolved_duplicates[]. Supplying it overwrites; omitting
95
- # preserves the prior value.
92
+ # RS1 (task 1367) + FM1 (task 1390): audit trail of code edits an agent made while
93
+ # resolving a duplicate group — accepted on ALL FOUR resolution paths
94
+ # (set_source_duplicate_merge_plan, set_duplicate_status, apply_new_key_cluster,
95
+ # mark_cluster_applied), persisted + surfaced in resolved_duplicates[]. FM1 changed
96
+ # the semantics to UNION-MERGE (accumulate + dedup by tuple), not overwrite.
96
97
  _FILES_MODIFIED_SCHEMA = {
97
98
  "type": "array",
98
99
  "description": (
99
100
  "Optional audit trail of the code edits you made (e.g. t() repoints) while "
100
- "resolving this group: each {path (required), line?, key_name?}. Supplying it "
101
- "overwrites the stored record; omit to preserve the prior value."
101
+ "resolving this group: each {path (required), line?, key_name?}. Accepted on "
102
+ "every resolution path and MERGED (union + dedup by the full {path,line,"
103
+ "key_name} tuple) into the record — so record your edits at whatever step you "
104
+ "make them and they accumulate; omit to preserve the existing list. Always "
105
+ "pass the STRUCTURED field, never just a note."
102
106
  ),
103
107
  "items": {
104
108
  "type": "object",
@@ -2291,6 +2295,7 @@ def register(server: Server, client: VerbumiaClient) -> tuple[Any, Any]:
2291
2295
  "type": "boolean",
2292
2296
  "description": "True to mark applied (default), false to un-mark.",
2293
2297
  },
2298
+ "files_modified": _FILES_MODIFIED_SCHEMA,
2294
2299
  },
2295
2300
  "required": ["source_value", "canonical_key_uuid"],
2296
2301
  "additionalProperties": False,
@@ -2308,8 +2313,8 @@ def register(server: Server, client: VerbumiaClient) -> tuple[Any, Any]:
2308
2313
  "the name must be free). Returns {new_key_uuid, name, namespace, "
2309
2314
  "copied_from_key_uuid, copied_languages, trashed_key_uuids}. YOUR job "
2310
2315
  "after this is the CODE only: repoint every t() usage of the trashed "
2311
- "keys onto new_key_uuid, then record it via set_source_duplicate_merge_"
2312
- "plan / set_duplicate_status files_modified. You do NOT create_key or "
2316
+ "keys onto new_key_uuid, and record those edits in `files_modified` "
2317
+ "(accepted right here, union-merged). You do NOT create_key or "
2313
2318
  "delete_keys_bulk yourself — the backend owns that. Author the "
2314
2319
  "new_key cluster in the merge plan first (on the dev's acceptance)."
2315
2320
  ),
@@ -2333,6 +2338,7 @@ def register(server: Server, client: VerbumiaClient) -> tuple[Any, Any]:
2333
2338
  },
2334
2339
  "required": ["name", "namespace"],
2335
2340
  },
2341
+ "files_modified": _FILES_MODIFIED_SCHEMA,
2336
2342
  },
2337
2343
  "required": ["source_value", "new_key"],
2338
2344
  "additionalProperties": False,
@@ -3088,6 +3094,8 @@ def register(server: Server, client: VerbumiaClient) -> tuple[Any, Any]:
3088
3094
  }
3089
3095
  if "applied" in args:
3090
3096
  body["applied"] = bool(args["applied"])
3097
+ if args.get("files_modified"):
3098
+ body["files_modified"] = args["files_modified"]
3091
3099
  data = await client.put(
3092
3100
  f"/v1/mcp/projects/{project_uuid}/source-duplicates/cluster-applied",
3093
3101
  json=body,
@@ -3100,9 +3108,12 @@ def register(server: Server, client: VerbumiaClient) -> tuple[Any, Any]:
3100
3108
  return _err("source_value and new_key {name, namespace} are required")
3101
3109
  if not new_key.get("name") or not new_key.get("namespace"):
3102
3110
  return _err("new_key requires name and namespace")
3111
+ body = {"source_value": args["source_value"], "new_key": new_key}
3112
+ if args.get("files_modified"):
3113
+ body["files_modified"] = args["files_modified"]
3103
3114
  data = await client.post(
3104
3115
  f"/v1/mcp/projects/{project_uuid}/source-duplicates/apply-cluster",
3105
- json={"source_value": args["source_value"], "new_key": new_key},
3116
+ json=body,
3106
3117
  )
3107
3118
  return _text(data)
3108
3119
  return _err(f"unknown tool: {name}")