@hanna84/mcp-writing 1.11.7 → 1.12.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/CHANGELOG.md CHANGED
@@ -4,11 +4,31 @@ All notable changes to this project will be documented in this file. Dates are d
4
4
 
5
5
  Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
6
6
 
7
+ #### [v1.12.0](https://github.com/hannasdev/mcp-writing.git
8
+ /compare/v1.11.8...v1.12.0)
9
+
10
+ - feat(scrivener-direct): ownership enforcement (PR-3a) [`#68`](https://github.com/hannasdev/mcp-writing.git
11
+ /pull/68)
12
+
13
+ #### [v1.11.8](https://github.com/hannasdev/mcp-writing.git
14
+ /compare/v1.11.7...v1.11.8)
15
+
16
+ > 24 April 2026
17
+
18
+ - chore(deps): remove unused fast-xml-parser and bump @xmldom/xmldom [`#67`](https://github.com/hannasdev/mcp-writing.git
19
+ /pull/67)
20
+ - Release 1.11.8 [`7329eb4`](https://github.com/hannasdev/mcp-writing.git
21
+ /commit/7329eb4107bb0ac1889d58446604381a47370133)
22
+
7
23
  #### [v1.11.7](https://github.com/hannasdev/mcp-writing.git
8
24
  /compare/v1.11.6...v1.11.7)
9
25
 
26
+ > 24 April 2026
27
+
10
28
  - refactor: consolidate merge_scrivener_project_beta to async-only [`#66`](https://github.com/hannasdev/mcp-writing.git
11
29
  /pull/66)
30
+ - Release 1.11.7 [`9e5e236`](https://github.com/hannasdev/mcp-writing.git
31
+ /commit/9e5e236c576d5d4f4beba1845ea41ffa1d7c6950)
12
32
 
13
33
  #### [v1.11.6](https://github.com/hannasdev/mcp-writing.git
14
34
  /compare/v1.11.5...v1.11.6)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hanna84/mcp-writing",
3
- "version": "1.11.7",
3
+ "version": "1.12.0",
4
4
  "description": "MCP service for AI-assisted reasoning and editing on long-form fiction projects",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -51,8 +51,7 @@
51
51
  },
52
52
  "dependencies": {
53
53
  "@modelcontextprotocol/sdk": "^1.29.0",
54
- "@xmldom/xmldom": "^0.9.9",
55
- "fast-xml-parser": "^5.6.0",
54
+ "@xmldom/xmldom": "^0.9.10",
56
55
  "gray-matter": "^4.0.3",
57
56
  "js-yaml": "^4.1.1",
58
57
  "zod": "^4.3.6"
@@ -100,6 +100,21 @@ function moveFileIfNeeded(fromPath, toPath) {
100
100
  return { moved: true };
101
101
  }
102
102
 
103
+ // Fields that are exclusively owned by the stable Scrivener sync-folder importer.
104
+ // The beta merge must never write these fields, even additively, because the
105
+ // importer derives them from the source filename and project structure in ways
106
+ // the beta merge path cannot reliably replicate (e.g. scene_id slug, timeline
107
+ // position from file sequence, external identity).
108
+ export const IMPORTER_AUTHORITATIVE_FIELDS = Object.freeze([
109
+ "scene_id",
110
+ "external_source",
111
+ "external_id",
112
+ "title",
113
+ "timeline_position",
114
+ ]);
115
+
116
+ const IMPORTER_AUTHORITATIVE_FIELD_SET = new Set(IMPORTER_AUTHORITATIVE_FIELDS);
117
+
103
118
  const KNOWN_CUSTOM_FIELD_IDS = new Set([
104
119
  "savethecat!",
105
120
  "causality",
@@ -222,8 +237,13 @@ function buildMergeDataFromProject(projectData, uuid) {
222
237
  export function mergeSidecarData(existing, mergeData) {
223
238
  const merged = { ...existing };
224
239
  const newKeys = [];
240
+ const blockedKeys = [];
225
241
 
226
242
  for (const [key, value] of Object.entries(mergeData)) {
243
+ if (IMPORTER_AUTHORITATIVE_FIELD_SET.has(key)) {
244
+ blockedKeys.push(key);
245
+ continue;
246
+ }
227
247
  if (!(key in merged)) {
228
248
  merged[key] = value;
229
249
  newKeys.push(key);
@@ -234,6 +254,7 @@ export function mergeSidecarData(existing, mergeData) {
234
254
  merged,
235
255
  changed: newKeys.length > 0,
236
256
  newKeys,
257
+ blockedKeys,
237
258
  };
238
259
  }
239
260