@lorekit/cli 1.55.1 → 1.55.2

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.
Files changed (43) hide show
  1. package/README.md +1 -1
  2. package/bin/lorekit.mjs +3 -3
  3. package/package.json +1 -1
  4. package/src/{bootstrap.mjs → commands/bootstrap.mjs} +5 -4
  5. package/src/{dedupe.mjs → commands/dedupe.mjs} +6 -6
  6. package/src/{diff.mjs → commands/diff.mjs} +6 -6
  7. package/src/{doctor.mjs → commands/doctor.mjs} +9 -9
  8. package/src/{hook.mjs → commands/hook.mjs} +12 -12
  9. package/src/{install.mjs → commands/install.mjs} +4 -4
  10. package/src/{link.mjs → commands/link.mjs} +4 -4
  11. package/src/{lint.mjs → commands/lint.mjs} +6 -6
  12. package/src/{list.mjs → commands/list.mjs} +7 -7
  13. package/src/{mcp-server.mjs → commands/mcp-server.mjs} +10 -10
  14. package/src/{migrate.mjs → commands/migrate.mjs} +8 -8
  15. package/src/{purge.mjs → commands/purge.mjs} +5 -5
  16. package/src/{remove.mjs → commands/remove.mjs} +5 -5
  17. package/src/{scopes.mjs → commands/scopes.mjs} +5 -5
  18. package/src/{search.mjs → commands/search.mjs} +7 -7
  19. package/src/{show.mjs → commands/show.mjs} +6 -6
  20. package/src/{stats.mjs → commands/stats.mjs} +6 -6
  21. package/src/{tree.mjs → commands/tree.mjs} +8 -8
  22. package/src/{uninstall.mjs → commands/uninstall.mjs} +2 -2
  23. package/src/{write.mjs → commands/write.mjs} +8 -8
  24. package/src/commands.mjs +21 -21
  25. package/src/core/lessons.mjs +4 -4
  26. package/src/{config.mjs → shared/config.mjs} +2 -2
  27. package/src/{lessons-pure.mjs → shared/lessons-pure.mjs} +2 -2
  28. package/src/{mcp.mjs → shared/mcp.mjs} +18 -0
  29. package/src/{origin.mjs → shared/origin.mjs} +2 -2
  30. package/src/{stores.mjs → shared/stores.mjs} +1 -1
  31. package/src/store/created-at.mjs +1 -1
  32. package/src/store/remote.mjs +6 -6
  33. package/src/store/ttl.mjs +1 -1
  34. package/src/surfaces.generated.mjs +1 -1
  35. package/src/{telemetry-identity.mjs → telemetry/telemetry-identity.mjs} +2 -2
  36. package/src/{telemetry.mjs → telemetry/telemetry.mjs} +2 -2
  37. /package/src/{control.mjs → shared/control.mjs} +0 -0
  38. /package/src/{deeplink-pure.mjs → shared/deeplink-pure.mjs} +0 -0
  39. /package/src/{dotenv.mjs → shared/dotenv.mjs} +0 -0
  40. /package/src/{lessons-view.mjs → shared/lessons-view.mjs} +0 -0
  41. /package/src/{scope.mjs → shared/scope.mjs} +0 -0
  42. /package/src/{util.mjs → shared/util.mjs} +0 -0
  43. /package/src/{telemetry-token.mjs → telemetry/telemetry-token.mjs} +0 -0
package/README.md CHANGED
@@ -555,7 +555,7 @@ the `.lorekit/` files directly, `remote` passes calls through to the hosted
555
555
  endpoint, and `off` advertises no tools.
556
556
 
557
557
  Tools advertised are **derived from the canonical tool catalog**
558
- (`packages/schemas/src/tool-catalog.ts`) rather than declared here, so this
558
+ (`packages/schemas/src/shared/tool-catalog.ts`) rather than declared here, so this
559
559
  server and the hosted one describe each operation identically. In `local` and
560
560
  `remote` mode that is `memory.write`, `memory.read`, `memory.list`,
561
561
  `memory.search`, `memory.delete`, `memory.archive`, `memory.restore` and
package/bin/lorekit.mjs CHANGED
@@ -2,7 +2,7 @@
2
2
  // LoreKit CLI — install the shared-memory skill and run health checks.
3
3
  import process from 'node:process';
4
4
  import { readFileSync } from 'node:fs';
5
- import { parseArgs, log, err, c } from '../src/util.mjs';
5
+ import { parseArgs, log, err, c } from '../src/shared/util.mjs';
6
6
  // Commands, their handlers, aliases and dispatch properties all come from one
7
7
  // registry — see ../src/commands.mjs for why membership lives there and the
8
8
  // help prose stays here.
@@ -10,8 +10,8 @@ import { COMMANDS_BY_NAME, STRICT_FLAG_COMMANDS, COMMAND_ALIASES } from '../src/
10
10
  // Catalog-derived, so the default this help PROMISES is the one the server
11
11
  // applies — see src/surfaces.generated.mjs.
12
12
  import { PURGE_RETENTION_DAYS_DEFAULT } from '../src/surfaces.generated.mjs';
13
- import { traceCommand, meterCommand } from '../src/telemetry.mjs';
14
- import { loadDotEnv } from '../src/dotenv.mjs';
13
+ import { traceCommand, meterCommand } from '../src/telemetry/telemetry.mjs';
14
+ import { loadDotEnv } from '../src/shared/dotenv.mjs';
15
15
 
16
16
  // Read the version from package.json so it always matches the published
17
17
  // package — release-please bumps package.json, and this tracks it for free.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lorekit/cli",
3
- "version": "1.55.1",
3
+ "version": "1.55.2",
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": {
@@ -12,13 +12,14 @@ import fs from 'node:fs';
12
12
  import path from 'node:path';
13
13
  import { fileURLToPath } from 'node:url';
14
14
  import process from 'node:process';
15
- import { log, err, heading, status, c } from './util.mjs';
15
+ import { log, err, heading, status, c } from '../shared/util.mjs';
16
16
 
17
17
  // The bootstrap.sql file is at <repo-root>/supabase/byod/bootstrap.sql.
