mcpill 1.11.0 → 1.13.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/CHANGELOG.md +15 -3
- package/README.md +10 -3
- package/dist/cli.js +67 -48
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.13.0
|
|
4
|
+
|
|
5
|
+
- Non-blocking user-defined hooks (`## Hook:` entries with `command:` but no `blocking: true`) are now distributed into the standalone `install.js` and wired into the target agent's config during `<pill> install --agent claude-code` (claude-code only in v1)
|
|
6
|
+
- `HAS_USER_HOOKS` flag in `install.js` is independent of `HAS_BLOCKING_HOOKS` — pills with only informational hooks produce a correct success message
|
|
7
|
+
- `<pill> install --agent codex` prints a warning when the pill defines hooks that Codex cannot run
|
|
8
|
+
- `mcpill compile` auto-generates a `UserPromptSubmit` hook for the pill's first declared tool and merges it into `.claude/settings.json`; hook is a no-op until `~/.<pill-name>/state.json` sets `enabled: true` (written by `<pill-name> install`); idempotent; skipped by `--no-hooks`
|
|
9
|
+
|
|
10
|
+
## 1.12.0
|
|
11
|
+
|
|
12
|
+
- Fix: `runValidate` used `console.log` for the `✓ Valid:` summary line, writing plain text to stdout and breaking stdio MCP transport (clients tried to parse it as JSON-RPC and crashed). Output is now sent to `process.stderr.write` instead.
|
|
13
|
+
- Bumped `mcpster` dep to `^0.3.2`, which carries the same fix in its `setup.js`
|
|
14
|
+
|
|
3
15
|
## 1.11.0
|
|
4
16
|
|
|
5
17
|
- `trigger: UserPromptSubmit` is a valid hook trigger in `PILL.md` `## Hook:` sections and `.mcpill/server/hooks/*.md` files
|
|
@@ -57,7 +69,7 @@
|
|
|
57
69
|
|
|
58
70
|
## 1.2.4
|
|
59
71
|
|
|
60
|
-
- Fix: bump `mcpill-runtime` to `^0.1.2` — `0.1.0` dist imported
|
|
72
|
+
- Fix: bump `mcpill-runtime` to `^0.1.2` — `0.1.0` dist imported `,ruco-ai/mcpster` (old scoped name), causing `ERR_MODULE_NOT_FOUND` on global install
|
|
61
73
|
|
|
62
74
|
## 1.2.3
|
|
63
75
|
|
|
@@ -87,7 +99,7 @@
|
|
|
87
99
|
|
|
88
100
|
## 1.1.0
|
|
89
101
|
|
|
90
|
-
- Renamed to `mcpill`;
|
|
91
|
-
- `mcpill-runtime` renamed from
|
|
102
|
+
- Renamed to `mcpill`; `,ruco-ai/mcpill` deprecated — install `mcpill` instead
|
|
103
|
+
- `mcpill-runtime` renamed from `,ruco-ai/mcpill-runtime`
|
|
92
104
|
- Canonical home: https://mcpill.ruco.dev
|
|
93
105
|
- Added `repository`, `homepage`, and `bugs` metadata to package.json
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
CLI for building, validating, and publishing MCP servers using the pill format.
|
|
4
4
|
|
|
5
|
-
> **Renamed from
|
|
5
|
+
> **Renamed from `,ruco-ai/mcpill`** — if you have the scoped package, run `npm uninstall -g ,ruco-ai/mcpill && npm install -g mcpill`.
|
|
6
6
|
|
|
7
7
|
## Install
|
|
8
8
|
|
|
@@ -60,10 +60,13 @@ Compiles `server.md` + `tools/*.md` + `prompts/*.md` into a `.<name>/` pill arti
|
|
|
60
60
|
mcpill compile # forward: source → pill
|
|
61
61
|
mcpill compile --to-md # reverse: pill → source
|
|
62
62
|
mcpill compile --strict # error on missing tool handlers (default: stub)
|
|
63
|
-
mcpill compile --no-hooks # skip writing
|
|
63
|
+
mcpill compile --no-hooks # skip writing all hooks to .claude/settings.json
|
|
64
64
|
```
|
|
65
65
|
|
|
66
|
-
Compile also writes
|
|
66
|
+
Compile also writes two auto-generated hooks into `.claude/settings.json`:
|
|
67
|
+
|
|
68
|
+
- **`PreToolUse`** — warns Claude to use the pill's MCP tools instead of native file tools (`Read`, `Bash`, etc.) when the pill declares a `replaces` field.
|
|
69
|
+
- **`UserPromptSubmit`** — on every user message, injects context instructing Claude to call the pill's first declared tool before responding. Present whenever the pill has at least one tool; no-op until `~/.<pill-name>/state.json` sets `enabled: true` (written by `<pill-name> install`). Hook mappings are read from two sources, merged at compile time — rerun `mcpill compile` after any change:
|
|
67
70
|
|
|
68
71
|
- **`PILL.md`** (recommended) — add a `replaces` field to any `## Tool:` section:
|
|
69
72
|
|
|
@@ -97,6 +100,10 @@ At runtime the gate script exits 1 (blocking the tool call) until `mcp__{pill}__
|
|
|
97
100
|
|
|
98
101
|
`required_tool` must name a tool defined in the same pill; `mcpill compile` aborts with an error if it doesn't.
|
|
99
102
|
|
|
103
|
+
#### Non-blocking hooks and distribution
|
|
104
|
+
|
|
105
|
+
`## Hook:` entries without `blocking: true` but with a `command` field emit soft hooks (context injectors) to `.claude/settings.json`. They are also bundled into the standalone distribution: when an end user runs `<pill> install --agent claude-code`, these hooks are wired into their config automatically. Codex installs print a warning when the pill defines hooks that Codex cannot run.
|
|
106
|
+
|
|
100
107
|
### `mcpill validate`
|
|
101
108
|
|
|
102
109
|
Validates all pill directories (`.<name>/`) in the project root.
|
package/dist/cli.js
CHANGED
|
@@ -97,6 +97,7 @@ Instructions for building an mcpill MCP server from a filled \`PILL.md\`.
|
|
|
97
97
|
4. **Run** \`mcpill compile\`.
|
|
98
98
|
- If the pill's \`AGENT.md\` has a \`## Tools\` table with a \`replaces\` column, compile writes a \`PreToolUse\` hook into \`.claude/settings.json\` that warns Claude to use the pill's MCP tools instead of native file tools.
|
|
99
99
|
- If PILL.md has \`## Hook:\` sections (or \`.mcpill/server/hooks/*.md\` files exist), compile writes those hooks into \`.claude/settings.json\` under the corresponding event key. These coexist with the auto-generated \`replaces:\` hooks \u2014 both are merged.
|
|
100
|
+
- Compile also auto-generates a \`UserPromptSubmit\` hook for the pill's first declared tool. When the pill is active (\`~/.\${pillName}/state.json\` has \`enabled: true\`), this hook injects context on every user message instructing Claude to call the main tool first. The hook is always present but is a no-op until state.json is written (typically by \`\${pillName} install\`).
|
|
100
101
|
- To skip all hook generation: \`mcpill compile --no-hooks\`.
|
|
101
102
|
|
|
102
103
|
5. **Report** what was generated and show the user the next commands:
|
|
@@ -422,6 +423,10 @@ After writing \`PILL.md\`, tell the user:
|
|
|
422
423
|
> "PILL.md is ready. Review the tool descriptions, then say: **Build this PILL.md**"
|
|
423
424
|
|
|
424
425
|
Do not run \`mcpill compile\` or generate source files yourself \u2014 that is the build phase, handled separately by \`pill-agent-guide.md\`.
|
|
426
|
+
|
|
427
|
+
### Auto-generated UserPromptSubmit hook
|
|
428
|
+
|
|
429
|
+
When the user runs \`mcpill compile\`, a \`UserPromptSubmit\` hook is automatically written to \`.claude/settings.json\`. It injects context on every user message instructing Claude to call the pill's first tool before responding. The hook is always present but is a no-op until \`~/.\${pillName}/state.json\` sets \`enabled: true\` \u2014 this file is written by \`\${pillName} install\` during the distribution flow. To opt out of all hook generation the user can pass \`--no-hooks\` to compile.
|
|
425
430
|
`;
|
|
426
431
|
function makePillUserGuideMd(projectName) {
|
|
427
432
|
return `# ${projectName} \u2014 mcpill user guide
|
|
@@ -548,7 +553,6 @@ async function runInit(opts) {
|
|
|
548
553
|
// src/commands/run.ts
|
|
549
554
|
import path7 from "path";
|
|
550
555
|
import fs6 from "fs";
|
|
551
|
-
import os from "os";
|
|
552
556
|
import { z as z2 } from "mcpill-runtime";
|
|
553
557
|
import { createServer, applySetup } from "mcpster";
|
|
554
558
|
|
|
@@ -1232,7 +1236,8 @@ async function validateOne(mcpillDir) {
|
|
|
1232
1236
|
}
|
|
1233
1237
|
process.exit(1);
|
|
1234
1238
|
}
|
|
1235
|
-
|
|
1239
|
+
process.stderr.write(`\u2713 Valid: ${toolCount} tools, ${promptCount} prompts, ${resourceCount} resources
|
|
1240
|
+
`);
|
|
1236
1241
|
}
|
|
1237
1242
|
async function runValidate(baseDir) {
|
|
1238
1243
|
const mcpillDir = path6.join(baseDir, ".mcpill");
|
|
@@ -1263,32 +1268,6 @@ async function runValidate(baseDir) {
|
|
|
1263
1268
|
}
|
|
1264
1269
|
|
|
1265
1270
|
// src/commands/run.ts
|
|
1266
|
-
function patchJson(filePath, patcher) {
|
|
1267
|
-
if (!fs6.existsSync(filePath)) return;
|
|
1268
|
-
try {
|
|
1269
|
-
const obj = JSON.parse(fs6.readFileSync(filePath, "utf-8"));
|
|
1270
|
-
patcher(obj);
|
|
1271
|
-
fs6.writeFileSync(filePath, JSON.stringify(obj, null, 2) + "\n", "utf-8");
|
|
1272
|
-
} catch {
|
|
1273
|
-
}
|
|
1274
|
-
}
|
|
1275
|
-
function desktopConfigPaths() {
|
|
1276
|
-
const home = os.homedir();
|
|
1277
|
-
if (process.platform === "win32") {
|
|
1278
|
-
const appData = process.env.APPDATA ?? path7.join(home, "AppData", "Roaming");
|
|
1279
|
-
return [path7.join(appData, "Claude", "claude_desktop_config.json")];
|
|
1280
|
-
}
|
|
1281
|
-
return [path7.join(home, "Library", "Application Support", "Claude", "claude_desktop_config.json")];
|
|
1282
|
-
}
|
|
1283
|
-
function unregisterSync(name, baseDir) {
|
|
1284
|
-
const remove = (obj) => {
|
|
1285
|
-
const servers = obj.mcpServers;
|
|
1286
|
-
if (servers) delete servers[name];
|
|
1287
|
-
};
|
|
1288
|
-
patchJson(path7.join(baseDir, ".claude", "settings.json"), remove);
|
|
1289
|
-
patchJson(path7.join(os.homedir(), ".claude.json"), remove);
|
|
1290
|
-
for (const p of desktopConfigPaths()) patchJson(p, remove);
|
|
1291
|
-
}
|
|
1292
1271
|
async function runServer(opts) {
|
|
1293
1272
|
const baseDir = path7.resolve(opts.dir ?? process.cwd());
|
|
1294
1273
|
await runValidate(baseDir);
|
|
@@ -1350,16 +1329,6 @@ async function runServer(opts) {
|
|
|
1350
1329
|
args: ["run", "--dir", baseDir]
|
|
1351
1330
|
}
|
|
1352
1331
|
});
|
|
1353
|
-
const cleanup = () => unregisterSync(name, baseDir);
|
|
1354
|
-
process.on("exit", cleanup);
|
|
1355
|
-
process.on("SIGINT", () => {
|
|
1356
|
-
cleanup();
|
|
1357
|
-
process.exit(0);
|
|
1358
|
-
});
|
|
1359
|
-
process.on("SIGTERM", () => {
|
|
1360
|
-
cleanup();
|
|
1361
|
-
process.exit(0);
|
|
1362
|
-
});
|
|
1363
1332
|
}
|
|
1364
1333
|
try {
|
|
1365
1334
|
await server.start();
|
|
@@ -1432,7 +1401,7 @@ ${tool.description}
|
|
|
1432
1401
|
`;
|
|
1433
1402
|
}
|
|
1434
1403
|
if (tool.handler !== void 0) {
|
|
1435
|
-
const cleanHandler = tool.handler.split("\n").filter((l) => !l.trim().startsWith("//
|
|
1404
|
+
const cleanHandler = tool.handler.split("\n").filter((l) => !l.trim().startsWith("// ,handler:") && !l.trim().startsWith("// ,end-handler:")).join("\n").trim();
|
|
1436
1405
|
md += `
|
|
1437
1406
|
## Handler
|
|
1438
1407
|
|
|
@@ -1484,7 +1453,7 @@ function dedent(s) {
|
|
|
1484
1453
|
}
|
|
1485
1454
|
function extractHandlers(toolsJsContent) {
|
|
1486
1455
|
const result = /* @__PURE__ */ new Map();
|
|
1487
|
-
const markerRegex = /[ \t]*\/\/
|
|
1456
|
+
const markerRegex = /[ \t]*\/\/ ,handler:([^\n]+)\n([\s\S]*?)\n[ \t]*\/\/ ,end-handler:[^\n]+/g;
|
|
1488
1457
|
let match;
|
|
1489
1458
|
while ((match = markerRegex.exec(toolsJsContent)) !== null) {
|
|
1490
1459
|
result.set(match[1].trim(), dedent(match[2]).trim());
|
|
@@ -1780,9 +1749,21 @@ function installClaudeCode() {
|
|
|
1780
1749
|
});
|
|
1781
1750
|
}
|
|
1782
1751
|
}
|
|
1752
|
+
if (HAS_USER_HOOKS) {
|
|
1753
|
+
if (!s.hooks) s.hooks = {};
|
|
1754
|
+
for (const uh of USER_HOOKS) {
|
|
1755
|
+
if (!s.hooks[uh.event]) s.hooks[uh.event] = [];
|
|
1756
|
+
s.hooks[uh.event] = s.hooks[uh.event].filter(e => e.hooks?.[0]?.command !== uh.command);
|
|
1757
|
+
const entry = uh.event === 'UserPromptSubmit'
|
|
1758
|
+
? { hooks: [{ type: 'command', command: uh.command }] }
|
|
1759
|
+
: { matcher: uh.matcher ?? '.*', hooks: [{ type: 'command', command: uh.command }] };
|
|
1760
|
+
s.hooks[uh.event].push(entry);
|
|
1761
|
+
}
|
|
1762
|
+
}
|
|
1783
1763
|
writeJson(settingsPath, s);
|
|
1784
1764
|
activatePill();
|
|
1785
|
-
|
|
1765
|
+
const _hookSuffix = (HAS_BLOCKING_HOOKS || HAS_USER_HOOKS) ? '' : ' (no hooks \u2014 MCP server only)';
|
|
1766
|
+
if (!silent) process.stdout.write('[mcpill] info: ' + (wasInstalled ? 'reinstalled' : 'installed') + ' ' + PILL_NAME + _hookSuffix + ' for claude-code\\n');
|
|
1786
1767
|
}
|
|
1787
1768
|
|
|
1788
1769
|
function uninstallClaudeCode() {
|
|
@@ -1794,6 +1775,13 @@ function uninstallClaudeCode() {
|
|
|
1794
1775
|
const gateMarker = '/' + PILL_NAME + '/hooks/';
|
|
1795
1776
|
if (s.hooks.PreToolUse) s.hooks.PreToolUse = s.hooks.PreToolUse.filter(e => !e.hooks?.[0]?.command?.includes(gateMarker));
|
|
1796
1777
|
if (s.hooks.PostToolUse) s.hooks.PostToolUse = s.hooks.PostToolUse.filter(e => !e.matcher?.startsWith('mcp__' + PILL_NAME + '__'));
|
|
1778
|
+
if (HAS_USER_HOOKS) {
|
|
1779
|
+
for (const uh of USER_HOOKS) {
|
|
1780
|
+
if (s.hooks[uh.event]) {
|
|
1781
|
+
s.hooks[uh.event] = s.hooks[uh.event].filter(e => e.hooks?.[0]?.command !== uh.command);
|
|
1782
|
+
}
|
|
1783
|
+
}
|
|
1784
|
+
}
|
|
1797
1785
|
}
|
|
1798
1786
|
writeJson(settingsPath, s);
|
|
1799
1787
|
deactivatePill();
|
|
@@ -1948,7 +1936,12 @@ function installCodex() {
|
|
|
1948
1936
|
existing += '\\n\\n[mcp_servers.' + PILL_NAME + ']\\ncommand = "node"\\nargs = [' + JSON.stringify(INDEX_PATH) + ']\\n';
|
|
1949
1937
|
writeFileSync(configPath, existing.trim() + '\\n');
|
|
1950
1938
|
activatePill();
|
|
1951
|
-
if (!silent)
|
|
1939
|
+
if (!silent) {
|
|
1940
|
+
if (HAS_USER_HOOKS || HAS_BLOCKING_HOOKS) {
|
|
1941
|
+
process.stderr.write('[mcpill] warning: ' + PILL_NAME + ' defines hooks that Codex does not support \u2014 hook-dependent features will not work\\n');
|
|
1942
|
+
}
|
|
1943
|
+
process.stdout.write('[mcpill] info: installed ' + PILL_NAME + ' for codex (MCP server only \u2014 hooks not yet supported for codex)\\n');
|
|
1944
|
+
}
|
|
1952
1945
|
}
|
|
1953
1946
|
|
|
1954
1947
|
function uninstallCodex() {
|
|
@@ -1980,10 +1973,15 @@ if (command === 'install') {
|
|
|
1980
1973
|
}
|
|
1981
1974
|
}
|
|
1982
1975
|
`;
|
|
1983
|
-
function generateStandaloneInstallJs(pillName, version, blockingHooks) {
|
|
1976
|
+
function generateStandaloneInstallJs(pillName, version, blockingHooks, userHooks) {
|
|
1984
1977
|
const hooksData = blockingHooks.map((h) => ({
|
|
1985
1978
|
required_tool: h.required_tool
|
|
1986
1979
|
}));
|
|
1980
|
+
const userHooksData = userHooks.map((h) => ({
|
|
1981
|
+
event: h.event,
|
|
1982
|
+
command: h.command,
|
|
1983
|
+
...h.matcher !== void 0 ? { matcher: h.matcher } : {}
|
|
1984
|
+
}));
|
|
1987
1985
|
const constants = [
|
|
1988
1986
|
`#!/usr/bin/env node`,
|
|
1989
1987
|
`import { readFileSync, writeFileSync, mkdirSync, existsSync, rmSync } from 'fs';`,
|
|
@@ -1998,6 +1996,8 @@ function generateStandaloneInstallJs(pillName, version, blockingHooks) {
|
|
|
1998
1996
|
`const PILL_VERSION = ${JSON.stringify(version)};`,
|
|
1999
1997
|
`const HAS_BLOCKING_HOOKS = ${blockingHooks.length > 0};`,
|
|
2000
1998
|
`const HOOKS = ${JSON.stringify(hooksData, null, 2)};`,
|
|
1999
|
+
`const HAS_USER_HOOKS = ${userHooks.length > 0};`,
|
|
2000
|
+
`const USER_HOOKS = ${JSON.stringify(userHooksData, null, 2)};`,
|
|
2001
2001
|
`const VALID_AGENTS = ['claude-code', 'cursor', 'windsurf', 'github-copilot', 'codex'];`,
|
|
2002
2002
|
``,
|
|
2003
2003
|
`const argv = process.argv.slice(2);`,
|
|
@@ -2043,7 +2043,7 @@ function generateDistPackageJson(pillName, version, opts) {
|
|
|
2043
2043
|
}
|
|
2044
2044
|
return JSON.stringify(pkg2, null, 2) + "\n";
|
|
2045
2045
|
}
|
|
2046
|
-
function emitStandalonePackage(baseDir, pillName, version, toolsJsContent, doc, blockingHooks, opts = {}) {
|
|
2046
|
+
function emitStandalonePackage(baseDir, pillName, version, toolsJsContent, doc, blockingHooks, opts = {}, userHooks = []) {
|
|
2047
2047
|
const distDir = join5(baseDir, ".mcpill", "dist", pillName);
|
|
2048
2048
|
const hooksDir = join5(distDir, "hooks");
|
|
2049
2049
|
mkdirSync3(hooksDir, { recursive: true });
|
|
@@ -2054,7 +2054,7 @@ function emitStandalonePackage(baseDir, pillName, version, toolsJsContent, doc,
|
|
|
2054
2054
|
join5(distDir, "index.js"),
|
|
2055
2055
|
generateStandaloneIndexJs(pillName, version, doc.prompts, doc.resources, blockingHookTools)
|
|
2056
2056
|
);
|
|
2057
|
-
writeFileSync3(join5(distDir, "install.js"), generateStandaloneInstallJs(pillName, version, blockingHooks));
|
|
2057
|
+
writeFileSync3(join5(distDir, "install.js"), generateStandaloneInstallJs(pillName, version, blockingHooks, userHooks));
|
|
2058
2058
|
if (blockingHooks.length > 0) {
|
|
2059
2059
|
writeFileSync3(join5(hooksDir, "pre-tool-gate.js"), generateStandaloneGateScript(pillName, blockingHooks));
|
|
2060
2060
|
writeFileSync3(join5(hooksDir, "post-analysis-flag.js"), generateStandaloneFlagScript(pillName));
|
|
@@ -2085,9 +2085,9 @@ export default [`];
|
|
|
2085
2085
|
...schemaLines,
|
|
2086
2086
|
` },`,
|
|
2087
2087
|
` handler:`,
|
|
2088
|
-
` //
|
|
2088
|
+
` // ,handler:${tool.name}`,
|
|
2089
2089
|
handlerBody,
|
|
2090
|
-
` //
|
|
2090
|
+
` // ,end-handler:${tool.name}`,
|
|
2091
2091
|
` ,`,
|
|
2092
2092
|
` },`
|
|
2093
2093
|
);
|
|
@@ -2257,7 +2257,18 @@ async function runCompile(opts) {
|
|
|
2257
2257
|
mergeUserHooksIntoSettings(baseDir, generatedEntries);
|
|
2258
2258
|
console.log(`\u2713 .claude/settings.json updated with ${blockingHooks.length} blocking hook(s)`);
|
|
2259
2259
|
}
|
|
2260
|
-
|
|
2260
|
+
if (mergedDoc.tools.length > 0) {
|
|
2261
|
+
const mainToolName = mergedDoc.tools[0].name;
|
|
2262
|
+
const pillName = mergedDoc.config.name;
|
|
2263
|
+
const pillNameUpper = pillName.toUpperCase();
|
|
2264
|
+
const additionalContext = `${pillNameUpper} ACTIVE: You MUST call mcp__${pillName}__${mainToolName} with the user text before responding. If results are relevant, mention them in your reply.`;
|
|
2265
|
+
const hookJson = JSON.stringify({ hookSpecificOutput: { hookEventName: "UserPromptSubmit", additionalContext } });
|
|
2266
|
+
const autoHookCommand = `enabled=$(jq -r '.enabled // false' ~/.${pillName}/state.json 2>/dev/null || echo false); [ "$enabled" = "true" ] && printf '${hookJson}' || true`;
|
|
2267
|
+
mergeUserHooksIntoSettings(baseDir, [{ event: "UserPromptSubmit", command: autoHookCommand }]);
|
|
2268
|
+
console.log(`\u2713 .claude/settings.json updated with UserPromptSubmit auto-hook (main tool: ${mainToolName})`);
|
|
2269
|
+
}
|
|
2270
|
+
const distributedUserHooks = regularHooks.filter((h) => !!h.command);
|
|
2271
|
+
emitStandalonePackage(baseDir, mergedDoc.config.name, pillVersion, toolsJsContent, mergedDoc, blockingHooks, { postinstall: pillPostinstall }, distributedUserHooks);
|
|
2261
2272
|
console.log(`\u2713 .mcpill/dist/${mergedDoc.config.name}/ updated`);
|
|
2262
2273
|
}
|
|
2263
2274
|
|
|
@@ -2295,6 +2306,14 @@ import path9 from "path";
|
|
|
2295
2306
|
async function runPublish(dir, access) {
|
|
2296
2307
|
const baseDir = path9.resolve(dir);
|
|
2297
2308
|
await runPack(baseDir);
|
|
2309
|
+
const whoami = spawnSync("npm", ["whoami"], { stdio: "pipe", encoding: "utf-8" });
|
|
2310
|
+
if (whoami.status !== 0) {
|
|
2311
|
+
console.log("Not logged in to npm \u2014 running npm login...");
|
|
2312
|
+
const login = spawnSync("npm", ["login"], { stdio: "inherit" });
|
|
2313
|
+
if (login.status !== 0) {
|
|
2314
|
+
throw new Error("npm login failed");
|
|
2315
|
+
}
|
|
2316
|
+
}
|
|
2298
2317
|
const result = spawnSync("npm", ["publish", "--access", access], {
|
|
2299
2318
|
cwd: baseDir,
|
|
2300
2319
|
stdio: "inherit"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcpill",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.13.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "CLI for building, validating, and publishing MCP servers using the pill format.",
|
|
6
6
|
"homepage": "https://mcpill.ruco.dev",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"mcpill-runtime": "^0.1.2",
|
|
30
|
-
"mcpster": "^0.3.
|
|
30
|
+
"mcpster": "^0.3.2",
|
|
31
31
|
"commander": "^12"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|