@lorekit/cli 1.13.0 → 1.13.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/bin/lorekit.mjs CHANGED
@@ -59,7 +59,7 @@ ${c.bold('Commands')}
59
59
  diff Compare the offline and remote stores for the applicable scopes and
60
60
  report divergence: local-only, remote-only, and conflicting keys
61
61
  (grouped by scope). Needs both stores readable. --json, --scope <s>.
62
- tree Show the injected scopes (branch → repo → global) as a precedence
62
+ tree Show the injected scopes (project → branch → repo → global) as a precedence
63
63
  (resolve) hierarchy and mark, per key, which scope's lesson WINS and which are
64
64
  shadowed — the real hook-resolution order. --json, --scope <s>.
65
65
  lint Flag low-quality lessons (empty/short/untrimmed value, empty key,
@@ -315,13 +315,12 @@ ${c.bold('Examples')}
315
315
  ${c.bold('Usage')}
316
316
  npx @lorekit/cli tree [options]
317
317
 
318
- Shows the scopes the hooks actually inject for the current directory — branch,
319
- repo, global, in precedence order (most-specific first) — and marks, for any key
318
+ Shows the scopes the hooks actually inject for the current directory — project,
319
+ branch, repo, global, in precedence order (most-specific first) — and marks, for any key
320
320
  present at more than one scope, which scope's lesson WINS and which are shadowed.
321
321
  This mirrors the SessionStart hook's resolution exactly (a more-specific scope
322
- overrides a broader scope's same-key lesson). Project-scope lessons are NOT
323
- injected by the hooks, so they are not shown here — browse them with \`lorekit list\`.
324
- Resolved independently per store, in the same Offline / Remote split.
322
+ overrides a broader scope's same-key lesson). Resolved independently per store,
323
+ in the same Offline / Remote split.
325
324
 
326
325
  ${c.bold('Options')}
327
326
  -d, --dir <path> Target project root (default: current directory)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lorekit/cli",
3
- "version": "1.13.0",
3
+ "version": "1.13.1",
4
4
  "description": "Install the LoreKit shared-memory skill and run health checks for the LoreKit MCP server.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -337,12 +337,31 @@ function withOverrides(args, env) {
337
337
  return out;
338
338
  }
339
339
 
340
+ // A one-line human-readable readiness banner for `lorekit mcp`. Pure so it can
341
+ // be unit-tested. Printed to STDERR (never stdout — that channel carries only
342
+ // JSON-RPC frames) and only when stdin is a TTY, so a real MCP client that
343
+ // pipes to us gets a pristine, banner-free stdout AND stderr.
344
+ export function startupBanner(mode) {
345
+ return (
346
+ `lorekit mcp — local stdio MCP server ready (mode: ${mode}). ` +
347
+ 'Speaking JSON-RPC 2.0 on stdin/stdout; this is machine-facing, so no ' +
348
+ 'further output is normal. Press Ctrl-C to stop.'
349
+ );
350
+ }
351
+
340
352
  // Entrypoint for `lorekit mcp`. Resolves the store once, then serves stdio
341
353
  // until the client closes stdin. Always resolves to exit code 0.
342
- export async function mcpServer(args = {}, { env = process.env, input = process.stdin, output = process.stdout } = {}) {
354
+ export async function mcpServer(
355
+ args = {},
356
+ { env = process.env, input = process.stdin, output = process.stdout, errorOutput = process.stderr } = {},
357
+ ) {
343
358
  const root = resolveProjectRoot(args.dir);
344
359
  const control = loadControl(root, { env: withOverrides(args, env) });
345
360
  const handle = createHandler(control);
361
+ // A human who runs `lorekit mcp` in a terminal would otherwise see a silent
362
+ // hang with no sign it is alive. Reassure them on stderr — but only when
363
+ // stdin is a TTY, so a piped MCP client never sees the banner on either channel.
364
+ if (input && input.isTTY) errorOutput.write(startupBanner(control.mode) + '\n');
346
365
  await runStdio(handle, input, output);
347
366
  return 0;
348
367
  }