18
- // This file lives at packages/cli/src/bootstrap.mjs, so the relative path
19
- // from here to the repo root is ../../../ (srcclipackages root).
18
+ // This file lives at packages/cli/src/commands/bootstrap.mjs, so the relative
19
+ // path from here to the repo root is ../../../../ (commandssrccli
20
+ // packages → root).
20
21
  const BOOTSTRAP_SQL_PATH = fileURLToPath(
21
- new URL('../../../supabase/byod/bootstrap.sql', import.meta.url),
22
+ new URL('../../../../supabase/byod/bootstrap.sql', import.meta.url),
22
23
  );
23
24
 
24
25
  export async function bootstrap(_args) {
@@ -11,12 +11,12 @@
11
11
  // Same Offline / Remote split and graceful degradation as `list`. Read-only.
12
12
  // Human-facing, so the bin wraps it in `traceCommand`.
13
13
  import process from 'node:process';
14
- import { resolveProjectRoot, readLorekitJson } from './config.mjs';
15
- import { deriveScope } from './scope.mjs';
16
- import { resolveDenies } from './control.mjs';
17
- import { resolveStores, remoteUnavailableReason } from './stores.mjs';
18
- import { scopeList, gather, gatherStream, clusterDuplicates, clusterDuplicatesBlocked, clusterByKeyPattern, compileKeyPattern, DEFAULT_MAX } from './lessons-view.mjs';
19
- import { log, heading, status, err, c } from './util.mjs';
14
+ import { resolveProjectRoot, readLorekitJson } from '../shared/config.mjs';
15
+ import { deriveScope } from '../shared/scope.mjs';
16
+ import { resolveDenies } from '../shared/control.mjs';
17
+ import { resolveStores, remoteUnavailableReason } from '../shared/stores.mjs';
18
+ import { scopeList, gather, gatherStream, clusterDuplicates, clusterDuplicatesBlocked, clusterByKeyPattern, compileKeyPattern, DEFAULT_MAX } from '../shared/lessons-view.mjs';
19
+ import { log, heading, status, err, c } from '../shared/util.mjs';
20
20
 
21
21
  const DEFAULT_THRESHOLD = 0.8;
22
22
  // Maximum entries to accumulate before the survey becomes memory-prohibitive.
@@ -11,12 +11,12 @@
11
11
  // and exits 0 (never a crash). Read-only. Human-facing, so the bin wraps it in
12
12
  // `traceCommand`.
13
13
  import process from 'node:process';
14
- import { resolveProjectRoot } from './config.mjs';
15
- import { deriveScope } from './scope.mjs';
16
- import { resolveDenies } from './control.mjs';
17
- import { resolveStores, remoteUnavailableReason } from './stores.mjs';
18
- import { scopeList, gather, diffGroups, preview, shortDate } from './lessons-view.mjs';
19
- import { log, heading, status, c } from './util.mjs';
14
+ import { resolveProjectRoot } from '../shared/config.mjs';
15
+ import { deriveScope } from '../shared/scope.mjs';
16
+ import { resolveDenies } from '../shared/control.mjs';
17
+ import { resolveStores, remoteUnavailableReason } from '../shared/stores.mjs';
18
+ import { scopeList, gather, diffGroups, preview, shortDate } from '../shared/lessons-view.mjs';
19
+ import { log, heading, status, c } from '../shared/util.mjs';
20
20
 
21
21
  export async function diff(args) {
22
22
  const root = resolveProjectRoot(args.dir);
@@ -16,18 +16,18 @@ import {
16
16
  readMcpConfig,
17
17
  tokenKind,
18
18
  readLorekitJson,
19
- } from './config.mjs';
20
- import { splitEndpoint } from './mcp.mjs';
19
+ } from '../shared/config.mjs';
20
+ import { splitEndpoint } from '../shared/mcp.mjs';
21
21
  import {
22
22
  resolveTelemetryConfig,
23
23
  resolveTelemetryTokenSource,
24
24
  probeTelemetryExport,
25
- } from './telemetry.mjs';
26
- import { describeIdentity } from './telemetry-identity.mjs';
27
- import { deriveScope } from './scope.mjs';
28
- import { loadControl, HOOK_INSTRUCTION_EVENTS } from './control.mjs';
29
- import { createStore } from './store/index.mjs';
30
- import { log, heading, status, c } from './util.mjs';
25
+ } from '../telemetry/telemetry.mjs';
26
+ import { describeIdentity } from '../telemetry/telemetry-identity.mjs';
27
+ import { deriveScope } from '../shared/scope.mjs';
28
+ import { loadControl, HOOK_INSTRUCTION_EVENTS } from '../shared/control.mjs';
29
+ import { createStore } from '../store/index.mjs';
30
+ import { log, heading, status, c } from '../shared/util.mjs';
31
31
 
32
32
  const AUTH_CODES = new Set([401, 403, -32001]);
33
33
 
@@ -590,7 +590,7 @@ async function checkTelemetryExport(args, root, record) {
590
590
  /** The running CLI version, for stamping the telemetry probe span. */
591
591
  function cliVersion() {
592
592
  try {
593
- return JSON.parse(fs.readFileSync(new URL('../package.json', import.meta.url), 'utf8')).version;
593
+ return JSON.parse(fs.readFileSync(new URL('../../package.json', import.meta.url), 'utf8')).version;
594
594
  } catch {
595
595
  return '0.0.0';
596
596
  }
@@ -3,10 +3,10 @@
3
3
  // logic, and prints the framework-shaped injection on stdout. Always exits 0 —
4
4
  // a memory hook must never block or break the host agent.
5
5
  import process from 'node:process';
6
- import { resolveProjectRoot } from './config.mjs';
7
- import { deriveScope } from './scope.mjs';
8
- import { loadControl } from './control.mjs';
9
- import { createStore } from './store/index.mjs';
6
+ import { resolveProjectRoot } from '../shared/config.mjs';
7
+ import { deriveScope } from '../shared/scope.mjs';
8
+ import { loadControl } from '../shared/control.mjs';
9
+ import { createStore } from '../store/index.mjs';
10
10
  import {
11
11
  fetchLessons,
12
12
  formatLessons,
@@ -20,19 +20,19 @@ import {
20
20
  relevantLessonsFromStore,
21
21
  formatRelevantLessons,
22
22
  writeConfirmation,
23
- } from './core/lessons.mjs';
24
- import { isFailure } from './core/failure.mjs';
25
- import { readSessionFriction, shouldRetrospect, FRICTION_FAILURE } from './core/friction.mjs';
23
+ } from '../core/lessons.mjs';
24
+ import { isFailure } from '../core/failure.mjs';
25
+ import { readSessionFriction, shouldRetrospect, FRICTION_FAILURE } from '../core/friction.mjs';
26
26
  import {
27
27
  firstTimeThisSession,
28
28
  sessionMarkerExists,
29
29
  shownLessons,
30
30
  recordShownLessons,
31
- } from './core/state.mjs';
32
- import { recordFixture } from './core/record.mjs';
33
- import { claude } from './adapters/claude.mjs';
34
- import { cursor } from './adapters/cursor.mjs';
35
- import { codex } from './adapters/codex.mjs';
31
+ } from '../core/state.mjs';
32
+ import { recordFixture } from '../core/record.mjs';
33
+ import { claude } from '../adapters/claude.mjs';
34
+ import { cursor } from '../adapters/cursor.mjs';
35
+ import { codex } from '../adapters/codex.mjs';
36
36
 
37
37
  const ADAPTERS = { claude, cursor, codex };
38
38
 
@@ -26,10 +26,10 @@ import {
26
26
  readJsonIfExists,
27
27
  readLorekitServer,
28
28
  isWebMcpServerEntry,
29
- } from './config.mjs';
30
- import { buildRemoteUrl, splitEndpoint } from './mcp.mjs';
31
- import { deriveScope } from './scope.mjs';
32
- import { log, heading, status, select, err, c } from './util.mjs';
29
+ } from '../shared/config.mjs';
30
+ import { buildRemoteUrl, splitEndpoint } from '../shared/mcp.mjs';
31
+ import { deriveScope } from '../shared/scope.mjs';
32
+ import { log, heading, status, select, err, c } from '../shared/util.mjs';
33
33
 
