mn-docs-mcp 0.2.1 → 0.2.3

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/mcp/cli.mjs CHANGED
@@ -11,6 +11,7 @@ let port;
11
11
  let prebuild = false;
12
12
  let silent = false;
13
13
  let root;
14
+ let resolvedRoot;
14
15
 
15
16
  for (let i = 0; i < args.length; i += 1) {
16
17
  const arg = args[i];
@@ -78,12 +79,27 @@ try {
78
79
  version = JSON.parse(raw).version || version;
79
80
  } catch {}
80
81
 
82
+ function hasDocsDir(base) {
83
+ try {
84
+ const docsPath = path.join(base, 'src', 'content', 'docs');
85
+ return fs.existsSync(docsPath);
86
+ } catch {
87
+ return false;
88
+ }
89
+ }
90
+
91
+ if (root) {
92
+ resolvedRoot = root;
93
+ } else if (hasDocsDir(process.cwd())) {
94
+ resolvedRoot = process.cwd();
95
+ }
96
+
81
97
  if (mode === 'stdio') {
82
98
  process.env.MCP_STDIO = '1';
83
99
  process.env.MCP_SILENT = silent ? '1' : '0';
84
100
  process.env.MN_DOCS_VERSION = version;
85
101
  process.env.MN_DOCS_MODE = 'stdio';
86
- process.env.MN_DOCS_ROOT = root || process.env.MN_DOCS_ROOT || process.cwd();
102
+ if (resolvedRoot) process.env.MN_DOCS_ROOT = resolvedRoot;
87
103
  if (prebuild) process.env.MCP_PREBUILD = '1';
88
104
  await import('./server.mjs');
89
105
  } else {
@@ -91,7 +107,7 @@ if (mode === 'stdio') {
91
107
  process.env.MN_DOCS_VERSION = version;
92
108
  process.env.MN_DOCS_MODE = 'http';
93
109
  if (port) process.env.MN_DOCS_PORT = String(port);
94
- process.env.MN_DOCS_ROOT = root || process.env.MN_DOCS_ROOT || process.cwd();
110
+ if (resolvedRoot) process.env.MN_DOCS_ROOT = resolvedRoot;
95
111
  if (prebuild) process.env.MCP_PREBUILD = '1';
96
112
  await import('./server-http.mjs');
97
113
  }
package/mcp/lib.mjs CHANGED
@@ -14,7 +14,7 @@ const DEFAULT_ROOT = path.resolve(__dirname, '..');
14
14
 
15
15
  function resolveRootDir() {
16
16
  const envRoot = (process.env.MN_DOCS_ROOT || '').trim();
17
- if (envRoot) return envRoot;
17
+ if (envRoot && fsSyncExists(path.join(envRoot, 'src', 'content', 'docs'))) return envRoot;
18
18
  const cwd = process.cwd();
19
19
  const docsFromCwd = path.join(cwd, 'src', 'content', 'docs');
20
20
  try {
@@ -16,8 +16,29 @@ function stripAnsi(text) {
16
16
  return text.replace(/\x1b\[[0-9;]*m/g, '');
17
17
  }
18
18
 
19
+ function stringWidth(text) {
20
+ const plain = stripAnsi(text);
21
+ let width = 0;
22
+ for (const char of plain) {
23
+ const code = char.codePointAt(0);
24
+ if (!code) continue;
25
+ const isWide =
26
+ (code >= 0x1100 && code <= 0x115f) ||
27
+ (code === 0x2329 || code === 0x232a) ||
28
+ (code >= 0x2e80 && code <= 0xa4cf) ||
29
+ (code >= 0xac00 && code <= 0xd7a3) ||
30
+ (code >= 0xf900 && code <= 0xfaff) ||
31
+ (code >= 0xfe10 && code <= 0xfe19) ||
32
+ (code >= 0xfe30 && code <= 0xfe6f) ||
33
+ (code >= 0xff00 && code <= 0xff60) ||
34
+ (code >= 0xffe0 && code <= 0xffe6);
35
+ width += isWide ? 2 : 1;
36
+ }
37
+ return width;
38
+ }
39
+
19
40
  function padLine(line, width) {
20
- const len = stripAnsi(line).length;
41
+ const len = stringWidth(line);
21
42
  const padding = width - len;
22
43
  return line + (padding > 0 ? ' '.repeat(padding) : '');
23
44
  }
@@ -31,7 +52,7 @@ function renderSplash() {
31
52
  color(`mn-docs-mcp v${version}`, '38;5;45'),
32
53
  color(`模式: ${mode} 端口: ${port}`, '38;5;39'),
33
54
  ];
34
- const maxWidth = Math.max(...contentLines.map((line) => stripAnsi(line).length)) + 4;
55
+ const maxWidth = Math.max(...contentLines.map((line) => stringWidth(line))) + 4;
35
56
  const top = color('╭' + '─'.repeat(maxWidth) + '╮', '38;5;45');
36
57
  const bottom = color('╰' + '─'.repeat(maxWidth) + '╯', '38;5;45');
37
58
  const body = contentLines.map((line) => {
package/mcp/server.mjs CHANGED
@@ -20,8 +20,30 @@ function stripAnsi(text) {
20
20
  return text.replace(/\x1b\[[0-9;]*m/g, '');
21
21
  }
22
22
 
23
+ function stringWidth(text) {
24
+ const plain = stripAnsi(text);
25
+ let width = 0;
26
+ for (const char of plain) {
27
+ const code = char.codePointAt(0);
28
+ if (!code) continue;
29
+ // CJK / Fullwidth / Wide characters
30
+ const isWide =
31
+ (code >= 0x1100 && code <= 0x115f) ||
32
+ (code === 0x2329 || code === 0x232a) ||
33
+ (code >= 0x2e80 && code <= 0xa4cf) ||
34
+ (code >= 0xac00 && code <= 0xd7a3) ||
35
+ (code >= 0xf900 && code <= 0xfaff) ||
36
+ (code >= 0xfe10 && code <= 0xfe19) ||
37
+ (code >= 0xfe30 && code <= 0xfe6f) ||
38
+ (code >= 0xff00 && code <= 0xff60) ||
39
+ (code >= 0xffe0 && code <= 0xffe6);
40
+ width += isWide ? 2 : 1;
41
+ }
42
+ return width;
43
+ }
44
+
23
45
  function padLine(line, width) {
24
- const len = stripAnsi(line).length;
46
+ const len = stringWidth(line);
25
47
  const padding = width - len;
26
48
  return line + (padding > 0 ? ' '.repeat(padding) : '');
27
49
  }
@@ -34,7 +56,7 @@ function renderSplash() {
34
56
  color(`mn-docs-mcp v${version}`, '38;5;45'),
35
57
  color(`模式: ${mode}`, '38;5;39'),
36
58
  ];
37
- const maxWidth = Math.max(...contentLines.map((line) => stripAnsi(line).length)) + 4;
59
+ const maxWidth = Math.max(...contentLines.map((line) => stringWidth(line))) + 4;
38
60
  const top = color('╭' + '─'.repeat(maxWidth) + '╮', '38;5;45');
39
61
  const bottom = color('╰' + '─'.repeat(maxWidth) + '╯', '38;5;45');
40
62
  const body = contentLines.map((line) => {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mn-docs-mcp",
3
3
  "type": "module",
4
- "version": "0.2.1",
4
+ "version": "0.2.3",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "https://github.com/Temsys-Shen/marginnote-addon-docs.git"