@tiwater/office-mcp 0.8.0 → 0.9.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/office/index.mjs +33 -5
- package/package.json +1 -1
package/office/index.mjs
CHANGED
|
@@ -56,7 +56,6 @@ const migrationChoiceInput = z.object({
|
|
|
56
56
|
sourceChoiceId: z.string().trim().min(1),
|
|
57
57
|
action: migrationAction,
|
|
58
58
|
targetChoiceId: z.string().trim().min(1).optional(),
|
|
59
|
-
cardinality: z.enum(['one', 'all']).optional(),
|
|
60
59
|
}).strict().superRefine((choice, context) => {
|
|
61
60
|
if (targetActions.has(choice.action) && !choice.targetChoiceId) {
|
|
62
61
|
context.addIssue({ code: 'custom', path: ['targetChoiceId'], message: `${choice.action} requires targetChoiceId` });
|
|
@@ -64,9 +63,6 @@ const migrationChoiceInput = z.object({
|
|
|
64
63
|
if (terminalActions.has(choice.action) && choice.targetChoiceId) {
|
|
65
64
|
context.addIssue({ code: 'custom', path: ['targetChoiceId'], message: `${choice.action} forbids targetChoiceId` });
|
|
66
65
|
}
|
|
67
|
-
if (choice.cardinality === 'all' && !terminalActions.has(choice.action)) {
|
|
68
|
-
context.addIssue({ code: 'custom', path: ['cardinality'], message: 'cardinality all is limited to terminal actions' });
|
|
69
|
-
}
|
|
70
66
|
});
|
|
71
67
|
|
|
72
68
|
const templateCleanupInput = z.object({
|
|
@@ -659,6 +655,32 @@ async function docxVerifyMigration(args) {
|
|
|
659
655
|
return runTemplateMigrationCommand('docx_verify_migration', 'verify-template-migration', args);
|
|
660
656
|
}
|
|
661
657
|
|
|
658
|
+
function invalidMigrationInput(message) {
|
|
659
|
+
return Object.assign(new Error(message), { code: -32602 });
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
function completeMigrationChoices(catalog, choices) {
|
|
663
|
+
const sources = new Map(catalog.sources.map(source => [source.id, source]));
|
|
664
|
+
const seen = new Set();
|
|
665
|
+
const completed = choices.map(choice => {
|
|
666
|
+
const source = sources.get(choice.sourceChoiceId);
|
|
667
|
+
if (!source) throw invalidMigrationInput(`unknown migration source id: ${choice.sourceChoiceId}`);
|
|
668
|
+
if (seen.has(choice.sourceChoiceId)) throw invalidMigrationInput(`duplicate migration source id: ${choice.sourceChoiceId}`);
|
|
669
|
+
seen.add(choice.sourceChoiceId);
|
|
670
|
+
if (!source.allowedActions.includes(choice.action)) {
|
|
671
|
+
throw invalidMigrationInput(`migration action ${choice.action} is not allowed for source id: ${choice.sourceChoiceId}`);
|
|
672
|
+
}
|
|
673
|
+
return source.requiredCardinality === 'all'
|
|
674
|
+
? { ...choice, cardinality: 'all' }
|
|
675
|
+
: choice;
|
|
676
|
+
});
|
|
677
|
+
const missing = [...sources.keys()].filter(sourceChoiceId => !seen.has(sourceChoiceId));
|
|
678
|
+
if (missing.length > 0) {
|
|
679
|
+
throw invalidMigrationInput(`migration choices must cover every source id; missing ${missing.length}`);
|
|
680
|
+
}
|
|
681
|
+
return completed;
|
|
682
|
+
}
|
|
683
|
+
|
|
662
684
|
async function runTemplateMigrationCommand(tool, command, args) {
|
|
663
685
|
const source = requireString(args.source, 'source');
|
|
664
686
|
const baseline = requireString(args.baseline, 'baseline');
|
|
@@ -666,9 +688,11 @@ async function runTemplateMigrationCommand(tool, command, args) {
|
|
|
666
688
|
if (!Array.isArray(args.choices)) {
|
|
667
689
|
throw Object.assign(new Error('choices must be an array'), { code: -32602 });
|
|
668
690
|
}
|
|
691
|
+
const catalogResult = await runJsonCandidateChain(docxCandidates, ['list-template-migration-choices', source, baseline]);
|
|
692
|
+
const catalog = migrationCatalog.parse(catalogResult.json);
|
|
669
693
|
const payload = {
|
|
670
694
|
schema: 'tiwater.docx.template-migration-business-choices/v1',
|
|
671
|
-
choices: args.choices,
|
|
695
|
+
choices: completeMigrationChoices(catalog, args.choices),
|
|
672
696
|
...(Array.isArray(args.templateCleanup) ? { templateCleanup: args.templateCleanup } : {}),
|
|
673
697
|
};
|
|
674
698
|
return withTempJsonFile(payload, async choicesPath => {
|
|
@@ -676,6 +700,10 @@ async function runTemplateMigrationCommand(tool, command, args) {
|
|
|
676
700
|
docxCandidates,
|
|
677
701
|
[command, source, baseline, choicesPath, output],
|
|
678
702
|
{ allowedExitCodes: [0, 1] });
|
|
703
|
+
if (result.json === null) {
|
|
704
|
+
const detail = result.stderr.trim() || result.stdout.trim() || 'no diagnostic output';
|
|
705
|
+
throw new Error(`${result.command} ${command} returned no JSON receipt (exit ${result.code}): ${detail}`);
|
|
706
|
+
}
|
|
679
707
|
const receipt = migrationReceipt.parse(result.json);
|
|
680
708
|
return {
|
|
681
709
|
tool,
|