@remnic/core 9.3.686 → 9.3.688

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 (37) hide show
  1. package/dist/access-cli.js +3 -3
  2. package/dist/active-recall.js +3 -3
  3. package/dist/{chunk-MCQDSY4G.js → chunk-3K37VPM3.js} +2 -2
  4. package/dist/{chunk-6GJS4BFH.js → chunk-A7UZR6RA.js} +2 -2
  5. package/dist/{chunk-QVMXQGT7.js → chunk-CCWHPGT4.js} +4 -4
  6. package/dist/{chunk-U7D7NP4J.js → chunk-ED35D32I.js} +2 -2
  7. package/dist/chunk-K6MV3TRQ.js +56 -0
  8. package/dist/chunk-K6MV3TRQ.js.map +1 -0
  9. package/dist/{chunk-QO3AILZN.js → chunk-OO42R444.js} +2 -2
  10. package/dist/{chunk-FE6DQUNJ.js → chunk-RVYD6LR3.js} +2 -2
  11. package/dist/cli.js +6 -6
  12. package/dist/config.js +3 -3
  13. package/dist/connectors/index.d.ts +10 -2
  14. package/dist/connectors/index.js +2 -2
  15. package/dist/emit-legacy-tools.js +2 -2
  16. package/dist/index.d.ts +11 -0
  17. package/dist/index.js +10 -7
  18. package/dist/index.js.map +1 -1
  19. package/dist/operator-toolkit.js +4 -4
  20. package/dist/resume-bundles.js +4 -4
  21. package/dist/schemas.d.ts +22 -22
  22. package/dist/transfer/types.d.ts +12 -12
  23. package/package.json +2 -2
  24. package/src/connectors/paths.test.ts +192 -0
  25. package/src/connectors/paths.ts +106 -20
  26. package/src/memory-extension/claude-code-publisher.ts +1 -0
  27. package/src/memory-extension/codex-publisher.ts +1 -0
  28. package/src/memory-extension/hermes-publisher.ts +1 -0
  29. package/src/memory-extension/types.ts +11 -0
  30. package/dist/chunk-3BQOQYRB.js +0 -33
  31. package/dist/chunk-3BQOQYRB.js.map +0 -1
  32. /package/dist/{chunk-MCQDSY4G.js.map → chunk-3K37VPM3.js.map} +0 -0
  33. /package/dist/{chunk-6GJS4BFH.js.map → chunk-A7UZR6RA.js.map} +0 -0
  34. /package/dist/{chunk-QVMXQGT7.js.map → chunk-CCWHPGT4.js.map} +0 -0
  35. /package/dist/{chunk-U7D7NP4J.js.map → chunk-ED35D32I.js.map} +0 -0
  36. /package/dist/{chunk-QO3AILZN.js.map → chunk-OO42R444.js.map} +0 -0
  37. /package/dist/{chunk-FE6DQUNJ.js.map → chunk-RVYD6LR3.js.map} +0 -0
@@ -4,46 +4,132 @@ import path from "node:path";
4
4
  import { readEnvVar, resolveHomeDir } from "../runtime/env.js";
5
5
 
6
6
  /**
7
- * Connector registry directory name. Kept under the legacy `engram` config
8
- * root for backward compatibility with existing installs; the rename to a
9
- * `remnic` path (with a legacy read-fallback) is tracked in #1518.
7
+ * Connector registry directory name. Kept under the canonical `remnic` config
8
+ * root for new installs; legacy installs that still live under `engram` are
9
+ * read-transparent via {@link getActiveConnectorsConfigRoot} (issue #1518).
10
10
  */
11
- export const REGISTRY_DIR_NAME = ".engram-connectors";
11
+ export const REGISTRY_DIR_NAME = ".remnic-connectors";
12
12
 
13
13
  /**
14
- * Single source of truth for the connectors config root
15
- * (`$XDG_CONFIG_HOME/engram` or `~/.config/engram`). Issue #1527 flagged this
16
- * derivation as previously duplicated across call sites — add new callers
17
- * here, never re-derive the path inline.
14
+ * Legacy registry directory name from the engram era. Used only for the
15
+ * read-fallback so existing installs keep resolving until the user migrates.
16
+ */
17
+ export const LEGACY_REGISTRY_DIR_NAME = ".engram-connectors";
18
+
19
+ /**
20
+ * Config-root segment for the canonical (post-rename) layout. Issue #1518
21
+ * point 6: the path `~/.config/engram/...` is confusing when the product is
22
+ * called Remnic, so new writes land under `remnic/`.
23
+ */
24
+ const CONFIG_ROOT_SEGMENT = "remnic";
25
+
26
+ /**
27
+ * Config-root segment for the legacy engram-era layout. Read-fallback only.
28
+ */
29
+ const LEGACY_CONFIG_ROOT_SEGMENT = "engram";
30
+
31
+ /**
32
+ * Single source of truth for the canonical connectors config root
33
+ * (`$XDG_CONFIG_HOME/remnic` or `~/.config/remnic`). New writes ALWAYS go
34
+ * here. Issue #1527 flagged this derivation as previously duplicated across
35
+ * call sites — add new callers here, never re-derive the path inline.
18
36
  */
