@kakedashi/md-to-article-mcp 1.0.2 → 1.0.5

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/clipboard.js CHANGED
@@ -15,14 +15,27 @@ function copyHtmlToClipboard(html) {
15
15
  }
16
16
  }
17
17
  function copyHtmlMacOS(html) {
18
+ // HTML バイト列を hex に変換して AppleScript リテラルとして埋め込む。
19
+ // hex は [0-9A-F] のみで構成されるためインジェクション不可。
18
20
  const hex = Buffer.from(html, "utf-8").toString("hex").toUpperCase();
19
21
  const script = `set the clipboard to «data HTML${hex}»`;
20
- (0, child_process_1.execSync)(`osascript -e '${script.replace(/'/g, "'\"'\"'")}'`);
22
+ // osascript に配列で渡すことでシェル展開を経由しない。
23
+ const result = (0, child_process_1.spawnSync)("osascript", ["-e", script]);
24
+ if (result.status !== 0) {
25
+ throw new Error(result.stderr?.toString() ?? "osascript failed");
26
+ }
21
27
  }
22
28
  function copyHtmlWindows(html) {
23
- const escaped = html.replace(/"/g, '\\"');
24
- (0, child_process_1.execSync)(`powershell -Command "Set-Clipboard -Value \\"${escaped}\\" -AsHtml"`, { shell: "powershell.exe" });
29
+ // PowerShell HTML を stdin 経由で渡し、コマンド文字列への展開を避ける。
30
+ const result = (0, child_process_1.spawnSync)("powershell", ["-NoProfile", "-Command", "$input | Set-Clipboard -AsHtml"], { input: html, encoding: "utf-8", shell: false });
31
+ if (result.status !== 0) {
32
+ throw new Error(result.stderr?.toString() ?? "Set-Clipboard failed");
33
+ }
25
34
  }
26
35
  function copyHtmlLinux(html) {
27
- (0, child_process_1.execSync)(`echo ${JSON.stringify(html)} | xclip -selection clipboard -t text/html`);
36
+ // xclip HTML stdin 経由で渡す。シェルを介さないので展開なし。
37
+ const result = (0, child_process_1.spawnSync)("xclip", ["-selection", "clipboard", "-t", "text/html"], { input: html, encoding: "utf-8", shell: false });
38
+ if (result.status !== 0) {
39
+ throw new Error(result.stderr?.toString() ?? "xclip failed");
40
+ }
28
41
  }
package/dist/converter.js CHANGED
@@ -8,9 +8,10 @@ function convertMarkdownToHtml(markdown) {
8
8
  renderer.image = (href, title, text) => {
9
9
  return text ? text : "";
10
10
  };
11
- // pre/code ブロックはプレーンテキストにフォールバック
12
- renderer.code = (code, _language) => {
13
- return `<pre>${escapeHtml(code)}</pre>`;
11
+ // pre/code ブロックを language クラス付きで出力
12
+ renderer.code = (code, language) => {
13
+ const cls = language ? ` class="language-${escapeHtml(language)}"` : "";
14
+ return `<pre><code${cls}>${escapeHtml(code)}</code></pre>`;
14
15
  };
15
16
  renderer.codespan = (code) => {
16
17
  return `<code>${escapeHtml(code)}</code>`;
package/dist/index.js CHANGED
@@ -136,6 +136,19 @@ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
136
136
  };
137
137
  });
138
138
  async function main() {
139
+ const filepath = process.argv[2];
140
+ if (filepath) {
141
+ const resolvedPath = path.resolve(filepath.replace(/^~/, os_1.default.homedir()));
142
+ if (path.extname(resolvedPath) !== ".md") {
143
+ console.error(`ファイルの拡張子が .md ではありません: ${filepath}`);
144
+ process.exit(1);
145
+ }
146
+ const markdown = fs.readFileSync(resolvedPath, "utf-8");
147
+ const html = (0, converter_js_1.convertMarkdownToHtml)(markdown);
148
+ (0, clipboard_js_1.copyHtmlToClipboard)(html);
149
+ console.log(`コピーしました: ${filepath}`);
150
+ process.exit(0);
151
+ }
139
152
  const transport = new stdio_js_1.StdioServerTransport();
140
153
  await server.connect(transport);
141
154
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kakedashi/md-to-article-mcp",
3
- "version": "1.0.2",
3
+ "version": "1.0.5",
4
4
  "description": "MCP tool to convert Markdown files to rich text and copy to clipboard for X Article editor",
5
5
  "main": "dist/index.js",
6
6
  "bin": {