docdex 0.2.61 → 0.2.62
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 +4 -0
- package/lib/install.js +146 -8
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.2.62
|
|
4
|
+
- 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.
|
|
5
|
+
- 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.
|
|
6
|
+
|
|
3
7
|
## 0.2.61
|
|
4
8
|
- 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
9
|
- 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/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
|
-
|
|
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
|
};
|