docdex 0.2.61 → 0.2.63

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 CHANGED
@@ -1,5 +1,14 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.2.63
4
+ - Add the packaged six-layer memory map over HTTP, CLI, and MCP so agents can inspect repo, profile, conversation, diary, temporal-KG, and personal-preferences lanes before selecting a memory surface.
5
+ - Extend packaged wake-up context assembly with optional recent-diary startup episodes, expose diary trace counters, and cover the new memory-layers and wake-up flows with HTTP, CLI, chat, and MCP regression tests.
6
+ - Update the packaged agent guidance to call `docdex_memory_layers` first when memory scope is unclear and to document the six-lane memory model in the shipped prompt assets.
7
+
8
+ ## 0.2.62
9
+ - Expand the packaged personal-preferences surface with claim, snapshot, feedback, and mind-clone flows across HTTP, CLI, and MCP, including review/override/forget controls and clone regression coverage.
10
+ - Harden the packaged installer's local-binary path selection by validating `docdexd --version` output before using explicit or fallback local binaries and by avoiding stale repo-local binaries during registry installs.
11
+
3
12
  ## 0.2.61
4
13
  - Add the optional personal-preferences memory subsystem with local capture, background digestion, and packaged HTTP/CLI/MCP controls for status, search, processing, export, redaction, deletion, and purge flows.
5
14
  - Align the packaged personal-preferences surface with the top-level `[personal_preferences]` config, richer lineage/materialization, review and retention controls, bounded chat-context injection, and supported-client transcript scanning.
package/assets/agents.md CHANGED
@@ -1,4 +1,4 @@
1
- ---- START OF DOCDEX INFO V0.2.61 ----
1
+ ---- START OF DOCDEX INFO V0.2.63 ----
2
2
  Docdex URL: http://127.0.0.1:28491
3
3
  Use this base URL for Docdex HTTP endpoints.
4
4
  Health check endpoint: `GET /healthz` (not `/v1/health`).
@@ -92,6 +92,11 @@ Precision tools for structural analysis. Do not rely on text search for definiti
92
92
  | docdex_memory_recall | Retrieve technical facts about the current repo. |
93
93
  | docdex_save_preference | Store a global user preference (Style, Tooling, Constraint). |
94
94
  | docdex_get_profile | Retrieve global preferences. |
95
+ | docdex_memory_layers | Inspect the six memory layers, their scope/storage, and when each one should be used. |
96
+
97
+ When unsure which memory lane fits the task, call `docdex_memory_layers` first.
98
+ - Repo memory and profile memory are the core/default lanes.
99
+ - Conversation memory, diary memory, temporal knowledge graph, and personal-preferences memory are selective lanes for continuity, handoff notes, structured recall, and richer user-specific context.
95
100
 
96
101
  ### D. Conversation Memory + Temporal Knowledge Graph
97
102
 
@@ -354,6 +359,7 @@ Do not guess fields; use these canonical shapes.
354
359
  - `docdex_dag_export`: `{ project_root, session_id|dag_session_id, format?, max_nodes? }`
355
360
  - `docdex_memory_save`: `{ project_root, text }`
356
361
  - `docdex_memory_recall`: `{ project_root, query, top_k? }`
362
+ - `docdex_memory_layers`: `{ project_root?, repo_path?, conversation_namespace? }`
357
363
  - `docdex_get_profile`: `{ agent_id }`
358
364
  - `docdex_save_preference`: `{ agent_id, category, content }`
359
365
  - `docdex_local_completion`: `{ task_type, instruction, context, max_tokens?, timeout_ms?, mode?, max_context_chars?, agent?, caller_agent_id?, caller_model?, primary_cost_per_million?, project_root?, repo_path? }`
package/lib/install.js CHANGED
@@ -219,6 +219,12 @@ function getVersion() {
219
219
  return version;
220
220
  }
221
221
 