19
37
  export function getConnectorsConfigRoot(): string {
20
38
  const xdgConfigHome = readEnvVar("XDG_CONFIG_HOME");
21
39
  return xdgConfigHome
22
- ? path.join(xdgConfigHome, "engram")
23
- : path.join(resolveHomeDir(), ".config", "engram");
40
+ ? path.join(xdgConfigHome, CONFIG_ROOT_SEGMENT)
41
+ : path.join(resolveHomeDir(), ".config", CONFIG_ROOT_SEGMENT);
24
42
  }
25
43
 
26
- /** Path of the connector registry manifest file. */
44
+ /**
45
+ * Legacy config root from the engram era (`$XDG_CONFIG_HOME/engram` or
46
+ * `~/.config/engram`). Exposed for tests and the migration path only —
47
+ * production code should call {@link getActiveConnectorsConfigRoot} so the
48
+ * read-fallback is applied uniformly.
49
+ */
50
+ export function getLegacyConnectorsConfigRoot(): string {
51
+ const xdgConfigHome = readEnvVar("XDG_CONFIG_HOME");
52
+ return xdgConfigHome
53
+ ? path.join(xdgConfigHome, LEGACY_CONFIG_ROOT_SEGMENT)
54
+ : path.join(resolveHomeDir(), ".config", LEGACY_CONFIG_ROOT_SEGMENT);
55
+ }
56
+
57
+ /**
58
+ * Read-time fallback: pick the config root that actually holds (or will hold)
59
+ * the connector registry.
60
+ *
61
+ * 1. Canonical `remnic/` root when its `.remnic-connectors` registry dir
62
+ * already exists (post-migration, or a fresh install that has already
63
+ * written its first connector).
64
+ * 2. Legacy `engram/` root when ONLY its `.engram-connectors` registry dir
65
+ * exists — an existing install we keep reading in place until the user
66
+ * runs `remnic migrate`.
67
+ * 3. Canonical `remnic/` root otherwise (fresh install with no registry on
68
+ * disk yet) so the first write lands at the new path.
69
+ *
70
+ * The probe looks for the REGISTRY SUBDIR (`.remnic-connectors` /
71
+ * `.engram-connectors`), not the bare config root. The config root
72
+ * `~/.config/remnic/` is created by unrelated daemon setup (e.g. the daemon's
73
+ * own `config.json`), so probing the bare root would falsely resolve to
74
+ * remnic and hide connector data that still lives under
75
+ * `~/.config/engram/.engram-connectors/` (cursor review round 1, #1620).
76
+ *
77
+ * This is a READ-time fallback. Writes go to whichever root this returns, so
78
+ * a legacy install keeps its data colocated for the active session; a fresh
79
+ * install writes straight to `remnic/`.
80
+ */
81
+ export function getActiveConnectorsConfigRoot(): string {
82
+ const canonical = getConnectorsConfigRoot();
83
+ if (fs.existsSync(path.join(canonical, REGISTRY_DIR_NAME))) return canonical;
84
+ const legacy = getLegacyConnectorsConfigRoot();
85
+ if (fs.existsSync(path.join(legacy, LEGACY_REGISTRY_DIR_NAME))) return legacy;
86
+ return canonical;
87
+ }
88
+
89
+ /**
90
+ * Path of the connector registry manifest file. The registry subdir name
91
+ * (`.remnic-connectors` vs the legacy `.engram-connectors`) is chosen from the
92
+ * active root so a pre-rename install reads its existing files without a
93
+ * rename-side migration step (#1518).
94
+ */
27
95
  export function getRegistryPath(): string {
28
- return path.join(getConnectorsConfigRoot(), REGISTRY_DIR_NAME, "registry.json");
96
+ const root = getActiveConnectorsConfigRoot();
97
+ const dirName = root === getConnectorsConfigRoot() ? REGISTRY_DIR_NAME : LEGACY_REGISTRY_DIR_NAME;
98
+ return path.join(root, dirName, "registry.json");
29
99
  }
30
100
 