34
34
  // The MCP server URL is fixed — there is only one hosted LoreKit endpoint.
35
35
  const LOREKIT_MCP_ENDPOINT = 'https://pqokxlhvnosogizsjztg.supabase.co/functions/v1/mcp';
@@ -15,8 +15,8 @@
15
15
  // Every param is JSON-encoded per the `useUrlState` contract (see
16
16
  // `deeplink-pure.mjs`) — a raw `?scope=global` would silently mean "all scopes".
17
17
  import process from 'node:process';
18
- import { resolveProjectRoot } from './config.mjs';
19
- import { deriveScope } from './scope.mjs';
18
+ import { resolveProjectRoot } from '../shared/config.mjs';
19
+ import { deriveScope } from '../shared/scope.mjs';
20
20
  import {
21
21
  resolveAppBase,
22
22
  buildLoreUrl,
@@ -26,8 +26,8 @@ import {
26
26
  parseTagsArg,
27
27
  resolveScopeKeyArgs,
28
28
  surfaceFor,
29
- } from './deeplink-pure.mjs';
30
- import { log, err } from './util.mjs';
29
+ } from '../shared/deeplink-pure.mjs';
30
+ import { log, err } from '../shared/util.mjs';
31
31
 
32
32
  export async function link(args) {
33
33
  const root = resolveProjectRoot(args.dir);
@@ -11,12 +11,12 @@
11
11
  // `list`; a `LOREKIT_DENY` ceiling or an unconfigured remote is a note, not an
12
12
  // error. Read-only. Human-facing, so the bin wraps it in `traceCommand`.
13
13
  import process from 'node:process';
14
- import { resolveProjectRoot } from './config.mjs';
15
- import { deriveScope } from './scope.mjs';
16
- import { resolveDenies } from './control.mjs';
17
- import { resolveStores, remoteUnavailableReason } from './stores.mjs';
18
- import { scopeList, gather, gatherStream, lintGroups, DEFAULT_MAX } from './lessons-view.mjs';
19
- import { log, heading, status, c } from './util.mjs';
14
+ import { resolveProjectRoot } from '../shared/config.mjs';
15
+ import { deriveScope } from '../shared/scope.mjs';
16
+ import { resolveDenies } from '../shared/control.mjs';
17
+ import { resolveStores, remoteUnavailableReason } from '../shared/stores.mjs';
18
+ import { scopeList, gather, gatherStream, lintGroups, DEFAULT_MAX } from '../shared/lessons-view.mjs';
19
+ import { log, heading, status, c } from '../shared/util.mjs';
20
20
 
21
21
  export async function lint(args) {
22
22
  const root = resolveProjectRoot(args.dir);
@@ -9,14 +9,14 @@
9
9
  import os from 'node:os';
10
10
  import path from 'node:path';
11
11
  import process from 'node:process';
12
- import { resolveProjectRoot } from './config.mjs';
13
- import { deriveScope } from './scope.mjs';
14
- import { resolveDenies } from './control.mjs';
15
- import { resolveStores, remoteUnavailableReason } from './stores.mjs';
16
- import { scopeList, gather, gatherStream, renderSection, DEFAULT_MAX } from './lessons-view.mjs';
17
- import { resolveAppBase, mostSpecificScope } from './deeplink-pure.mjs';
12
+ import { resolveProjectRoot } from '../shared/config.mjs';
13
+ import { deriveScope } from '../shared/scope.mjs';
14
+ import { resolveDenies } from '../shared/control.mjs';
15
+ import { resolveStores, remoteUnavailableReason } from '../shared/stores.mjs';
16
+ import { scopeList, gather, gatherStream, renderSection, DEFAULT_MAX } from '../shared/lessons-view.mjs';
17
+ import { resolveAppBase, mostSpecificScope } from '../shared/deeplink-pure.mjs';
18
18
  import { emitLink } from './link.mjs';
19
- import { log, heading, c } from './util.mjs';
19
+ import { log, heading, c } from '../shared/util.mjs';
20
20
 
21
21
  // Abbreviate the user's home directory to `~` for readable paths.
22
22
  function prettyPath(p) {
@@ -24,17 +24,17 @@
24
24
  //
25
25
  // The transport is hand-rolled (no MCP SDK) to keep the CLI dependency-free.
26
26
  import process from 'node:process';
27
- import { resolveProjectRoot } from './config.mjs';
28
- import { loadControl } from './control.mjs';
29
- import { createStore } from './store/index.mjs';
30
- import { createRemoteStore } from './store/remote.mjs';
31
- import { deriveOrigin, mergeOrigin } from './origin.mjs';
32
- import { readScopeInventory } from './store/scope-inventory.mjs';
33
- import { inferKindHostFromTags } from './lessons-view.mjs';
34
- // Generated from packages/schemas/src/tool-catalog.ts — the same declaration the
27
+ import { resolveProjectRoot } from '../shared/config.mjs';
28
+ import { loadControl } from '../shared/control.mjs';
29
+ import { createStore } from '../store/index.mjs';
30
+ import { createRemoteStore } from '../store/remote.mjs';
31
+ import { deriveOrigin, mergeOrigin } from '../shared/origin.mjs';
32
+ import { readScopeInventory } from '../store/scope-inventory.mjs';
33
+ import { inferKindHostFromTags } from '../shared/lessons-view.mjs';
34
+ // Generated from packages/schemas/src/shared/tool-catalog.ts — the same declaration the
35
35
  // hosted MCP server renders `tools/list` from. Committed and zero-dep because
36
36
  // this is a published package that cannot import the workspace schemas.
37
- import { MCP_TOOL_DEFS, MCP_TOOL_NAMES } from './surfaces.generated.mjs';
37
+ import { MCP_TOOL_DEFS, MCP_TOOL_NAMES } from '../surfaces.generated.mjs';
38
38
 
39
39
  const PROTOCOL_VERSION = '2024-11-05';
40
40
  const SERVER_INFO = { name: 'lorekit-local', version: '1.0.0' };
@@ -365,7 +365,7 @@ export function advertise(dispatch) {
365
365
  if (!def) {
366
366
  throw new Error(
367
367
  `mcp-server dispatches "${name}", which the tool catalog does not declare. `
368
- + 'Add it to packages/schemas/src/tool-catalog.ts (and regenerate: node scripts/gen-surfaces.mjs).',
368
+ + 'Add it to packages/schemas/src/shared/tool-catalog.ts (and regenerate: node scripts/gen-surfaces.mjs).',
369
369
  );
370
370
  }
371
371
  return def;
@@ -22,16 +22,16 @@
22
22
  // org-owned writes; a v1 migration always lands as the caller's personal lore.
23
23
  import fs from 'node:fs';
24
24
  import path from 'node:path';
25
- import { resolveProjectRoot, tokenKind } from './config.mjs';
26
- import { localStoreDirs, loadControl } from './control.mjs';
27
- import { createLocalStore, createTwoTierStore, createRemoteStore } from './store/index.mjs';
28
- import { parseEntry } from './store/format.mjs';
29
- import { isLive, TTL_MAX_DAYS } from './store/ttl.mjs';
30
- import { remoteWriteLosses } from './store/remote.mjs';
25
+ import { resolveProjectRoot, tokenKind } from '../shared/config.mjs';
26
+ import { localStoreDirs, loadControl } from '../shared/control.mjs';
27
+ import { createLocalStore, createTwoTierStore, createRemoteStore } from '../store/index.mjs';
28
+ import { parseEntry } from '../store/format.mjs';
29
+ import { isLive, TTL_MAX_DAYS } from '../store/ttl.mjs';
30
+ import { remoteWriteLosses } from '../store/remote.mjs';
31
31
  import {
32
32
  createPacer, withRetry, isMemoryCap, sleep, DEFAULT_CONSECUTIVE_FAILURE_LIMIT,
33
- } from './store/rate-limit.mjs';
34
- import { log, heading, status, err, c } from './util.mjs';
33
+ } from '../store/rate-limit.mjs';
34
+ import { log, heading, status, err, c } from '../shared/util.mjs';
35
35
 
36
36
  // Recursively collect every parseable LoreKit entry under a base dir. The
37
37
  // canonical scope comes from each file's frontmatter, so the source layout does
@@ -24,11 +24,11 @@
24
24
  // business sweeping the whole account. The CLI makes exactly one request and
25
25
  // reports the server's answer; it never retries, never splits the sweep and
26
26
  // never re-scopes to work around it.
27
- import { resolveProjectRoot } from './config.mjs';
28
- import { loadControl, resolveDenies } from './control.mjs';
29
- import { resolveStores, remoteUnavailableReason } from './stores.mjs';
30
- import { log, err, c, select } from './util.mjs';
31
- import { PURGE_RETENTION_DAYS_DEFAULT } from './surfaces.generated.mjs';
27
+ import { resolveProjectRoot } from '../shared/config.mjs';
28
+ import { loadControl, resolveDenies } from '../shared/control.mjs';
29
+ import { resolveStores, remoteUnavailableReason } from '../shared/stores.mjs';
30
+ import { log, err, c, select } from '../shared/util.mjs';
31
+ import { PURGE_RETENTION_DAYS_DEFAULT } from '../surfaces.generated.mjs';
32
32
 
33
33
  /** The window `retention_days` accepts, mirroring `PurgeMemoriesBodySchema`. */
34
34
  export const RETENTION_DAYS_MIN = 1;
@@ -12,11 +12,11 @@
12
12
  // memory.delete / memory.restore operations, which are scope-authorized for an
13
13
  // API token by its allowlist (migrations 00071 / 00072): a key scoped to a
14
14
  // scope may manage every writer's row in it, an unscoped key only its own.
15
- import { resolveProjectRoot } from './config.mjs';
16
- import { loadControl, resolveDenies } from './control.mjs';
17
- import { resolveStores, remoteUnavailableReason } from './stores.mjs';
18
- import { log, err, c } from './util.mjs';
19
- import { resolveScopeKeyArgs, scopeIssue } from './lessons-view.mjs';
15
+ import { resolveProjectRoot } from '../shared/config.mjs';
16
+ import { loadControl, resolveDenies } from '../shared/control.mjs';
17
+ import { resolveStores, remoteUnavailableReason } from '../shared/stores.mjs';
18
+ import { log, err, c } from '../shared/util.mjs';
19
+ import { resolveScopeKeyArgs, scopeIssue } from '../shared/lessons-view.mjs';
20
20
 
21
21
  // The three surfaces return different success shapes: the remote store answers
22
22
  // `{ ok, error, networkError }`, the local store `{ deleted, archived, entry }`.
@@ -25,11 +25,11 @@
25
25
  // scopes whose string contains that substring; `--json` emits `{ offline,
26
26
  // remote }`.
27
27
  import process from 'node:process';
28
- import { resolveProjectRoot } from './config.mjs';
29
- import { resolveDenies } from './control.mjs';
30
- import { resolveStores, remoteUnavailableReason } from './stores.mjs';
31
- import { summarizeScopeInventory, filterScopeInventory, describeError } from './lessons-view.mjs';
32
- import { log, heading, status, c } from './util.mjs';
28
+ import { resolveProjectRoot } from '../shared/config.mjs';
29
+ import { resolveDenies } from '../shared/control.mjs';
30
+ import { resolveStores, remoteUnavailableReason } from '../shared/stores.mjs';
31
+ import { summarizeScopeInventory, filterScopeInventory, describeError } from '../shared/lessons-view.mjs';
32
+ import { log, heading, status, c } from '../shared/util.mjs';
33
33
 
34
34
  export async function scopes(args) {
35
35
  const root = resolveProjectRoot(args.dir);
@@ -14,14 +14,14 @@
14
14
  // never an error; a per-scope read failure is a warning, not a crash. Read-only,
15
15
  // archived hidden. Human-facing, so the bin wraps it in `traceCommand`.
16
16
  import process from 'node:process';
17
- import { resolveProjectRoot } from './config.mjs';
18
- import { deriveScope } from './scope.mjs';
19
- import { resolveDenies } from './control.mjs';
20
- import { resolveStores, remoteUnavailableReason } from './stores.mjs';
21
- import { scopeList, gather, filterGroups, renderSection } from './lessons-view.mjs';
22
- import { resolveAppBase, mostSpecificScope } from './deeplink-pure.mjs';
17
+ import { resolveProjectRoot } from '../shared/config.mjs';
18
+ import { deriveScope } from '../shared/scope.mjs';
19
+ import { resolveDenies } from '../shared/control.mjs';
20
+ import { resolveStores, remoteUnavailableReason } from '../shared/stores.mjs';
21
+ import { scopeList, gather, filterGroups, renderSection } from '../shared/lessons-view.mjs';
22
+ import { resolveAppBase, mostSpecificScope } from '../shared/deeplink-pure.mjs';
23
23
  import { emitLink } from './link.mjs';
24
- import { log, err, heading, c } from './util.mjs';
24
+ import { log, err, heading, c } from '../shared/util.mjs';
25
25
 
26
26
  export async function search(args) {
27
27
  const root = resolveProjectRoot(args.dir);
@@ -18,9 +18,9 @@
18
18
  // an unconfigured remote is a short note, never an error. Read-only. Human-facing,
19
19
  // so the bin wraps it in `traceCommand`.
20
20
  import process from 'node:process';
21
- import { resolveProjectRoot } from './config.mjs';
22
- import { resolveDenies } from './control.mjs';
23
- import { resolveStores, remoteUnavailableReason } from './stores.mjs';
21
+ import { resolveProjectRoot } from '../shared/config.mjs';
22
+ import { resolveDenies } from '../shared/control.mjs';
23
+ import { resolveStores, remoteUnavailableReason } from '../shared/stores.mjs';
24
24
  import {
25
25
  normalizeEntry,
26
26
  shortDate,
@@ -28,10 +28,10 @@ import {
28
28
  recordsDiverge,
29
29
  resolveScopeKeyArgs,
30
30
  scopeIssue,
31
- } from './lessons-view.mjs';
32
- import { resolveAppBase } from './deeplink-pure.mjs';
31
+ } from '../shared/lessons-view.mjs';
32
+ import { resolveAppBase } from '../shared/deeplink-pure.mjs';
33
33
  import { emitLink } from './link.mjs';
34
- import { log, err, heading, status, c } from './util.mjs';
34
+ import { log, err, heading, status, c } from '../shared/util.mjs';
35
35
 
36
36
  // Read one scope::key from a store, normalizing the result into a small,
37
37
  // uniform shape: { available:true, found, record } on success, or
@@ -16,12 +16,12 @@
16
16
  // `memory.list` returns for each scope (server-side default page size), the
17
17
  // same window `list` already shows.
18
18
  import process from 'node:process';
19
- import { resolveProjectRoot } from './config.mjs';
20
- import { deriveScope } from './scope.mjs';
21
- import { resolveDenies } from './control.mjs';
22
- import { resolveStores, remoteUnavailableReason } from './stores.mjs';
23
- import { scopeList, gather, tallyGroups, summarizeScopeInventory, filterScopeInventory } from './lessons-view.mjs';
24
- import { log, heading, status, c } from './util.mjs';
19
+ import { resolveProjectRoot } from '../shared/config.mjs';
20
+ import { deriveScope } from '../shared/scope.mjs';
21
+ import { resolveDenies } from '../shared/control.mjs';
22
+ import { resolveStores, remoteUnavailableReason } from '../shared/stores.mjs';
23
+ import { scopeList, gather, tallyGroups, summarizeScopeInventory, filterScopeInventory } from '../shared/lessons-view.mjs';
24
+ import { log, heading, status, c } from '../shared/util.mjs';
25
25
 
26
26
  export async function stats(args) {
27
27
  const root = resolveProjectRoot(args.dir);
@@ -28,15 +28,15 @@
28
28
  // in the same Offline / Remote split as `list`. Graceful, read-only, wrapped in
29
29
  // `traceCommand` by the bin.
30
30
  import process from 'node:process';
31
- import { resolveProjectRoot } from './config.mjs';
32
- import { deriveScope } from './scope.mjs';
33
- import { resolveDenies } from './control.mjs';
34
- import { resolveStores, remoteUnavailableReason } from './stores.mjs';
35
- import { resolvePrecedence } from './lessons-pure.mjs';
36
- import { gather, preview, shortDate } from './lessons-view.mjs';
37
- import { resolveAppBase, mostSpecificScope } from './deeplink-pure.mjs';
31
+ import { resolveProjectRoot } from '../shared/config.mjs';
32
+ import { deriveScope } from '../shared/scope.mjs';
33
+ import { resolveDenies } from '../shared/control.mjs';
34
+ import { resolveStores, remoteUnavailableReason } from '../shared/stores.mjs';
35
+ import { resolvePrecedence } from '../shared/lessons-pure.mjs';
36
+ import { gather, preview, shortDate } from '../shared/lessons-view.mjs';
37
+ import { resolveAppBase, mostSpecificScope } from '../shared/deeplink-pure.mjs';
38
38
  import { emitLink } from './link.mjs';
39
- import { log, heading, status, c } from './util.mjs';
39
+ import { log, heading, status, c } from '../shared/util.mjs';
40
40
 
41
41
  export async function tree(args) {
42
42
  const root = resolveProjectRoot(args.dir);
@@ -12,8 +12,8 @@ import {
12
12
  removeWebMcpServer,
13
13
  removeClaudeHooks,
14
14
  homeDir,
15
- } from './config.mjs';
16
- import { log, heading, status, c } from './util.mjs';
15
+ } from '../shared/config.mjs';
16
+ import { log, heading, status, c } from '../shared/util.mjs';
17
17
 
18
18
  function ask(question) {
19
19
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
@@ -60,13 +60,13 @@
60
60
  // resolved scope, key, store written, and a boolean `inserted` (true = created,
61
61
  // false = updated) when the remote reports it.
62
62
  import process from 'node:process';
63
- import { resolveProjectRoot } from './config.mjs';
64
- import { loadControl, resolveDenies } from './control.mjs';
65
- import { resolveStores, remoteUnavailableReason } from './stores.mjs';
66
- import { log, err, heading, status, c } from './util.mjs';
67
- import { resolveScopeKeyArgs, scopeIssue } from './lessons-view.mjs';
68
- import { deriveOrigin, mergeOrigin } from './origin.mjs';
69
- import { parseTtlDays, resolveDefaultTtlDays } from './store/ttl.mjs';
63
+ import { resolveProjectRoot } from '../shared/config.mjs';
64
+ import { loadControl, resolveDenies } from '../shared/control.mjs';
65
+ import { resolveStores, remoteUnavailableReason } from '../shared/stores.mjs';
66
+ import { log, err, heading, status, c } from '../shared/util.mjs';
67
+ import { resolveScopeKeyArgs, scopeIssue } from '../shared/lessons-view.mjs';
68
+ import { deriveOrigin, mergeOrigin } from '../shared/origin.mjs';
69
+ import { parseTtlDays, resolveDefaultTtlDays } from '../store/ttl.mjs';
70
70
 
71
71
  // Read all of stdin to a string. Resolves to '' when stdin IS a TTY (no pipe).
72
72
  function readStdin() {
@@ -108,7 +108,7 @@ export async function write(args) {
108
108
  // string, so this is also the only thing standing between a local write and
109
109
  // a scope the hosted API would reject with a 400. It is a PARTIAL gate, not
110
110
  // an equivalent one: `scopeIssue` checks the segment SHAPE (`[^/]+/[^/]+`)
111
- // where `packages/mcp-core/src/scope.ts` additionally restricts the CHARSET
111
+ // where `packages/mcp-core/src/scope/scope.ts` additionally restricts the CHARSET
112
112
  // (`[\w.-]+/[\w.-]+`), so `repo::a b/c,d` and `branch::o/r::a",x` pass here
113
113
  // and still 400 remotely. Tightening the CLI to match would also change what
114
114
  // `lint`'s malformed-scope rule flags in existing offline stores, so it is a
package/src/commands.mjs CHANGED
@@ -33,32 +33,32 @@
33
33
  // leaving them entirely silent meant the usage that dominates was the usage
34
34
  // nobody could see — a span each is still the wrong trade, a counter is not.
35
35
 
36
- import { install } from './install.mjs';
37
- import { uninstall } from './uninstall.mjs';
38
- import { doctor } from './doctor.mjs';
39
- import { list } from './list.mjs';
40
- import { search } from './search.mjs';
41
- import { show } from './show.mjs';
42
- import { write } from './write.mjs';
43
- import { archive, del, restore } from './remove.mjs';
44
- import { stats } from './stats.mjs';
45
- import { scopes } from './scopes.mjs';
46
- import { diff } from './diff.mjs';
47
- import { tree } from './tree.mjs';
48
- import { lint } from './lint.mjs';
49
- import { dedupe } from './dedupe.mjs';
50
- import { link } from './link.mjs';
51
- import { hook } from './hook.mjs';
52
- import { migrate } from './migrate.mjs';
53
- import { bootstrap } from './bootstrap.mjs';
54
- import { mcpServer } from './mcp-server.mjs';
55
- import { purge, purgeExpired } from './purge.mjs';
36
+ import { install } from './commands/install.mjs';
37
+ import { uninstall } from './commands/uninstall.mjs';
38
+ import { doctor } from './commands/doctor.mjs';
39
+ import { list } from './commands/list.mjs';
40
+ import { search } from './commands/search.mjs';
41
+ import { show } from './commands/show.mjs';
42
+ import { write } from './commands/write.mjs';
43
+ import { archive, del, restore } from './commands/remove.mjs';
44
+ import { stats } from './commands/stats.mjs';
45
+ import { scopes } from './commands/scopes.mjs';
46
+ import { diff } from './commands/diff.mjs';
47
+ import { tree } from './commands/tree.mjs';
48
+ import { lint } from './commands/lint.mjs';
49
+ import { dedupe } from './commands/dedupe.mjs';
50
+ import { link } from './commands/link.mjs';
51
+ import { hook } from './commands/hook.mjs';
52
+ import { migrate } from './commands/migrate.mjs';
53
+ import { bootstrap } from './commands/bootstrap.mjs';
54
+ import { mcpServer } from './commands/mcp-server.mjs';
55
+ import { purge, purgeExpired } from './commands/purge.mjs';
56
56
 
57
57
  /**
58
58
  * Every command, in the order the top-level help lists them.
59
59
  *
60
60
  * `tool` binds a command to a catalog operation (`surfaces.cli` in
61
- * `packages/schemas/src/tool-catalog.ts`) — the two are cross-checked, so a
61
+ * `packages/schemas/src/shared/tool-catalog.ts`) — the two are cross-checked, so a
62
62
  * catalog op claiming a CLI command that does not exist here fails a test.
63
63
  * `native` marks a command with no catalog operation and says why, which is
64
64
  * most of them: installing, diagnosing and grooming are CLI concerns that no
@@ -2,7 +2,7 @@
2
2
  // Framework-agnostic — adapters shape these strings into each tool's contract.
3
3
  // Storage is reached through the resolved store (local | remote), never a
4
4
  // backend directly, so the same read path serves every mode.
5
- import { deriveScope } from '../scope.mjs';
5
+ import { deriveScope } from '../shared/scope.mjs';
6
6
  // The cross-scope precedence merge comes from the dependency-free
7
7
  // `lessons-pure.mjs` — the SAME `resolvePrecedence` `tree` uses, so the hook
8
8
  // can't drift from it, and the hot path never pulls in the `lessons-view.mjs`
@@ -14,7 +14,7 @@ import { deriveScope } from '../scope.mjs';
14
14
  // of what "most useful" means.
15
15
  import {
16
16
  resolvePrecedence, rankLessons, diversifyRankedLessons, capPerBucket, loopBucketOf,
17
- } from '../lessons-pure.mjs';
17
+ } from '../shared/lessons-pure.mjs';
18
18
  // The store's own scope inventory, normalised — the SAME helper `memory.scopes`
19
19
  // uses, so the map and the MCP tool cannot disagree about what a scope holds or
20
20
  // about what a failed enumeration looks like.
@@ -23,7 +23,7 @@ import { readScopeInventory } from '../store/scope-inventory.mjs';
23
23
  // `--link` flag use, so the hook's confirmation/nudge links are JSON-encoded
24
24
  // correctly (a raw `?scope=global` silently means "all scopes") and can't drift
25
25
  // from the command-line links.
26
- import { loreScopeUrl, buildLessonUrl } from '../deeplink-pure.mjs';
26
+ import { loreScopeUrl, buildLessonUrl } from '../shared/deeplink-pure.mjs';
27
27
  // The SAME resolver `lorekit write` applies, so the TTL the nudge advises an
28
28
  // agent to send is byte-for-byte the one the CLI would have applied itself. A
29
29
  // hook cannot set a TTL — it only reads and emits text; the write happens later,
@@ -41,7 +41,7 @@ import {
41
41
  DEFAULT_SESSION_START_MAX_LESSONS,
42
42
  MAX_SESSION_START_MAX_LESSONS,
43
43
  SESSION_START_MODES,
44
- } from '../control.mjs';
44
+ } from '../shared/control.mjs';
45
45
  import { FRICTION_FAILURE, FRICTION_STUCK_LOOP } from './friction.mjs';
46
46
 
47
47
  // THE INJECTED SET IS BOUNDED BY A CHARACTER BUDGET, NOT BY A COUNT.
@@ -5,8 +5,8 @@ import path from 'node:path';
5
5
  import { spawnSync } from 'node:child_process';
6
6
  import { fileURLToPath } from 'node:url';
7
7
 
8
- // packages/cli/ — the installable package root (this file lives in src/).
9
- export const PKG_ROOT = fileURLToPath(new URL('../', import.meta.url));
8
+ // packages/cli/ — the installable package root (this file lives in src/shared/).
9
+ export const PKG_ROOT = fileURLToPath(new URL('../../', import.meta.url));
10
10
  export const SKILL_NAME = 'lorekit-memory';
11
11
  export const SKILL_SOURCE = path.join(PKG_ROOT, 'skill', SKILL_NAME);
12
12
 
@@ -271,7 +271,7 @@ export const DEFAULT_RANK_WEIGHTS = Object.freeze({ recency: 1, salience: 1, rel
271
271
  *
272
272
  * This is the ONE deliberate asymmetry vs `normalizeRelevance` (which returns
273
273
  * 0 for absent / unreadable input). Mirrored byte-identically in
274
- * `packages/mcp-core/src/lesson-rank.ts` and its edge twin.
274
+ * `packages/mcp-core/src/ranking/lesson-rank.ts` and its edge twin.
275
275
  */
276
276
  export const COLD_START_OUTCOME_PRIOR = 0.5;
277
277
 
@@ -491,7 +491,7 @@ function seenCountFrom(entry) {
491
491
  * MMR λ (lambda) — weight given to relevance vs diversity in the MMR objective.
492
492
  * At 0.7 the selector favours relevance, with 0.3 of the budget for diversity.
493
493
  * Anchored to Carbonell & Goldstein (1998), the original MMR paper.
494
- * Mirrored byte-identically in the edge twin and `packages/mcp-core/src/lesson-rank.ts`.
494
+ * Mirrored byte-identically in the edge twin and `packages/mcp-core/src/ranking/lesson-rank.ts`.
495
495
  */
496
496
  export const MMR_LAMBDA = 0.7;
497
497
 
@@ -77,6 +77,24 @@ export async function mcpCall(endpoint, token, method, params = {}, { timeoutMs
77
77
  error: { code: res.status, message: text.slice(0, 200) || res.statusText },
78
78
  };
79
79
  }
80
+ // A tool-originated failure arrives as a SUCCESSFUL JSON-RPC result carrying
81
+ // `isError: true` — that is the MCP spec's shape, so the model can see the
82
+ // error and self-correct, and the edge handler now uses it for everything
83
+ // the caller can fix (a memory-cap hit, a malformed scope, a bad TTL).
84
+ //
85
+ // Without this branch the check above passes (there is no `json.error`) and
86
+ // the call is reported as `ok: true`, so a cap rejection reads as a
87
+ // successful write. Exactly the trap the load-test driver hit from the other
88
+ // side: on this transport the status code does not carry the outcome.
89
+ if (json && json.result && json.result.isError) {
90
+ const text0 = json.result.content && json.result.content[0];
91
+ return {
92
+ ok: false,
93
+ httpStatus: res.status,
94
+ toolError: true,
95
+ error: { code: 'tool_error', message: (text0 && text0.text) || 'The tool reported an error.' },
96
+ };
97
+ }
80
98
  return { ok: true, httpStatus: res.status, result: json ? json.result : undefined };
81
99
  } catch (e) {
82
100
  return { ok: false, networkError: String(e && e.message ? e.message : e) };
@@ -65,7 +65,7 @@ function toPositiveInt(raw) {
65
65
  *
66
66
  * A deny list, deliberately: a branch is whatever a contributor named it, and
67
67
  * `feat/add+x` / `fix/issue#123` / `feat/café` are all legal. The canonical
68
- * rule lives in `packages/mcp-core/src/origin.ts` (`parseOriginBranch`); this
68
+ * rule lives in `packages/mcp-core/src/provenance/origin.ts` (`parseOriginBranch`); this
69
69
  * is the zero-dependency CLI copy, kept behaviourally identical so a branch the
70
70
  * CLI derives is never one the server would reject.
71
71
  */
@@ -155,7 +155,7 @@ export function deriveOrigin({ cwd = process.cwd(), env = process.env, run = git
155
155
  * Normalise a candidate `owner/name`, or null when it is not one.
156
156
  *
157
157
  * The single repo rule for every derivation path, matching the server's
158
- * `parseOriginRepo` (`packages/mcp-core/src/origin.ts`) — including its
158
+ * `parseOriginRepo` (`packages/mcp-core/src/provenance/origin.ts`) — including its
159
159
  * rejection of a dots-only segment, which `[\\w.-]+` alone admits and which
160
160
  * would render as a link to a different repository.
161
161
  */
@@ -12,7 +12,7 @@ import process from 'node:process';
12
12
  import { localStoreDirs } from './control.mjs';
13
13
  import { resolveProjectConnection } from './config.mjs';
14
14
  import { splitEndpoint } from './mcp.mjs';
15
- import { createTwoTierStore, createRemoteStore } from './store/index.mjs';
15
+ import { createTwoTierStore, createRemoteStore } from '../store/index.mjs';
16
16
 
17
17
  // Build both stores for `root`. Explicit `endpoint` / `token` (e.g. from
18
18
  // `--endpoint` / `--token` flags) take precedence over the resolved connection;
@@ -1,5 +1,5 @@
1
1
  // Zero-dependency mirror of the created_at validation used by the hosted MCP
2
- // server (packages/mcp-core/src/created-at.ts). Keeps the local `lorekit mcp`
2
+ // server (packages/mcp-core/src/limits/created-at.ts). Keeps the local `lorekit mcp`
3
3
  // stdio server's memory.write contract identical to the remote one: an optional
4
4
  // ISO 8601 creation-date override, rejected when invalid or future-dated.
5
5
 
@@ -14,13 +14,13 @@
14
14
  // and the `orgs` edge function now passes it plus its own tenant filters — so
15
15
  // every `/orgs*` route serves api_key tokens and the holdout is gone.
16
16
  //
17
- // `packages/cli/src/mcp.mjs` still exists and is still used: it backs the
17
+ // `packages/cli/src/shared/mcp.mjs` still exists and is still used: it backs the
18
18
  // `lorekit mcp` stdio server command and provides `mcpToRestBase`. It is just
19
19
  // no longer a transport for this store.
20
20
  // Zero-dependency.
21
- import { restFetch, mcpToRestBase } from '../mcp.mjs';
22
- import { rememberAccountId } from '../telemetry-identity.mjs';
23
- import { getActiveTraceparent } from '../telemetry.mjs';
21
+ import { restFetch, mcpToRestBase } from '../shared/mcp.mjs';
22
+ import { rememberAccountId } from '../telemetry/telemetry-identity.mjs';
23
+ import { getActiveTraceparent } from '../telemetry/telemetry.mjs';
24
24
  import { withReadFields } from './entry-fields.mjs';
25
25
  import { normalizeCreatedAt } from './created-at.mjs';
26
26
 
@@ -598,7 +598,7 @@ class RemoteStore {
598
598
  // ── Org operations → REST ─────────────────────────────────────────────────
599
599
  // `supabase/functions/orgs/` serves `lk_*` tokens on every route as of
600
600
  // 00041_org_actor_override.sql (see the file header). Each method's RETURN
601
- // SHAPE is unchanged from the MCP era — `packages/cli/src/mcp-server.mjs`
601
+ // SHAPE is unchanged from the MCP era — `packages/cli/src/commands/mcp-server.mjs`
602
602
  // serialises these objects straight into a `tools/call` result, so the shape
603
603
  // is a published contract, not an internal detail.
604
604
  //
@@ -613,7 +613,7 @@ class RemoteStore {
613
613
  // `{ id, slug, name }`. A bare JSON id string is the LEGACY shape an older
614
614
  // deployed backend can still return — that is what the string branch below is
615
615
  // for, not the normal case. Either way this method reassembles the
616
- // `{ id, slug, name }` triple, because `packages/cli/src/mcp-server.mjs`
616
+ // `{ id, slug, name }` triple, because `packages/cli/src/commands/mcp-server.mjs`
617
617
  // serialises it straight into a `tools/call` result and that shape is a
618
618
  // published contract.
619
619
  async orgCreate({ slug, name } = {}) {
package/src/store/ttl.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  // Zero-dependency mirror of the TTL (time-to-live) contract used by the hosted
2
- // MCP server (packages/mcp-core/src/ttl.ts) and the `memory_write` RPC
2
+ // MCP server (packages/mcp-core/src/limits/ttl.ts) and the `memory_write` RPC
3
3
  // (migrations 00030/00031). Keeps the local file store's expiry semantics
4
4
  // identical to the remote one, so a memory written offline expires the same way
5
5
  // it would have online — and a local↔remote migration is lossless.
@@ -1,5 +1,5 @@
1
1
  // GENERATED — do not edit.
2
- // Source: packages/schemas/src/tool-catalog.ts
2
+ // Source: packages/schemas/src/shared/tool-catalog.ts
3
3
  // Regenerate: node scripts/gen-surfaces.mjs
4
4
  //
5
5
  // Edit the catalog's `surfaces` bindings, not this file. `--check` fails CI
@@ -50,8 +50,8 @@
50
50
  import process from 'node:process';
51
51
  import fs from 'node:fs';
52
52
  import path from 'node:path';
53
- import { homeRoot } from './control.mjs';
54
- import { writeFileAtomic } from './config.mjs';
53
+ import { homeRoot } from '../shared/control.mjs';
54
+ import { writeFileAtomic } from '../shared/config.mjs';
55
55
 
56
56
  /** Filename under the home tier. Sits beside `config.json` and the local store. */
57
57
  const IDENTITY_FILE = 'telemetry-id.json';
@@ -34,7 +34,7 @@
34
34
 
35
35
  import process from 'node:process';
36
36
  import { TELEMETRY_TOKEN } from './telemetry-token.mjs';
37
- import { readLorekitJson } from './config.mjs';
37
+ import { readLorekitJson } from '../shared/config.mjs';
38
38
  import {
39
39
  ensureIdentity,
40
40
  identityAttributes,
@@ -77,7 +77,7 @@ let _activeSampled = false;
77
77
  *
78
78
  * Flags are `01` when the CLI span is exported and `00` when it is not — the
79
79
  * trace id is still carried either way, so the server can correlate. This
80
- * mirrors `formatTraceparent` in `packages/mcp-core/src/trace-context.ts`
80
+ * mirrors `formatTraceparent` in `packages/mcp-core/src/telemetry/trace-context.ts`
81
81
  * (the CLI is zero-dep `.mjs` and cannot import the TS module); keep the two
82
82
  * byte-consistent.
83
83
  */
File without changes
File without changes
File without changes
File without changes