katana-markdown-linter 0.19.2 → 0.19.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/README.md +28 -11
- package/bin/katana-markdown-linter.js +4 -0
- package/bin/kml-mcp-remote.js +4 -0
- package/bin/kml-mcp.js +4 -0
- package/bin/kml.js +2 -11
- package/lib/installer.js +29 -4
- package/lib/launcher.js +30 -0
- package/package.json +8 -3
package/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# katana-markdown-linter
|
|
2
2
|
|
|
3
|
-
`katana-markdown-linter` is a thin
|
|
4
|
-
The package does not contain independent lint
|
|
5
|
-
|
|
6
|
-
SHA-256 checksum, installs the binary
|
|
7
|
-
|
|
3
|
+
`katana-markdown-linter` is a thin launcher over GitHub Release binary
|
|
4
|
+
archives for npm. The package does not contain independent lint or MCP server
|
|
5
|
+
logic. On first use, it downloads the matching `kml`, `kml-mcp`, or `kml-mcp-remote`
|
|
6
|
+
binary archive, verifies the neighboring SHA-256 checksum, installs the binary
|
|
7
|
+
into the wrapper cache, and delegates to that binary.
|
|
8
8
|
|
|
9
9
|
## Install
|
|
10
10
|
|
|
@@ -16,8 +16,8 @@ kml --version
|
|
|
16
16
|
Use `npx` for one-off runs:
|
|
17
17
|
|
|
18
18
|
~~~bash
|
|
19
|
-
npx --yes katana-markdown-linter@0.
|
|
20
|
-
npx --yes katana-markdown-linter@0.
|
|
19
|
+
npx --yes katana-markdown-linter@0.19.3 --version
|
|
20
|
+
npx --yes katana-markdown-linter@0.19.3 check README.md
|
|
21
21
|
~~~
|
|
22
22
|
|
|
23
23
|
## Basic Usage
|
|
@@ -45,6 +45,23 @@ kml fix README.md
|
|
|
45
45
|
kml fmt
|
|
46
46
|
~~~
|
|
47
47
|
|
|
48
|
+
## MCP server entrypoints
|
|
49
|
+
|
|
50
|
+
Use `kml-mcp` for local stdio MCP clients:
|
|
51
|
+
|
|
52
|
+
~~~bash
|
|
53
|
+
npx --yes katana-markdown-linter@0.19.3 kml-mcp --workspace-root /absolute/path/to/workspace
|
|
54
|
+
bunx --package katana-markdown-linter@0.19.3 kml-mcp --workspace-root /absolute/path/to/workspace
|
|
55
|
+
npx --yes --package katana-markdown-linter@0.19.3 kml-mcp --workspace-root /absolute/path/to/workspace
|
|
56
|
+
~~~
|
|
57
|
+
|
|
58
|
+
Use `kml-mcp-remote` only for self-hosted Streamable HTTP:
|
|
59
|
+
|
|
60
|
+
~~~bash
|
|
61
|
+
KML_MCP_REMOTE_TOKEN=change-me \
|
|
62
|
+
npx --yes --package katana-markdown-linter@0.19.3 kml-mcp-remote
|
|
63
|
+
~~~
|
|
64
|
+
|
|
48
65
|
## Supported Platforms
|
|
49
66
|
|
|
50
67
|
The npm launcher uses the same binary archives as the GitHub Release channel.
|
|
@@ -60,12 +77,12 @@ Unsupported platforms fail before download with an explicit platform error.
|
|
|
60
77
|
## Wrapper Contract
|
|
61
78
|
|
|
62
79
|
- The package version selects the GitHub Release tag.
|
|
63
|
-
- The launcher downloads `kml-vX.Y.Z-<target
|
|
64
|
-
`kml-vX.Y.Z-<target
|
|
80
|
+
- The launcher downloads the matching `kml-vX.Y.Z-<target>`,
|
|
81
|
+
`kml-mcp-vX.Y.Z-<target>`, or `kml-mcp-remote-vX.Y.Z-<target>` archive.
|
|
65
82
|
- The launcher downloads the matching `.sha256` file and verifies the archive
|
|
66
83
|
before extraction.
|
|
67
|
-
- The installed binary is cached
|
|
68
|
-
|
|
84
|
+
- The installed binary is cached by version, platform, and executable role.
|
|
85
|
+
- MCP launchers do not write wrapper logs to stdout, preserving JSON-RPC stdio.
|
|
69
86
|
|
|
70
87
|
For full CLI usage, rule coverage, and other install channels, see the
|
|
71
88
|
[repository README](https://github.com/HiroyukiFuruno/katana-markdown-linter).
|
package/bin/kml-mcp.js
ADDED
package/bin/kml.js
CHANGED
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
const {
|
|
3
|
-
const { KmlInstaller } = require("../lib/installer");
|
|
2
|
+
const { KmlLauncher } = require("../lib/launcher");
|
|
4
3
|
|
|
5
|
-
|
|
6
|
-
const binaryPath = installer.ensureBinary();
|
|
7
|
-
const result = spawnSync(binaryPath, process.argv.slice(2), { stdio: "inherit" });
|
|
8
|
-
|
|
9
|
-
if (result.error) {
|
|
10
|
-
throw result.error;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
process.exit(result.status === null ? 1 : result.status);
|
|
4
|
+
process.exit(new KmlLauncher("kml", process.argv.slice(2)).run());
|
package/lib/installer.js
CHANGED
|
@@ -4,8 +4,18 @@ const fs = require("node:fs");
|
|
|
4
4
|
const os = require("node:os");
|
|
5
5
|
const path = require("node:path");
|
|
6
6
|
|
|
7
|
+
const BINARY_ROLES = {
|
|
8
|
+
cli: { executable: "kml", archivePrefix: "kml" },
|
|
9
|
+
kml: { executable: "kml", archivePrefix: "kml" },
|
|
10
|
+
"kml-mcp": { executable: "kml-mcp", archivePrefix: "kml-mcp" },
|
|
11
|
+
mcp: { executable: "kml-mcp", archivePrefix: "kml-mcp" },
|
|
12
|
+
"kml-mcp-remote": { executable: "kml-mcp-remote", archivePrefix: "kml-mcp-remote" },
|
|
13
|
+
"mcp-remote": { executable: "kml-mcp-remote", archivePrefix: "kml-mcp-remote" }
|
|
14
|
+
};
|
|
15
|
+
|
|
7
16
|
class KmlInstaller {
|
|
8
|
-
constructor() {
|
|
17
|
+
constructor(binaryRole = "cli") {
|
|
18
|
+
this.role = this.resolveRole(binaryRole);
|
|
9
19
|
this.packageRoot = path.resolve(__dirname, "..");
|
|
10
20
|
this.packageJson = require(path.join(this.packageRoot, "package.json"));
|
|
11
21
|
this.version = process.env.KML_WRAPPER_VERSION || `v${this.packageJson.version}`;
|
|
@@ -15,7 +25,14 @@ class KmlInstaller {
|
|
|
15
25
|
}
|
|
16
26
|
|
|
17
27
|
ensureBinary() {
|
|
18
|
-
const binaryPath = path.join(
|
|
28
|
+
const binaryPath = path.join(
|
|
29
|
+
this.installRoot,
|
|
30
|
+
this.version,
|
|
31
|
+
this.target,
|
|
32
|
+
this.role.executable,
|
|
33
|
+
"bin",
|
|
34
|
+
this.binaryName()
|
|
35
|
+
);
|
|
19
36
|
if (fs.existsSync(binaryPath)) {
|
|
20
37
|
return binaryPath;
|
|
21
38
|
}
|
|
@@ -83,7 +100,15 @@ class KmlInstaller {
|
|
|
83
100
|
|
|
84
101
|
resolveArchiveName() {
|
|
85
102
|
const suffix = this.target.includes("windows") ? "zip" : "tar.gz";
|
|
86
|
-
return
|
|
103
|
+
return `${this.role.archivePrefix}-${this.version}-${this.target}.${suffix}`;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
resolveRole(binaryRole) {
|
|
107
|
+
const role = BINARY_ROLES[binaryRole];
|
|
108
|
+
if (!role) {
|
|
109
|
+
throw new Error(`Unsupported kml wrapper binary role: ${binaryRole}`);
|
|
110
|
+
}
|
|
111
|
+
return role;
|
|
87
112
|
}
|
|
88
113
|
|
|
89
114
|
resolveTarget() {
|
|
@@ -101,7 +126,7 @@ class KmlInstaller {
|
|
|
101
126
|
}
|
|
102
127
|
|
|
103
128
|
binaryName() {
|
|
104
|
-
return this.target.includes("windows") ?
|
|
129
|
+
return this.target.includes("windows") ? `${this.role.executable}.exe` : this.role.executable;
|
|
105
130
|
}
|
|
106
131
|
}
|
|
107
132
|
|
package/lib/launcher.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
const { spawnSync } = require("node:child_process");
|
|
2
|
+
const { KmlInstaller } = require("./installer");
|
|
3
|
+
|
|
4
|
+
class KmlLauncher {
|
|
5
|
+
constructor(binaryRole, args) {
|
|
6
|
+
this.binaryRole = binaryRole;
|
|
7
|
+
this.args = args;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
run() {
|
|
11
|
+
const installer = new KmlInstaller(this.binaryRole);
|
|
12
|
+
const binaryPath = installer.ensureBinary();
|
|
13
|
+
const result = spawnSync(binaryPath, this.args, { stdio: "inherit" });
|
|
14
|
+
if (result.error) {
|
|
15
|
+
throw result.error;
|
|
16
|
+
}
|
|
17
|
+
return result.status === null ? 1 : result.status;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function dispatchPackageCommand(args) {
|
|
22
|
+
const [firstArg, ...remainingArgs] = args;
|
|
23
|
+
const roles = new Set(["kml", "kml-mcp", "kml-mcp-remote"]);
|
|
24
|
+
if (roles.has(firstArg)) {
|
|
25
|
+
return new KmlLauncher(firstArg, remainingArgs).run();
|
|
26
|
+
}
|
|
27
|
+
return new KmlLauncher("kml", args).run();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
module.exports = { KmlLauncher, dispatchPackageCommand };
|
package/package.json
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "katana-markdown-linter",
|
|
3
|
-
"version": "0.19.
|
|
3
|
+
"version": "0.19.3",
|
|
4
4
|
"description": "Fast Markdown linter and formatter with localized CLI help and version aliases.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"markdown",
|
|
7
7
|
"markdownlint",
|
|
8
8
|
"linter",
|
|
9
9
|
"kml",
|
|
10
|
-
"cli"
|
|
10
|
+
"cli",
|
|
11
|
+
"mcp",
|
|
12
|
+
"model-context-protocol"
|
|
11
13
|
],
|
|
12
14
|
"homepage": "https://github.com/HiroyukiFuruno/katana-markdown-linter#readme",
|
|
13
15
|
"bugs": {
|
|
@@ -19,7 +21,10 @@
|
|
|
19
21
|
"url": "https://github.com/HiroyukiFuruno/katana-markdown-linter.git"
|
|
20
22
|
},
|
|
21
23
|
"bin": {
|
|
22
|
-
"
|
|
24
|
+
"katana-markdown-linter": "bin/katana-markdown-linter.js",
|
|
25
|
+
"kml": "bin/kml.js",
|
|
26
|
+
"kml-mcp": "bin/kml-mcp.js",
|
|
27
|
+
"kml-mcp-remote": "bin/kml-mcp-remote.js"
|
|
23
28
|
},
|
|
24
29
|
"scripts": {
|
|
25
30
|
"postinstall": "node lib/installer.js"
|