31
- /** Directory holding one `<connector-id>.json` per installed connector. */
101
+ /**
102
+ * Directory holding one `<connector-id>.json` per installed connector. The
103
+ * registry subdir name follows the active root (see {@link getRegistryPath}).
104
+ */
32
105
  export function getConnectorsDir(): string {
33
- return path.join(getConnectorsConfigRoot(), REGISTRY_DIR_NAME, "connectors");
106
+ const root = getActiveConnectorsConfigRoot();
107
+ const dirName = root === getConnectorsConfigRoot() ? REGISTRY_DIR_NAME : LEGACY_REGISTRY_DIR_NAME;
108
+ return path.join(root, dirName, "connectors");
34
109
  }
35
110
 
36
111
  /**
37
112
  * Sticky-legacy evidence for `emitLegacyTools` (issue #1550): any persisted
38
- * connector entry under the legacy engram connectors dir means an existing
39
- * install whose clients may still address engram_* aliases. Missing or
40
- * unreadable dir means fresh install — no evidence, no aliases.
113
+ * connector entry under the LEGACY engram registry means an existing install
114
+ * whose clients may still address engram_* aliases. Missing or unreadable
115
+ * legacy dir means fresh install — no evidence, no aliases.
116
+ *
117
+ * Probes ONLY the legacy engram registry (`$XDG_CONFIG_HOME/engram/.engram-connectors`),
118
+ * never the active/canonical root. A fresh post-rename install that just
119
+ * wrote its first connector under `remnic/.remnic-connectors/` is NOT legacy
120
+ * evidence — counting it would flip `resolveEmitLegacyTools` to true and
121
+ * advertise deprecated `engram.*` aliases to users who never had them
122
+ * (#1620 review, codex P2). An unmigrated install still reports its entries
123
+ * here because its data lives under the engram tree.
41
124
  */
