@syntholoc/mcp 0.1.2 → 0.2.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/dist/build-server.js
CHANGED
|
@@ -49,10 +49,15 @@ function registerPrompts(server) {
|
|
|
49
49
|
"1. Read `.syntholoc/config.json` for the source file(s) and project.",
|
|
50
50
|
projectId ? ` (Use project ${projectId} if config is missing.)` : "",
|
|
51
51
|
"2. From `git diff` on the source file(s), collect added/changed keys and `upsert_keys` (dryRun first to preview).",
|
|
52
|
+
" - MULTI-FILE / namespaced project (a file per namespace, e.g. messages/en/home.json): import each",
|
|
53
|
+
" changed file with `import_source_strings` passing `keyPrefix` = the namespace (the filename",
|
|
54
|
+
' without extension, e.g. "home"). This keeps overlapping keys from different files distinct.',
|
|
52
55
|
"3. Call `get_config` for `maxBulkSize`. For EACH target locale check `locale_progress` \u2192 `untranslated`.",
|
|
53
56
|
" - If untranslated >= maxBulkSize: `translate_locale` (scope UNTRANSLATED) and `wait_for_job`.",
|
|
54
57
|
" - If below the threshold: tell me the counts and ASK whether to translate now or accumulate.",
|
|
55
58
|
"4. `export_locale` for each translated locale and write the result back into the mapped local files.",
|
|
59
|
+
" - Namespaced project: call `export_locale` once per namespace with the same `keyPrefix` (the prefix",
|
|
60
|
+
" is stripped on export) and write each result to its file, e.g. messages/{locale}/home.json.",
|
|
56
61
|
"5. Summarize keys added, locales translated, and the cost from the job usage."
|
|
57
62
|
].filter(Boolean).join("\n")
|
|
58
63
|
)
|
|
@@ -84,10 +89,21 @@ function registerPrompts(server) {
|
|
|
84
89
|
() => userMessage(
|
|
85
90
|
[
|
|
86
91
|
"Set up Syntholoc for this repository:",
|
|
87
|
-
"1. Find the i18n source files
|
|
88
|
-
"
|
|
89
|
-
"
|
|
90
|
-
"
|
|
92
|
+
"1. Find the i18n source files and infer the source locale. Note the LAYOUT:",
|
|
93
|
+
" - Single file per locale (e.g. messages/en.json) \u2192 one mapping, no namespace.",
|
|
94
|
+
" - A directory per locale with many namespace files (e.g. messages/en/home.json, common.json) \u2192",
|
|
95
|
+
" each file is a NAMESPACE. Syntholoc stores a flat key space, so import each file under a",
|
|
96
|
+
" `keyPrefix` = its namespace to avoid collisions between files.",
|
|
97
|
+
"2. `create_project`, then `seed_starter_locales` (or `add_locale`) for the target languages. Use valid",
|
|
98
|
+
' BCP-47 codes (e.g. "zh-CN", not "cn"); `add_locale` accepts `code` or `locale`.',
|
|
99
|
+
"3. Import the source strings:",
|
|
100
|
+
" - Single file \u2192 `import_source_strings` once.",
|
|
101
|
+
" - Namespaced \u2192 `import_source_strings` once PER FILE with `keyPrefix` set to the namespace",
|
|
102
|
+
" (filename without extension). Keys become e.g. `home.title`, `common.title`.",
|
|
103
|
+
"4. Write `.syntholoc/config.json` (schema https://syntholoc.com/schemas/config.json): the `projectId` and",
|
|
104
|
+
" a Crowdin-style `files` array of `{ source, translation }` patterns with a `{locale}` placeholder,",
|
|
105
|
+
' e.g. { "source": "messages/en/home.json", "translation": "messages/{locale}/home.json", "namespace": "home" }.',
|
|
106
|
+
' Do NOT invent fields like `i18nDir`, `format: "nested-dirs"`, or `localeMapping` \u2014 they are not read.',
|
|
91
107
|
"5. Offer to run the localize_changed flow next."
|
|
92
108
|
].join("\n")
|
|
93
109
|
)
|
|
@@ -575,17 +591,22 @@ function registerKeyTools(server, gql) {
|
|
|
575
591
|
"import_source_strings",
|
|
576
592
|
{
|
|
577
593
|
title: "Import source strings",
|
|
578
|
-
description:
|
|
594
|
+
description: 'Imports source strings from ONE file (paste the raw content) and returns the diff summary. For a multi-file / namespaced project (a file per namespace, e.g. messages/en/home.json), pass `keyPrefix` (the namespace, e.g. "home") so keys become `home.title` and files with overlapping top-level keys do not collide \u2014 call once per file. Use `dryRun` to preview.',
|
|
579
595
|
inputSchema: {
|
|
580
596
|
projectId: z6.string(),
|
|
581
597
|
content: z6.string(),
|
|
582
598
|
format: z6.enum(FORMATS),
|
|
599
|
+
keyPrefix: z6.string().optional().describe('Namespace prefix, e.g. "home" (per-file, multi-file projects).'),
|
|
600
|
+
sourceFile: z6.string().optional().describe('Real source file path, e.g. "messages/en/home.json" \u2014 stored for the file tree + reliable export.'),
|
|
583
601
|
dryRun: z6.boolean().default(false)
|
|
584
602
|
},
|
|
585
603
|
annotations: { idempotentHint: true, openWorldHint: true }
|
|
586
604
|
},
|
|
587
|
-
async ({ projectId, content, format, dryRun }) => jsonResult(
|
|
588
|
-
(await gql.request(IMPORT_SOURCE_STRINGS, {
|
|
605
|
+
async ({ projectId, content, format, keyPrefix, sourceFile, dryRun }) => jsonResult(
|
|
606
|
+
(await gql.request(IMPORT_SOURCE_STRINGS, {
|
|
607
|
+
projectId,
|
|
608
|
+
input: { content, format, keyPrefix, sourceFile, dryRun }
|
|
609
|
+
})).importSourceStrings
|
|
589
610
|
)
|
|
590
611
|
);
|
|
591
612
|
}
|
|
@@ -608,10 +629,13 @@ function registerLocaleTools(server, gql) {
|
|
|
608
629
|
"add_locale",
|
|
609
630
|
{
|
|
610
631
|
title: "Add locale",
|
|
611
|
-
description: "Adds
|
|
632
|
+
description: "Adds ONE target locale to a project. To add several at once, prefer seed_starter_locales (one call for the whole list).",
|
|
612
633
|
inputSchema: {
|
|
613
634
|
projectId: z7.string(),
|
|
614
|
-
code
|
|
635
|
+
// `code` and `locale` are aliases — accept either so the natural
|
|
636
|
+
// `locale: "de-DE"` form works as well as `code`.
|
|
637
|
+
code: z7.string().optional().describe('BCP-47 code, e.g. "de-DE" or "ru". Alias: `locale`.'),
|
|
638
|
+
locale: z7.string().optional().describe("Alias for `code`."),
|
|
615
639
|
name: z7.string().optional(),
|
|
616
640
|
formality: z7.string().optional(),
|
|
617
641
|
gender: z7.string().optional(),
|
|
@@ -619,14 +643,26 @@ function registerLocaleTools(server, gql) {
|
|
|
619
643
|
},
|
|
620
644
|
annotations: { openWorldHint: true }
|
|
621
645
|
},
|
|
622
|
-
async ({ projectId,
|
|
646
|
+
async ({ projectId, code, locale, name, formality, gender, variant }) => {
|
|
647
|
+
const resolvedCode = code ?? locale;
|
|
648
|
+
if (!resolvedCode) {
|
|
649
|
+
return jsonResult({
|
|
650
|
+
error: 'Missing locale code. Pass `code` (BCP-47, e.g. "de-DE" or "ru"). To add several locales at once, use seed_starter_locales with a `codes` array.'
|
|
651
|
+
});
|
|
652
|
+
}
|
|
653
|
+
const input = { code: resolvedCode, name, formality, gender, variant };
|
|
654
|
+
return jsonResult((await gql.request(ADD_LOCALE, { projectId, input })).addLocale);
|
|
655
|
+
}
|
|
623
656
|
);
|
|
624
657
|
server.registerTool(
|
|
625
658
|
"seed_starter_locales",
|
|
626
659
|
{
|
|
627
660
|
title: "Seed starter locales",
|
|
628
|
-
description:
|
|
629
|
-
inputSchema: {
|
|
661
|
+
description: 'Adds MULTIPLE target locales in one call \u2014 pass `codes` (BCP-47, e.g. ["ru","de-DE","fr"]), or omit for a common starter set. Prefer this over repeated add_locale calls.',
|
|
662
|
+
inputSchema: {
|
|
663
|
+
projectId: z7.string(),
|
|
664
|
+
codes: z7.array(z7.string()).optional().describe('BCP-47 codes to add, e.g. ["ru","de-DE","fr"].')
|
|
665
|
+
},
|
|
630
666
|
annotations: { openWorldHint: true }
|
|
631
667
|
},
|
|
632
668
|
async ({ projectId, codes }) => jsonResult((await gql.request(SEED_STARTER_LOCALES, { projectId, codes })).seedStarterLocales)
|
|
@@ -989,12 +1025,14 @@ function registerTranslationTools(server, gql) {
|
|
|
989
1025
|
"export_locale",
|
|
990
1026
|
{
|
|
991
1027
|
title: "Export locale",
|
|
992
|
-
description:
|
|
1028
|
+
description: 'Exports a locale to a file string in the chosen format \u2014 the basis for writing translations back into local files. Set `onlyApproved` to exclude drafts. For a multi-file project prefer `sourceFile` (the real path, e.g. "messages/en/home.json") to export exactly that file with file-local key names \u2014 reliable. `keyPrefix` is the legacy name-prefix heuristic.',
|
|
993
1029
|
inputSchema: {
|
|
994
1030
|
projectId: z13.string(),
|
|
995
1031
|
localeId: z13.string(),
|
|
996
1032
|
format: z13.enum(FORMATS2).default("JSON"),
|
|
997
|
-
onlyApproved: z13.boolean().optional()
|
|
1033
|
+
onlyApproved: z13.boolean().optional(),
|
|
1034
|
+
sourceFile: z13.string().optional().describe('Real source file path to export, e.g. "messages/en/home.json" (reliable, preferred).'),
|
|
1035
|
+
keyPrefix: z13.string().optional().describe('Legacy namespace prefix, e.g. "home".')
|
|
998
1036
|
},
|
|
999
1037
|
annotations: { readOnlyHint: true, openWorldHint: true }
|
|
1000
1038
|
},
|
|
@@ -1004,23 +1042,24 @@ function registerTranslationTools(server, gql) {
|
|
|
1004
1042
|
"import_translations",
|
|
1005
1043
|
{
|
|
1006
1044
|
title: "Import translations",
|
|
1007
|
-
description: "Imports ready-made translations for a locale (paste file content). `autoApprove` lands them as APPROVED; `conflict` is OVERWRITE | SKIP_EXISTING | KEEP_APPROVED; `dryRun` previews.",
|
|
1045
|
+
description: "Imports ready-made translations for a locale (paste file content). `autoApprove` lands them as APPROVED; `conflict` is OVERWRITE | SKIP_EXISTING | KEEP_APPROVED; `dryRun` previews. For a multi-file / namespaced project pass `keyPrefix` (the namespace) to match prefixed source keys.",
|
|
1008
1046
|
inputSchema: {
|
|
1009
1047
|
projectId: z13.string(),
|
|
1010
1048
|
localeId: z13.string(),
|
|
1011
1049
|
content: z13.string(),
|
|
1012
1050
|
format: z13.enum(FORMATS2),
|
|
1051
|
+
keyPrefix: z13.string().optional().describe('Namespace prefix, e.g. "home" (per-file, multi-file projects).'),
|
|
1013
1052
|
autoApprove: z13.boolean().default(false),
|
|
1014
1053
|
conflict: z13.enum(["OVERWRITE", "SKIP_EXISTING", "KEEP_APPROVED"]).default("OVERWRITE"),
|
|
1015
1054
|
dryRun: z13.boolean().default(false)
|
|
1016
1055
|
},
|
|
1017
1056
|
annotations: { idempotentHint: true, openWorldHint: true }
|
|
1018
1057
|
},
|
|
1019
|
-
async ({ projectId, localeId, content, format, autoApprove, conflict, dryRun }) => jsonResult(
|
|
1058
|
+
async ({ projectId, localeId, content, format, keyPrefix, autoApprove, conflict, dryRun }) => jsonResult(
|
|
1020
1059
|
(await gql.request(IMPORT_TRANSLATIONS, {
|
|
1021
1060
|
projectId,
|
|
1022
1061
|
localeId,
|
|
1023
|
-
input: { content, format, autoApprove, conflict, dryRun }
|
|
1062
|
+
input: { content, format, keyPrefix, autoApprove, conflict, dryRun }
|
|
1024
1063
|
})).importTranslations
|
|
1025
1064
|
)
|
|
1026
1065
|
);
|
package/dist/index.js
CHANGED