@hanna84/mcp-writing 2.9.0 → 2.9.1
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 +10 -0
- package/index.js +19 -6
- package/package.json +1 -1
- package/sync.js +4 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,11 +4,21 @@ 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
|
+
#### [v2.9.1](https://github.com/hannasdev/mcp-writing.git
|
|
8
|
+
/compare/v2.9.0...v2.9.1)
|
|
9
|
+
|
|
10
|
+
- fix(describe-workflows): suppress structural dir names as project_id [`#93`](https://github.com/hannasdev/mcp-writing.git
|
|
11
|
+
/pull/93)
|
|
12
|
+
|
|
7
13
|
#### [v2.9.0](https://github.com/hannasdev/mcp-writing.git
|
|
8
14
|
/compare/v2.8.0...v2.9.0)
|
|
9
15
|
|
|
16
|
+
> 26 April 2026
|
|
17
|
+
|
|
10
18
|
- feat(get_runtime_config): include server_version in response [`#92`](https://github.com/hannasdev/mcp-writing.git
|
|
11
19
|
/pull/92)
|
|
20
|
+
- Release 2.9.0 [`bea57f7`](https://github.com/hannasdev/mcp-writing.git
|
|
21
|
+
/commit/bea57f7c7548a428e5335425114b1dbc2cd19450)
|
|
12
22
|
|
|
13
23
|
#### [v2.8.0](https://github.com/hannasdev/mcp-writing.git
|
|
14
24
|
/compare/v2.7.0...v2.8.0)
|
package/index.js
CHANGED
|
@@ -12,7 +12,7 @@ import matter from "gray-matter";
|
|
|
12
12
|
import yaml from "js-yaml";
|
|
13
13
|
import { z } from "zod";
|
|
14
14
|
import { openDb } from "./db.js";
|
|
15
|
-
import { syncAll, isSyncDirWritable, getSyncOwnershipDiagnostics, getFileWriteDiagnostics, writeMeta, readMeta, indexSceneFile, normalizeSceneMetaForPath, sidecarPath } from "./sync.js";
|
|
15
|
+
import { syncAll, isSyncDirWritable, getSyncOwnershipDiagnostics, getFileWriteDiagnostics, writeMeta, readMeta, indexSceneFile, normalizeSceneMetaForPath, sidecarPath, isStructuralProjectId } from "./sync.js";
|
|
16
16
|
import { isGitAvailable, isGitRepository, initGitRepository, createSnapshot, listSnapshots, getSceneProseAtCommit, getHeadCommitHash } from "./git.js";
|
|
17
17
|
import { renderCharacterArcTemplate, renderCharacterSheetTemplate, renderPlaceSheetTemplate, slugifyEntityName } from "./world-entity-templates.js";
|
|
18
18
|
import { importScrivenerSync, validateProjectId, validateUniverseId } from "./importer.js";
|
|
@@ -866,7 +866,7 @@ const WORKFLOW_CATALOGUE = [
|
|
|
866
866
|
steps: [
|
|
867
867
|
{ tool: "describe_workflows", note: "Check context.scene_count; use that value as max_scenes in the next call." },
|
|
868
868
|
{ tool: "bootstrap_prose_styleguide_config", note: "Detect dominant conventions. Confirm suggestions with the user before applying." },
|
|
869
|
-
{ tool: "setup_prose_styleguide_config", note: "
|
|
869
|
+
{ tool: "setup_prose_styleguide_config", note: "Only if ALL context.styleguide_exists fields are false — a config at any scope is sufficient. Create at project_root scope (requires project_id and language e.g. 'english_us'), or sync_root if no project_id is known." },
|
|
870
870
|
{ tool: "update_prose_styleguide_config", note: "Apply the fields accepted from bootstrap suggestions." },
|
|
871
871
|
],
|
|
872
872
|
},
|
|
@@ -960,7 +960,15 @@ function createMcpServer() {
|
|
|
960
960
|
const projectRow = db.prepare(
|
|
961
961
|
`SELECT project_id FROM scenes GROUP BY project_id ORDER BY COUNT(*) DESC, project_id ASC LIMIT 1`
|
|
962
962
|
).get();
|
|
963
|
-
|
|
963
|
+
// Suppress structural-dir names (e.g. "scenes") that appear when SYNC_DIR points at the
|
|
964
|
+
// project directory itself rather than the universe root. They are path artifacts, not
|
|
965
|
+
// real project identifiers. Only suppress when no real project directory exists at that
|
|
966
|
+
// path, so a project intentionally named "scenes" (though inadvisable) is still honoured.
|
|
967
|
+
const rawProjectId = projectRow?.project_id ?? null;
|
|
968
|
+
const rawProjectRootPath = rawProjectId ? resolveProjectRoot(rawProjectId) : null;
|
|
969
|
+
const project_id = (
|
|
970
|
+
isStructuralProjectId(rawProjectId) && !fs.existsSync(rawProjectRootPath)
|
|
971
|
+
) ? null : rawProjectId;
|
|
964
972
|
|
|
965
973
|
const sceneCountRow = db.prepare(`SELECT COUNT(*) as count FROM scenes`).get();
|
|
966
974
|
const scene_count = sceneCountRow?.count ?? 0;
|
|
@@ -974,6 +982,10 @@ function createMcpServer() {
|
|
|
974
982
|
? path.join(SYNC_DIR, "universes", universeSegment, STYLEGUIDE_CONFIG_BASENAME)
|
|
975
983
|
: null;
|
|
976
984
|
|
|
985
|
+
const syncRootExists = fs.existsSync(syncRootConfigPath);
|
|
986
|
+
const universeRootExists = universeRootConfigPath !== null && fs.existsSync(universeRootConfigPath);
|
|
987
|
+
const projectRootExists = projectRootConfigPath !== null && fs.existsSync(projectRootConfigPath);
|
|
988
|
+
|
|
977
989
|
return jsonResponse({
|
|
978
990
|
ok: true,
|
|
979
991
|
context: {
|
|
@@ -981,9 +993,9 @@ function createMcpServer() {
|
|
|
981
993
|
scene_count,
|
|
982
994
|
sync_dir: SYNC_DIR_ABS,
|
|
983
995
|
styleguide_exists: {
|
|
984
|
-
sync_root:
|
|
985
|
-
universe_root:
|
|
986
|
-
project_root:
|
|
996
|
+
sync_root: syncRootExists,
|
|
997
|
+
universe_root: universeRootExists,
|
|
998
|
+
project_root: projectRootExists,
|
|
987
999
|
},
|
|
988
1000
|
git_available: GIT_AVAILABLE,
|
|
989
1001
|
pending_proposals: pendingProposals.size,
|
|
@@ -994,6 +1006,7 @@ function createMcpServer() {
|
|
|
994
1006
|
"If a tool returns a next_step field (in a success or error response), follow it before trying anything else.",
|
|
995
1007
|
"Use find_scenes without filters to discover what project_ids are indexed.",
|
|
996
1008
|
"When calling bootstrap_prose_styleguide_config or check_prose_styleguide_drift, set max_scenes to context.scene_count to avoid the default limit.",
|
|
1009
|
+
"Styleguide tools resolve config in priority order: project_root > universe_root > sync_root. If any styleguide_exists field is true, a config exists and styleguide tools will work — do not run setup_prose_styleguide_config unless ALL styleguide_exists fields are false.",
|
|
997
1010
|
],
|
|
998
1011
|
});
|
|
999
1012
|
}
|
package/package.json
CHANGED
package/sync.js
CHANGED
|
@@ -99,6 +99,10 @@ export function normalizeSceneMetaForPath(syncDir, filePath, meta = {}) {
|
|
|
99
99
|
// Structural directory names that are never project slugs under projects/<id>/.
|
|
100
100
|
const PROJECT_STRUCTURAL_DIRS = new Set(["world", "scenes", "misc", "fragments", "feedback", "draft"]);
|
|
101
101
|
|
|
102
|
+
export function isStructuralProjectId(name) {
|
|
103
|
+
return typeof name === "string" && PROJECT_STRUCTURAL_DIRS.has(name.toLowerCase());
|
|
104
|
+
}
|
|
105
|
+
|
|
102
106
|
// Cache universe project root existence checks during sync scans.
|
|
103
107
|
const UNIVERSE_PROJECT_ROOT_CACHE = new Map();
|
|
104
108
|
|