layoutbridge-light 0.0.0-stage → 1.0.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 +105 -0
- package/LICENSE +26 -0
- package/README.de.md +367 -0
- package/README.md +353 -2
- package/THIRD-PARTY-NOTICES.md +2878 -0
- package/dist/src/mcp/catalog.js +131 -0
- package/dist/src/mcp/config.js +211 -0
- package/dist/src/mcp/content-credentials.js +65 -0
- package/dist/src/mcp/dispatch.js +171 -0
- package/dist/src/mcp/epub-check.js +331 -0
- package/dist/src/mcp/epub-orientation.js +132 -0
- package/dist/src/mcp/license/free-tools.js +16 -0
- package/dist/src/mcp/license/gate.js +210 -0
- package/dist/src/mcp/license/index.js +107 -0
- package/dist/src/mcp/license/instance-name.js +57 -0
- package/dist/src/mcp/license/key-source.js +59 -0
- package/dist/src/mcp/license/lemonsqueezy-verifier.js +207 -0
- package/dist/src/mcp/license/placeholder-verifier.js +10 -0
- package/dist/src/mcp/license/polar-ids.js +100 -0
- package/dist/src/mcp/license/polar-verifier.js +285 -0
- package/dist/src/mcp/license/product-ids.js +73 -0
- package/dist/src/mcp/license/state-store.js +91 -0
- package/dist/src/mcp/license/types.js +11 -0
- package/dist/src/mcp/logging.js +271 -0
- package/dist/src/mcp/pdf-postprocess.js +798 -0
- package/dist/src/mcp/product-info.js +54 -0
- package/dist/src/mcp/product.js +56 -0
- package/dist/src/mcp/server.js +253 -0
- package/dist/src/mcp/setup.js +680 -0
- package/dist/src/mcp/start.cjs +117 -0
- package/dist/src/mcp/target-folder.js +25 -0
- package/dist/src/mcp/tool-definition.js +2 -0
- package/dist/src/mcp/tools.js +2680 -0
- package/dist/src/mcp/typography-rules.js +70 -0
- package/dist/src/transport/com.js +436 -0
- package/dist/src/transport/osascript.js +171 -0
- package/dist/src/transport/queue.js +19 -0
- package/dist/src/transport/script-bundle.js +92 -0
- package/dist/src/transport/transport.js +52 -0
- package/indesign/commands/10-app.js +6 -0
- package/indesign/commands/20-documents.js +517 -0
- package/indesign/commands/22-document-setup.js +204 -0
- package/indesign/commands/23-save-package.js +258 -0
- package/indesign/commands/25-export.js +695 -0
- package/indesign/commands/26-export-image.js +202 -0
- package/indesign/commands/27-textdefaults.js +151 -0
- package/indesign/commands/28-selection.js +174 -0
- package/indesign/commands/30-pages.js +1032 -0
- package/indesign/commands/31-view.js +310 -0
- package/indesign/commands/32-sections.js +203 -0
- package/indesign/commands/35-parents.js +448 -0
- package/indesign/commands/37-layout.js +837 -0
- package/indesign/commands/40-frames.js +886 -0
- package/indesign/commands/41-shapes.js +505 -0
- package/indesign/commands/42-groups.js +117 -0
- package/indesign/commands/43-layers.js +310 -0
- package/indesign/commands/44-effects.js +274 -0
- package/indesign/commands/45-frame-options.js +247 -0
- package/indesign/commands/47-anchored.js +473 -0
- package/indesign/commands/50-modify.js +803 -0
- package/indesign/commands/52-align.js +139 -0
- package/indesign/commands/55-fit.js +106 -0
- package/indesign/commands/60-images.js +1154 -0
- package/indesign/commands/62-embed.js +120 -0
- package/indesign/commands/69-placeholders.js +132 -0
- package/indesign/commands/70-text.js +710 -0
- package/indesign/commands/71-outlines.js +92 -0
- package/indesign/commands/72-place-text.js +476 -0
- package/indesign/commands/73-story-lock.js +157 -0
- package/indesign/commands/74-stories.js +121 -0
- package/indesign/commands/75-tables.js +702 -0
- package/indesign/commands/76-text-variables.js +260 -0
- package/indesign/commands/77-story-options.js +86 -0
- package/indesign/commands/78-frame-lines.js +511 -0
- package/indesign/commands/79-check-typography.js +480 -0
- package/indesign/commands/80-styles.js +1960 -0
- package/indesign/commands/81-composition.js +355 -0
- package/indesign/commands/82-object-styles.js +263 -0
- package/indesign/commands/83-drop-caps.js +87 -0
- package/indesign/commands/83-indents-tabs.js +264 -0
- package/indesign/commands/84-import-styles.js +142 -0
- package/indesign/commands/85-swatches.js +112 -0
- package/indesign/commands/86-gradients.js +185 -0
- package/indesign/commands/87-replace-swatch.js +180 -0
- package/indesign/commands/88-replace-font.js +212 -0
- package/indesign/commands/89-toc-index.js +1002 -0
- package/indesign/commands/90-print-on-demand.js +495 -0
- package/indesign/commands/91-epub.js +629 -0
- package/indesign/commands/92-accessibility.js +1131 -0
- package/indesign/interpreter.js +829 -0
- package/package.json +41 -4
- package/rules/typography-rules.json +32 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Feste Produktangaben, die in Meldungen und Protokoll erscheinen (Auftraege
|
|
3
|
+
* A-10 Nr. 1 und A-11 Nr. 1/3 des Vermarktungsprojekts, 17.09.2026; E-72).
|
|
4
|
+
*
|
|
5
|
+
* Die Adressen sind vom Vermarktungsprojekt festgelegt und aendern sich
|
|
6
|
+
* nicht mehr; die englische Fassung ist massgeblich fuer Verzeichnisse, die
|
|
7
|
+
* deutsche fuer Kunden. Keine Hauswerte, keine Umgebungsnamen – nur das,
|
|
8
|
+
* was jeder Kunde des Produkts sehen soll.
|
|
9
|
+
*/
|
|
10
|
+
import { PRODUCT } from './product.js';
|
|
11
|
+
/**
|
|
12
|
+
* Seit A-70 (E-109) haengen die Adressen am Produktprofil: das Vollprodukt
|
|
13
|
+
* unter /layoutbridge/ (unveraendert), LayoutBridge Light unter
|
|
14
|
+
* /layoutbridge-light/ mit denselben Dateinamen.
|
|
15
|
+
*/
|
|
16
|
+
/** Support-Eingang (A-10 Nr. 1; seit A-12 Nr. 1 unter dem Dach MCP Interfaces, E-75). Erscheint im Klartext in jeder Meldung der Fehlerart `license`. */
|
|
17
|
+
export const SUPPORT_EMAIL = 'kontakt@mcp-interfaces.com';
|
|
18
|
+
/** Lizenzbedingungen (EULA), englisch (massgeblich fuer Verzeichnisse) und deutsch. */
|
|
19
|
+
export const LICENSE_TERMS_URL = 'https://mcp-interfaces.com/' + PRODUCT.pagePath + '/license.html';
|
|
20
|
+
export const LICENSE_TERMS_URL_DE = 'https://mcp-schnittstellen.de/' + PRODUCT.pagePath + '/lizenzbedingungen.html';
|
|
21
|
+
/** Datenschutzerklaerung des Produkts, englisch und deutsch; dazu die des Zahlungsdienstes. */
|
|
22
|
+
export const PRIVACY_POLICY_URL = 'https://mcp-interfaces.com/' + PRODUCT.pagePath + '/privacy.html';
|
|
23
|
+
export const PRIVACY_POLICY_URL_DE = 'https://mcp-schnittstellen.de/' + PRODUCT.pagePath + '/datenschutz.html';
|
|
24
|
+
/**
|
|
25
|
+
* Datenschutzerklaerung je Zahlungsdienst (A-15 Nr. 5, 23.09.2026). Zum
|
|
26
|
+
* Verkaufsstart gilt Polar (A-15a); lemonsqueezy bleibt als Rueckfall der
|
|
27
|
+
* Bauphase, ausgegeben wird der Eintrag des gewaehlten Dienstes.
|
|
28
|
+
*/
|
|
29
|
+
export const PAYMENT_PRIVACY_POLICY_URLS = {
|
|
30
|
+
lemonsqueezy: 'https://www.lemonsqueezy.com/privacy',
|
|
31
|
+
polar: 'https://polar.sh/legal/privacy',
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Der Eintrag des vorgegebenen Dienstes (polar seit A-15a Nr. 2; muss zu
|
|
35
|
+
* DEFAULT_LICENSE_PROVIDER in license/index.ts passen, ein Test wacht
|
|
36
|
+
* darueber). Steht in manifest.json und in der README.
|
|
37
|
+
*/
|
|
38
|
+
export const PAYMENT_PRIVACY_POLICY_URL = PAYMENT_PRIVACY_POLICY_URLS['polar'];
|
|
39
|
+
/** Datenschutzerklaerung eines bestimmten Dienstes; unbekannt = Vorgabe. */
|
|
40
|
+
export function paymentPrivacyPolicyUrlFor(provider) {
|
|
41
|
+
return PAYMENT_PRIVACY_POLICY_URLS[provider] ?? PAYMENT_PRIVACY_POLICY_URL;
|
|
42
|
+
}
|
|
43
|
+
/** Produktseite. */
|
|
44
|
+
export const PRODUCT_PAGE_URL = 'https://mcp-interfaces.com/' + PRODUCT.pagePath + '/';
|
|
45
|
+
export const PRODUCT_PAGE_URL_DE = 'https://mcp-schnittstellen.de/' + PRODUCT.pagePath + '/';
|
|
46
|
+
/** Haengt den Support-Hinweis an eine Meldung, sofern die Adresse nicht schon darin steht. */
|
|
47
|
+
export function withSupportHint(message) {
|
|
48
|
+
if (message.includes(SUPPORT_EMAIL))
|
|
49
|
+
return message;
|
|
50
|
+
const trimmed = message.trimEnd();
|
|
51
|
+
const separator = /[.!?]$/.test(trimmed) ? ' ' : '. ';
|
|
52
|
+
return trimmed + separator + 'Support: ' + SUPPORT_EMAIL;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=product-info.js.map
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Produktprofil (A-70, Vermerk E-109, 30.10.2026).
|
|
3
|
+
*
|
|
4
|
+
* Aus derselben Codebasis entstehen zwei Produkte: das Vollprodukt
|
|
5
|
+
* `layoutbridge-spm` (alle Werkzeuge) und **LayoutBridge Light**
|
|
6
|
+
* (`layoutbridge-light`, Buchsatz, eine feste Teilmenge der Werkzeuge).
|
|
7
|
+
* Welches Produkt laeuft, bestimmt allein der Name in der package.json des
|
|
8
|
+
* ausgelieferten Pakets – das Light-Paket wird von scripts/light-package.mjs
|
|
9
|
+
* mit eigenem Namen gebaut. Es gibt keinen Schalter fuer Kunden: weder
|
|
10
|
+
* config.json noch eine Umgebungsvariable waehlen das Produkt.
|
|
11
|
+
*
|
|
12
|
+
* Das Profil des Vollprodukts gibt exakt die bisherigen Werte wieder
|
|
13
|
+
* (Namen, Ordner, Umgebungsvariablen, Adressen); fuer das Vollprodukt aendert
|
|
14
|
+
* sich nichts (E-79).
|
|
15
|
+
*/
|
|
16
|
+
import { readFileSync } from 'node:fs';
|
|
17
|
+
import { dirname, join } from 'node:path';
|
|
18
|
+
import { fileURLToPath } from 'node:url';
|
|
19
|
+
export const FULL_PRODUCT = {
|
|
20
|
+
id: 'full',
|
|
21
|
+
packageName: 'layoutbridge-spm',
|
|
22
|
+
displayName: 'LayoutBridge for Adobe InDesign®',
|
|
23
|
+
dataDirName: 'layoutbridge-spm',
|
|
24
|
+
envPrefix: 'LAYOUTBRIDGE_SPM',
|
|
25
|
+
pagePath: 'layoutbridge',
|
|
26
|
+
};
|
|
27
|
+
export const LIGHT_PRODUCT = {
|
|
28
|
+
id: 'light',
|
|
29
|
+
packageName: 'layoutbridge-light',
|
|
30
|
+
displayName: 'LayoutBridge Light for Adobe InDesign®',
|
|
31
|
+
dataDirName: 'layoutbridge-light',
|
|
32
|
+
envPrefix: 'LAYOUTBRIDGE_LIGHT',
|
|
33
|
+
pagePath: 'layoutbridge-light',
|
|
34
|
+
};
|
|
35
|
+
export const PRODUCTS = [FULL_PRODUCT, LIGHT_PRODUCT];
|
|
36
|
+
/** Profil zu einem Paketnamen; alles Unbekannte ist das Vollprodukt (Entwicklung im Repo). */
|
|
37
|
+
export function productForPackageName(name) {
|
|
38
|
+
return name === LIGHT_PRODUCT.packageName ? LIGHT_PRODUCT : FULL_PRODUCT;
|
|
39
|
+
}
|
|
40
|
+
function readPackageName() {
|
|
41
|
+
try {
|
|
42
|
+
const packageJson = join(dirname(fileURLToPath(import.meta.url)), '..', '..', '..', 'package.json');
|
|
43
|
+
const parsed = JSON.parse(readFileSync(packageJson, 'utf8'));
|
|
44
|
+
return parsed.name;
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/** Das Produkt dieses Pakets – einmal beim Laden bestimmt. */
|
|
51
|
+
export const PRODUCT = productForPackageName(readPackageName());
|
|
52
|
+
/** Name einer Umgebungsvariablen dieses Produkts, z. B. envName('LICENSE_KEY'). */
|
|
53
|
+
export function envName(suffix, product = PRODUCT) {
|
|
54
|
+
return product.envPrefix + '_' + suffix;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=product.js.map
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* layoutbridge-spm – MCP-Server für Adobe InDesign (bis 04.09.2026: indesign-connector-spm).
|
|
4
|
+
*
|
|
5
|
+
* Startet den Server ueber die Standardein-/-ausgabe (stdio) und meldet die
|
|
6
|
+
* Werkzeuge aus tools.ts an. Aufrufe laufen sequenziell (SerialTransport).
|
|
7
|
+
*/
|
|
8
|
+
import { readFileSync } from 'node:fs';
|
|
9
|
+
import { homedir } from 'node:os';
|
|
10
|
+
import { dirname, join } from 'node:path';
|
|
11
|
+
import { fileURLToPath } from 'node:url';
|
|
12
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
13
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
14
|
+
import { loadServerConfig } from './config.js';
|
|
15
|
+
import { CallLogger } from './logging.js';
|
|
16
|
+
import { maskErrorPaths, runTool } from './dispatch.js';
|
|
17
|
+
import { createLicenseGate, runDeactivation } from './license/index.js';
|
|
18
|
+
import { LICENSE_TERMS_URL, LICENSE_TERMS_URL_DE, SUPPORT_EMAIL } from './product-info.js';
|
|
19
|
+
import { createTerminalIo, runSetup } from './setup.js';
|
|
20
|
+
import { CATALOG } from './catalog.js';
|
|
21
|
+
import { PRODUCT } from './product.js';
|
|
22
|
+
import { nodeVersionProblem } from './start.cjs';
|
|
23
|
+
import { ComTransport } from '../transport/com.js';
|
|
24
|
+
import { OsascriptTransport } from '../transport/osascript.js';
|
|
25
|
+
import { SerialTransport } from '../transport/queue.js';
|
|
26
|
+
/** Servername = npm-Paket des Produkts (A-70, E-109; Vollprodukt unveraendert layoutbridge-spm). */
|
|
27
|
+
export const SERVER_NAME = PRODUCT.packageName;
|
|
28
|
+
/**
|
|
29
|
+
* Version aus package.json – eine Quelle fuer Paket, Server, server.json und
|
|
30
|
+
* manifest.json (A-11 Nr. 6; scripts/version-sync.mjs zieht die beiden
|
|
31
|
+
* Dateien nach). Faellt auf 0.0.0 zurueck, wenn package.json nicht lesbar ist.
|
|
32
|
+
*/
|
|
33
|
+
export const SERVER_VERSION = readPackageVersion();
|
|
34
|
+
function readPackageVersion() {
|
|
35
|
+
try {
|
|
36
|
+
const packageJson = join(dirname(fileURLToPath(import.meta.url)), '..', '..', '..', 'package.json');
|
|
37
|
+
const parsed = JSON.parse(readFileSync(packageJson, 'utf8'));
|
|
38
|
+
return typeof parsed.version === 'string' ? parsed.version : '0.0.0';
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
return '0.0.0';
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Haelt fest, ob noch ein Aufruf laeuft. Der Server darf sich erst beenden,
|
|
46
|
+
* wenn die Eingabe zu Ende ist UND keine Antwort mehr aussteht – sonst bricht
|
|
47
|
+
* er einen laufenden InDesign-Aufruf mitten im Satz ab.
|
|
48
|
+
*/
|
|
49
|
+
export class Lifecycle {
|
|
50
|
+
onIdle;
|
|
51
|
+
inFlight = 0;
|
|
52
|
+
inputEnded = false;
|
|
53
|
+
stopping = false;
|
|
54
|
+
constructor(onIdle) {
|
|
55
|
+
this.onIdle = onIdle;
|
|
56
|
+
}
|
|
57
|
+
begin() {
|
|
58
|
+
this.inFlight += 1;
|
|
59
|
+
}
|
|
60
|
+
end() {
|
|
61
|
+
this.inFlight = Math.max(0, this.inFlight - 1);
|
|
62
|
+
this.check();
|
|
63
|
+
}
|
|
64
|
+
inputIsOver() {
|
|
65
|
+
this.inputEnded = true;
|
|
66
|
+
this.check();
|
|
67
|
+
}
|
|
68
|
+
get busy() {
|
|
69
|
+
return this.inFlight > 0;
|
|
70
|
+
}
|
|
71
|
+
check() {
|
|
72
|
+
if (this.inputEnded && this.inFlight === 0 && !this.stopping) {
|
|
73
|
+
this.stopping = true;
|
|
74
|
+
this.onIdle();
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
export function createServer(transport, logger, lifecycle, config = {}, gate) {
|
|
79
|
+
const server = new McpServer({ name: SERVER_NAME, version: SERVER_VERSION });
|
|
80
|
+
for (const definition of CATALOG) {
|
|
81
|
+
server.registerTool(definition.name, {
|
|
82
|
+
title: definition.title,
|
|
83
|
+
description: definition.description,
|
|
84
|
+
inputSchema: definition.inputShape,
|
|
85
|
+
annotations: {
|
|
86
|
+
title: definition.title,
|
|
87
|
+
readOnlyHint: definition.readOnly,
|
|
88
|
+
destructiveHint: definition.destructive === true,
|
|
89
|
+
idempotentHint: definition.readOnly,
|
|
90
|
+
openWorldHint: false,
|
|
91
|
+
},
|
|
92
|
+
}, async (input) => {
|
|
93
|
+
lifecycle?.begin();
|
|
94
|
+
try {
|
|
95
|
+
/* Lizenzschranke (E-60): vor dem Transport, InDesign bleibt unberuehrt. */
|
|
96
|
+
let graceWarning = null;
|
|
97
|
+
if (gate !== undefined) {
|
|
98
|
+
const decision = await gate.decide(definition.name, definition.readOnly);
|
|
99
|
+
if (!decision.allowed) {
|
|
100
|
+
/* Wie jede Fehlerantwort ohne Benutzerverzeichnis (E-68, Befund 1 aus Sitzung 33). */
|
|
101
|
+
const refused = maskErrorPaths(gate.toError(decision));
|
|
102
|
+
logger.log({
|
|
103
|
+
tool: definition.name,
|
|
104
|
+
command: definition.command,
|
|
105
|
+
args: {},
|
|
106
|
+
duration_ms: 0,
|
|
107
|
+
ok: false,
|
|
108
|
+
error_kind: 'license',
|
|
109
|
+
error_message: refused.error?.message ?? '',
|
|
110
|
+
warnings: [],
|
|
111
|
+
result_keys: [],
|
|
112
|
+
});
|
|
113
|
+
return {
|
|
114
|
+
content: [{ type: 'text', text: JSON.stringify(refused, null, 2) }],
|
|
115
|
+
isError: true,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
graceWarning = decision.message;
|
|
119
|
+
}
|
|
120
|
+
let result = await runTool(definition, input, transport, logger, {
|
|
121
|
+
timeoutMs: definition.timeoutMs,
|
|
122
|
+
config,
|
|
123
|
+
});
|
|
124
|
+
if (graceWarning !== null) {
|
|
125
|
+
const warnings = Array.isArray(result.warnings) ? result.warnings : [];
|
|
126
|
+
result = { ...result, warnings: [...warnings, graceWarning] };
|
|
127
|
+
}
|
|
128
|
+
return {
|
|
129
|
+
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
|
|
130
|
+
isError: result.ok !== true,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
finally {
|
|
134
|
+
lifecycle?.end();
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
return server;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Startet den Server ueber die Standardein-/-ausgabe und kuemmert sich um ein
|
|
142
|
+
* sauberes Ende: Ende der Eingabe merken, aber erst aufhoeren, wenn die letzte
|
|
143
|
+
* Antwort geschrieben ist.
|
|
144
|
+
*/
|
|
145
|
+
export async function startStdioServer(transport, logger, config = {}, gate) {
|
|
146
|
+
let stopping = false;
|
|
147
|
+
const stop = (code) => {
|
|
148
|
+
if (stopping)
|
|
149
|
+
return;
|
|
150
|
+
stopping = true;
|
|
151
|
+
void transport.close().finally(() => {
|
|
152
|
+
/* Erst schreiben lassen, dann gehen. */
|
|
153
|
+
process.stdout.write('', () => process.exit(code));
|
|
154
|
+
});
|
|
155
|
+
};
|
|
156
|
+
const lifecycle = new Lifecycle(() => stop(0));
|
|
157
|
+
const server = createServer(transport, logger, lifecycle, config, gate);
|
|
158
|
+
process.stdin.on('end', () => lifecycle.inputIsOver());
|
|
159
|
+
process.stdin.on('close', () => lifecycle.inputIsOver());
|
|
160
|
+
server.server.onclose = () => lifecycle.inputIsOver();
|
|
161
|
+
process.on('SIGINT', () => stop(0));
|
|
162
|
+
process.on('SIGTERM', () => stop(0));
|
|
163
|
+
await server.connect(new StdioServerTransport());
|
|
164
|
+
return server;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Rechnerwechsel (A-6 Ergaenzung Nr. 7): `layoutbridge-spm --deactivate`
|
|
168
|
+
* gibt die Aktivierung dieses Arbeitsplatzes beim Dienst frei. Laeuft ohne
|
|
169
|
+
* InDesign und ohne Client; kein Werkzeug im Katalog (A-5).
|
|
170
|
+
*/
|
|
171
|
+
async function deactivateFromCommandLine() {
|
|
172
|
+
const result = await runDeactivation();
|
|
173
|
+
process.stderr.write(`[${SERVER_NAME}] ${result.message}\n`);
|
|
174
|
+
process.exit(result.ok ? 0 : 1);
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Einrichtung (A-13 Nr. 1, E-76): `layoutbridge-spm --setup` traegt den
|
|
178
|
+
* Server in Claude Desktop ein und legt den Lizenzschluessel ab. Nur auf
|
|
179
|
+
* ausdrueckliche Eingabe, kein Werkzeug im Katalog (A-5); laeuft vor
|
|
180
|
+
* Protokoll, Transport und Lizenzschranke, also ohne Netz und ohne InDesign.
|
|
181
|
+
*/
|
|
182
|
+
async function setupFromCommandLine() {
|
|
183
|
+
const code = await runSetup(process.argv.slice(2), createTerminalIo(), {
|
|
184
|
+
platform: process.platform,
|
|
185
|
+
home: homedir(),
|
|
186
|
+
env: process.env,
|
|
187
|
+
now: new Date(),
|
|
188
|
+
nodeVersion: process.version,
|
|
189
|
+
});
|
|
190
|
+
process.exit(code);
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Transport nach Plattform. Die einzige Stelle im Server, die zwischen den
|
|
194
|
+
* Wegen unterscheidet; alles darueber kennt nur die Schnittstelle.
|
|
195
|
+
* Der Windows-Weg ist gebaut, aber noch nicht an einem laufenden InDesign
|
|
196
|
+
* nachgewiesen (Vermerk E-67).
|
|
197
|
+
*/
|
|
198
|
+
function createPlatformTransport() {
|
|
199
|
+
return process.platform === 'win32' ? new ComTransport({ dataDirName: PRODUCT.dataDirName }) : new OsascriptTransport();
|
|
200
|
+
}
|
|
201
|
+
/** Eine Zeile mit Lizenzbedingungen und Support-Adresse fuer Startmeldung und Protokoll. */
|
|
202
|
+
export function describeProductTerms() {
|
|
203
|
+
return `licence terms: ${LICENSE_TERMS_URL} (de: ${LICENSE_TERMS_URL_DE}), support: ${SUPPORT_EMAIL}`;
|
|
204
|
+
}
|
|
205
|
+
async function main() {
|
|
206
|
+
if (process.argv.includes('--setup')) {
|
|
207
|
+
await setupFromCommandLine();
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
if (process.argv.includes('--deactivate')) {
|
|
211
|
+
await deactivateFromCommandLine();
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
const logger = new CallLogger();
|
|
215
|
+
const transport = new SerialTransport(createPlatformTransport());
|
|
216
|
+
const loaded = loadServerConfig();
|
|
217
|
+
const gate = createLicenseGate({ product: SERVER_NAME, version: SERVER_VERSION });
|
|
218
|
+
process.stderr.write(`[${SERVER_NAME}] ${SERVER_VERSION} started, ${CATALOG.length} tools, transport: ${transport.name}, log: ${logger.file} (level ${logger.level}${logger.removedLogs.length > 0 ? `, ${logger.removedLogs.length} old log file(s) removed` : ''}), config: ${loaded.path ?? 'none'}\n`);
|
|
219
|
+
if (logger.level === 'full') {
|
|
220
|
+
process.stderr.write(`[${SERVER_NAME}] log level "full": tool arguments are written unfiltered, including document text and paths with your user name.\n`);
|
|
221
|
+
}
|
|
222
|
+
for (const problem of loaded.problems) {
|
|
223
|
+
process.stderr.write(`[${SERVER_NAME}] config: ${problem}\n`);
|
|
224
|
+
}
|
|
225
|
+
process.stderr.write(`[${SERVER_NAME}] ${gate.describe()}\n`);
|
|
226
|
+
/* Lizenzbedingungen und Support in der Startzeile (A-11 Nr. 3, A-10 Nr. 1). */
|
|
227
|
+
process.stderr.write(`[${SERVER_NAME}] ${describeProductTerms()}\n`);
|
|
228
|
+
await startStdioServer(transport, logger, loaded.config, gate);
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Einstieg fuer die Kommandozeile. Aufgerufen von der Startdatei `start.cjs`
|
|
232
|
+
* (bin, MCPB-Bundle; prueft vorher die Node-Version, E-74) und beim direkten
|
|
233
|
+
* Start `node dist/src/mcp/server.js` (Handeintrag, bestehende Konfigurationen).
|
|
234
|
+
*/
|
|
235
|
+
export function runCli() {
|
|
236
|
+
/* Beim direkten Start von server.js hat keine Startdatei geprueft. Laufen die
|
|
237
|
+
Imports unter Node 18/19 noch durch, soll die Meldung trotzdem die richtige
|
|
238
|
+
Ursache nennen (E-74). */
|
|
239
|
+
const problem = nodeVersionProblem(process.version);
|
|
240
|
+
if (problem !== null) {
|
|
241
|
+
process.stderr.write(problem);
|
|
242
|
+
process.exit(1);
|
|
243
|
+
}
|
|
244
|
+
main().catch((error) => {
|
|
245
|
+
process.stderr.write(`[${SERVER_NAME}] fatal: ${String(error)}\n`);
|
|
246
|
+
process.exit(1);
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
const isEntryPoint = process.argv[1] !== undefined && process.argv[1].endsWith('server.js');
|
|
250
|
+
if (isEntryPoint) {
|
|
251
|
+
runCli();
|
|
252
|
+
}
|
|
253
|
+
//# sourceMappingURL=server.js.map
|