42
125
  export function hasLegacyConnectorEntries(): boolean {
43
126
  try {
44
- return fs
45
- .readdirSync(getConnectorsDir())
46
- .some((name) => name.endsWith(".json"));
127
+ const legacyDir = path.join(
128
+ getLegacyConnectorsConfigRoot(),
129
+ LEGACY_REGISTRY_DIR_NAME,
130
+ "connectors",
131
+ );
132
+ return fs.readdirSync(legacyDir).some((name) => name.endsWith(".json"));
47
133
  } catch {
48
134
  return false;
49
135
  }
@@ -17,6 +17,7 @@ export class ClaudeCodeMemoryExtensionPublisher implements MemoryExtensionPublis
17
17
  readonly hostId = "claude-code";
18
18
 
19
19
  static readonly capabilities: PublisherCapabilities = {
20
+ isStub: true,
20
21
  instructionsMd: false,
21
22
  skillsFolder: false,
22
23
  citationFormat: false,
@@ -53,6 +53,7 @@ export class CodexMemoryExtensionPublisher implements MemoryExtensionPublisher {
53
53
  readonly hostId = "codex";
54
54
 
55
55
  static readonly capabilities: PublisherCapabilities = {
56
+ isStub: false,
56
57
  instructionsMd: true,
57
58
  skillsFolder: false,
58
59
  citationFormat: true,
@@ -17,6 +17,7 @@ export class HermesMemoryExtensionPublisher implements MemoryExtensionPublisher
17
17
  readonly hostId = "hermes";
18
18
 
19
19
  static readonly capabilities: PublisherCapabilities = {
20
+ isStub: true,
20
21
  instructionsMd: false,
21
22
  skillsFolder: false,
22
23
  citationFormat: false,
@@ -73,8 +73,19 @@ export interface PublishResult {
73
73
  * Declarative capability flags that describe what a given publisher
74
74
  * can produce. Useful for feature-gating UI or doctor output without
75
75
  * instantiating the publisher.
76
+ *
77
+ * `isStub` is the explicit declaration required by #1518: when true, the
78
+ * docs-code parity gate (`scripts/check-docs-parity.mjs`) refuses any
79
+ * automation claim ("installs the plugin", "configures mcp",
80
+ * "automatically …") in the publisher's mapped install docs, because a stub
81
+ * publisher writes nothing to disk. A publisher that implements any real
82
+ * artefact writes MUST set this false. The inferred "all flags false ⇒ stub"
83
+ * detection in the parity script remains as a backstop, but the explicit
84
+ * flag is now the source of truth.
76
85
  */
77
86
  export interface PublisherCapabilities {
87
+ /** Whether the publisher is an intentional no-op stub (writes nothing). */
88
+ readonly isStub: boolean;
78
89
  /** Whether the publisher writes an instructions.md file. */
79
90
  readonly instructionsMd: boolean;
80
91
  /** Whether the publisher populates a skills folder. */
@@ -1,33 +0,0 @@
1
- import {
2
- readEnvVar,
3
- resolveHomeDir
4
- } from "./chunk-JUC24CTX.js";
5
-
6
- // src/connectors/paths.ts
7
- import fs from "fs";
8
- import path from "path";
9
- var REGISTRY_DIR_NAME = ".engram-connectors";
10
- function getConnectorsConfigRoot() {
11
- const xdgConfigHome = readEnvVar("XDG_CONFIG_HOME");
12
- return xdgConfigHome ? path.join(xdgConfigHome, "engram") : path.join(resolveHomeDir(), ".config", "engram");
13
- }
14
- function getRegistryPath() {
15
- return path.join(getConnectorsConfigRoot(), REGISTRY_DIR_NAME, "registry.json");
16
- }
17
- function getConnectorsDir() {
18
- return path.join(getConnectorsConfigRoot(), REGISTRY_DIR_NAME, "connectors");
19
- }
20
- function hasLegacyConnectorEntries() {
21
- try {
22
- return fs.readdirSync(getConnectorsDir()).some((name) => name.endsWith(".json"));
23
- } catch {
24
- return false;
25
- }
26
- }
27
-
28
- export {
29
- getRegistryPath,
30
- getConnectorsDir,
31
- hasLegacyConnectorEntries
32
- };
33
- //# sourceMappingURL=chunk-3BQOQYRB.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/connectors/paths.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\n\nimport { readEnvVar, resolveHomeDir } from \"../runtime/env.js\";\n\n/**\n * Connector registry directory name. Kept under the legacy `engram` config\n * root for backward compatibility with existing installs; the rename to a\n * `remnic` path (with a legacy read-fallback) is tracked in #1518.\n */\nexport const REGISTRY_DIR_NAME = \".engram-connectors\";\n\n/**\n * Single source of truth for the connectors config root\n * (`$XDG_CONFIG_HOME/engram` or `~/.config/engram`). Issue #1527 flagged this\n * derivation as previously duplicated across call sites — add new callers\n * here, never re-derive the path inline.\n */\nexport function getConnectorsConfigRoot(): string {\n const xdgConfigHome = readEnvVar(\"XDG_CONFIG_HOME\");\n return xdgConfigHome\n ? path.join(xdgConfigHome, \"engram\")\n : path.join(resolveHomeDir(), \".config\", \"engram\");\n}\n\n/** Path of the connector registry manifest file. */\nexport function getRegistryPath(): string {\n return path.join(getConnectorsConfigRoot(), REGISTRY_DIR_NAME, \"registry.json\");\n}\n\n/** Directory holding one `<connector-id>.json` per installed connector. */\nexport function getConnectorsDir(): string {\n return path.join(getConnectorsConfigRoot(), REGISTRY_DIR_NAME, \"connectors\");\n}\n\n/**\n * Sticky-legacy evidence for `emitLegacyTools` (issue #1550): any persisted\n * connector entry under the legacy engram connectors dir means an existing\n * install whose clients may still address engram_* aliases. Missing or\n * unreadable dir means fresh install — no evidence, no aliases.\n */\nexport function hasLegacyConnectorEntries(): boolean {\n try {\n return fs\n .readdirSync(getConnectorsDir())\n .some((name) => name.endsWith(\".json\"));\n } catch {\n return false;\n }\n}\n"],"mappings":";;;;;;AAAA,OAAO,QAAQ;AACf,OAAO,UAAU;AASV,IAAM,oBAAoB;AAQ1B,SAAS,0BAAkC;AAChD,QAAM,gBAAgB,WAAW,iBAAiB;AAClD,SAAO,gBACH,KAAK,KAAK,eAAe,QAAQ,IACjC,KAAK,KAAK,eAAe,GAAG,WAAW,QAAQ;AACrD;AAGO,SAAS,kBAA0B;AACxC,SAAO,KAAK,KAAK,wBAAwB,GAAG,mBAAmB,eAAe;AAChF;AAGO,SAAS,mBAA2B;AACzC,SAAO,KAAK,KAAK,wBAAwB,GAAG,mBAAmB,YAAY;AAC7E;AAQO,SAAS,4BAAqC;AACnD,MAAI;AACF,WAAO,GACJ,YAAY,iBAAiB,CAAC,EAC9B,KAAK,CAAC,SAAS,KAAK,SAAS,OAAO,CAAC;AAAA,EAC1C,QAAQ;AACN,WAAO;AAAA,EACT;AACF;","names":[]}