222
+ function normalizeVersion(value) {
223
+ return String(value || "")
224
+ .trim()
225
+ .replace(/^v/i, "");
226
+ }
227
+
222
228
  function requestOptions() {
223
229
  const headers = { "User-Agent": USER_AGENT };
224
230
  const token = process.env.DOCDEX_GITHUB_TOKEN || process.env.GITHUB_TOKEN;
@@ -665,11 +671,7 @@ function shouldPreferLocalInstall({ env, localBinaryPath, pathModule, localRepoR
665
671
  if (parseEnvBool(env?.[LOCAL_FALLBACK_ENV]) === false) return false;
666
672
  if (env?.[LOCAL_BINARY_ENV]) return true;
667
673
  if (env?.npm_lifecycle_event !== "postinstall") return false;
668
- if (isLocalInstallRequest({ env, pathModule })) return true;
669
- if (!env?.INIT_CWD || !localRepoRoot) return false;
670
- const initCwd = pathModule.resolve(env.INIT_CWD);
671
- const repoRoot = pathModule.resolve(localRepoRoot);
672
- return initCwd === repoRoot || initCwd.startsWith(`${repoRoot}${pathModule.sep}`);
674
+ return isLocalInstallRequest({ env, pathModule });
673
675
  }
674
676
 
675
677
  function resolveLocalBinaryCandidate({
@@ -746,6 +748,100 @@ async function installFromLocalBinary({
746
748
  return { binaryPath: destPath, outcome: "local", outcomeCode: "local" };
747
749
  }
748
750
 
751
+ function parseBinaryVersionOutput(output) {
752
+ const text = String(output || "").trim();
753
+ if (!text) return null;
754
+ const taggedMatch = text.match(/\bdocdexd\s+v?(\d+\.\d+\.\d+(?:[-+][0-9A-Za-z._-]+)?)\b/i);
755
+ if (taggedMatch?.[1]) return normalizeVersion(taggedMatch[1]);
756
+ const genericMatch = text.match(/\bv?(\d+\.\d+\.\d+(?:[-+][0-9A-Za-z._-]+)?)\b/);
757
+ if (genericMatch?.[1]) return normalizeVersion(genericMatch[1]);
758
+ return null;
759
+ }
760
+
761
+ function probeBinaryVersion({
762
+ binaryPath,
763
+ spawnSyncFn = spawnSync
764
+ }) {
765
+ if (!binaryPath) {
766
+ return { version: null, raw: "", error: "missing_binary" };
767
+ }
768
+ const result = spawnSyncFn(binaryPath, ["--version"], {
769
+ encoding: "utf8"
770
+ });
771
+ const raw = [result?.stdout, result?.stderr].filter(Boolean).join("\n").trim();
772
+ if (result?.error) {
773
+ return {
774
+ version: null,
775
+ raw,
776
+ error: result.error?.message || String(result.error)
777
+ };
778
+ }
779
+ if (typeof result?.status === "number" && result.status !== 0) {
780
+ return {
781
+ version: null,
782
+ raw,
783
+ error: raw || `exit_${result.status}`
784
+ };
785
+ }
786
+ const version = parseBinaryVersionOutput(raw);
787
+ if (!version) {
788
+ return { version: null, raw, error: "version_unparseable" };
789
+ }
790
+ return { version, raw, error: null };
791
+ }
792
+
793
+ function validateLocalBinaryVersion({
794
+ binaryPath,
795
+ expectedVersion,
796
+ spawnSyncFn = spawnSync
797
+ }) {
798
+ const probed = probeBinaryVersion({ binaryPath, spawnSyncFn });
799
+ if (!probed.version) {
800
+ return {
801
+ ok: false,
802
+ reason: probed.error || "version_probe_failed",
803
+ expectedVersion,
804
+ detectedVersion: null,
805
+ raw: probed.raw || ""
806
+ };
807
+ }
808
+ if (normalizeVersion(probed.version) !== normalizeVersion(expectedVersion)) {
809
+ return {
810
+ ok: false,
811
+ reason: "version_mismatch",
812
+ expectedVersion,
813
+ detectedVersion: probed.version,
814
+ raw: probed.raw || ""
815
+ };
816
+ }
817
+ return {
818
+ ok: true,
819
+ reason: "matched",
820
+ expectedVersion,
821
+ detectedVersion: probed.version,
822
+ raw: probed.raw || ""
823
+ };
824
+ }
825
+
826
+ function buildLocalBinaryVersionError({ binaryPath, validation, explicitEnvOverride = false } = {}) {
827
+ const expected = validation?.expectedVersion || "unknown";
828
+ const detected = validation?.detectedVersion || "unknown";
829
+ const sourceName = explicitEnvOverride ? "DOCDEX_LOCAL_BINARY" : "local Docdex binary";
830
+ const probeHint = validation?.reason === "version_mismatch"
831
+ ? `expected ${expected} but found ${detected}`
832
+ : `version probe failed (${validation?.reason || "unknown"})`;
833
+ return new InstallerConfigError(
834
+ `${sourceName} is stale or invalid: ${probeHint}`,
835
+ {
836
+ expectedVersion: expected,
837
+ detectedVersion: validation?.detectedVersion || null,
838
+ binaryPath: binaryPath || null,
839
+ explicitEnvOverride,
840
+ probeOutput: validation?.raw || null
841
+ }
842
+ );
843
+ }
844
+
749
845
  async function maybeInstallLocalFallback({
750
846
  err,
751
847
  env,
@@ -761,7 +857,8 @@ async function maybeInstallLocalFallback({
761
857
  writeJsonFileAtomicFn,
762
858
  logger,
763
859
  localRepoRoot,
764
- localBinaryPath
860
+ localBinaryPath,
861
+ spawnSyncFn = spawnSync
765
862
  }) {
766
863
  if (!err || err.code !== "DOCDEX_CHECKSUM_UNUSABLE") return null;
767
864
  const allowFallback = parseEnvBool(env[LOCAL_FALLBACK_ENV]);
@@ -778,6 +875,18 @@ async function maybeInstallLocalFallback({
778
875
  });
779
876
  if (!candidate) return null;
780
877
 
878
+ const validation = validateLocalBinaryVersion({
879
+ binaryPath: candidate,
880
+ expectedVersion: version,
881
+ spawnSyncFn
882
+ });
883
+ if (!validation.ok) {
884
+ logger?.warn?.(
885
+ `[docdex] local fallback skipped for ${candidate}: expected ${version}, detected ${validation.detectedVersion || "unknown"} (${validation.reason}).`
886
+ );
887
+ return null;
888
+ }
889
+
781
890
  return installFromLocalBinary({
782
891
  fsModule,
783
892
  pathModule,
@@ -1780,6 +1889,7 @@ async function runInstaller(options) {
1780
1889
  const artifactNameFn = opts.artifactNameFn || artifactName;
1781
1890
  const assetPatternForPlatformKeyFn = opts.assetPatternForPlatformKeyFn || assetPatternForPlatformKey;
1782
1891
  const sha256FileFn = opts.sha256FileFn || sha256File;
1892
+ const spawnSyncFn = opts.spawnSyncFn || spawnSync;
1783
1893
  const writeJsonFileAtomicFn = opts.writeJsonFileAtomicFn || writeJsonFileAtomic;
1784
1894
  const restartFn = opts.restartFn;
1785
1895
  const localRepoRoot =
@@ -1853,6 +1963,18 @@ async function runInstaller(options) {
1853
1963
 
1854
1964
  const forceLocalBinary = Boolean(env?.[LOCAL_BINARY_ENV]);
1855
1965
  if (forceLocalBinary && localBinaryPath) {
1966
+ const validation = validateLocalBinaryVersion({
1967
+ binaryPath: localBinaryPath,
1968
+ expectedVersion: version,
1969
+ spawnSyncFn
1970
+ });
1971
+ if (!validation.ok) {
1972
+ throw buildLocalBinaryVersionError({
1973
+ binaryPath: localBinaryPath,
1974
+ validation,
1975
+ explicitEnvOverride: true
1976
+ });
1977
+ }
1856
1978
  const localInstall = await installFromLocalBinary({
1857
1979
  fsModule,
1858
1980
  pathModule,
@@ -1871,6 +1993,18 @@ async function runInstaller(options) {
1871
1993
  }
1872
1994
 
1873
1995
  if (preferLocal) {
1996
+ const validation = validateLocalBinaryVersion({
1997
+ binaryPath: localBinaryPath,
1998
+ expectedVersion: version,
1999
+ spawnSyncFn
2000
+ });
2001
+ if (!validation.ok) {
2002
+ throw buildLocalBinaryVersionError({
2003
+ binaryPath: localBinaryPath,
2004
+ validation,
2005
+ explicitEnvOverride: false
2006
+ });
2007
+ }
1874
2008
  const localInstall = await installFromLocalBinary({
1875
2009
  fsModule,
1876
2010
  pathModule,
@@ -1951,7 +2085,8 @@ async function runInstaller(options) {
1951
2085
  writeJsonFileAtomicFn,
1952
2086
  logger,
1953
2087
  localRepoRoot,
1954
- localBinaryPath
2088
+ localBinaryPath,
2089
+ spawnSyncFn
1955
2090
  });
1956
2091
  if (fallback) {
1957
2092
  return fallback;
@@ -2666,5 +2801,8 @@ module.exports = {
2666
2801
  ChecksumResolutionError,
2667
2802
  runInstaller,
2668
2803
  describeFatalError,
2669
- handleFatal
2804
+ handleFatal,
2805
+ parseBinaryVersionOutput,
2806
+ probeBinaryVersion,
2807
+ validateLocalBinaryVersion
2670
2808
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "docdex",
3
- "version": "0.2.61",
3
+ "version": "0.2.63",
4
4
  "mcpName": "io.github.bekirdag/docdex",
5
5
  "description": "Local-first documentation and code indexer with HTTP/MCP search, AST, and agent memory.",
6
6
  "bin": {