@remnic/core 9.46.1 → 9.47.0
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/dist/access-admin-ops-surface.d.ts +2 -2
- package/dist/access-admin-ops-surface.js +3 -2
- package/dist/access-authorization-probe.d.ts +2 -2
- package/dist/access-authorization-probe.js +4 -3
- package/dist/access-boundary.d.ts +2 -2
- package/dist/access-boundary.js +3 -2
- package/dist/access-cli.js +16 -16
- package/dist/access-extraction-force-flush.d.ts +2 -2
- package/dist/access-extraction-force-flush.js +3 -2
- package/dist/access-http-lcm-compaction.d.ts +2 -2
- package/dist/access-http-lcm-compaction.js +1 -1
- package/dist/access-http-lifecycle-flush.d.ts +2 -2
- package/dist/access-http-lifecycle-flush.js +2 -2
- package/dist/access-http-offline-stream.d.ts +2 -2
- package/dist/access-http-query.js +3 -2
- package/dist/access-http.d.ts +8 -2
- package/dist/access-http.js +11 -10
- package/dist/access-identity-continuity-surface.d.ts +1 -1
- package/dist/access-identity-continuity-surface.js +3 -2
- package/dist/access-lcm-surface.d.ts +2 -2
- package/dist/access-lcm-surface.js +3 -2
- package/dist/access-mcp.d.ts +2 -2
- package/dist/access-mcp.js +7 -6
- package/dist/access-memory-search-fanout.d.ts +163 -2
- package/dist/access-memory-search-fanout.js +20 -3
- package/dist/access-namespace-preflight.js +3 -2
- package/dist/access-observe-write-surface.d.ts +2 -2
- package/dist/access-observe-write-surface.js +3 -2
- package/dist/access-offline-manifest.d.ts +1 -1
- package/dist/access-operations-batch.js +4 -3
- package/dist/access-operations.d.ts +6 -5
- package/dist/access-operations.js +6 -5
- package/dist/access-recall-concurrency.d.ts +2 -2
- package/dist/access-recall-concurrency.js +3 -2
- package/dist/access-recall-response.d.ts +2 -2
- package/dist/access-recall-response.js +3 -2
- package/dist/access-recall-surface.d.ts +2 -2
- package/dist/access-recall-surface.js +3 -2
- package/dist/access-schema.d.ts +84 -84
- package/dist/{access-service-loJadYd7.d.ts → access-service-DNBYHK33.d.ts} +2 -1
- package/dist/access-service-helpers.d.ts +2 -2
- package/dist/access-service.d.ts +2 -2
- package/dist/access-service.js +3 -2
- package/dist/access-surface-catalog.d.ts +2 -2
- package/dist/access-surface-catalog.js +1 -0
- package/dist/access-surface-catalog.js.map +1 -1
- package/dist/active-recall.js +2 -2
- package/dist/bootstrap.d.ts +1 -1
- package/dist/{chunk-WHWDBTCJ.js → chunk-74HN5QUH.js} +2 -2
- package/dist/{chunk-2DSUT7DZ.js → chunk-FQU3HTQM.js} +40 -11
- package/dist/chunk-FQU3HTQM.js.map +1 -0
- package/dist/{chunk-5LRDM4R7.js → chunk-G2L5IZV4.js} +7 -7
- package/dist/{chunk-TQZ4DVBC.js → chunk-GZ3R6XOE.js} +5 -2
- package/dist/chunk-GZ3R6XOE.js.map +1 -0
- package/dist/{chunk-5546W5SI.js → chunk-HLKPRWF4.js} +2 -2
- package/dist/chunk-IXEBUYO4.js +201 -0
- package/dist/chunk-IXEBUYO4.js.map +1 -0
- package/dist/{chunk-RCU25Z66.js → chunk-IXH2U2QT.js} +169 -58
- package/dist/chunk-IXH2U2QT.js.map +1 -0
- package/dist/{chunk-HJ3SVHUW.js → chunk-IZQ5TDFT.js} +9 -4
- package/dist/chunk-IZQ5TDFT.js.map +1 -0
- package/dist/{chunk-RVPTS4U5.js → chunk-JCNJIXZN.js} +2 -2
- package/dist/{chunk-5R6S4DJZ.js → chunk-N5XULCU3.js} +2 -2
- package/dist/{chunk-6H744ZBH.js → chunk-QISYTKG4.js} +2 -2
- package/dist/{chunk-AUMWZSE7.js → chunk-RN53QBM4.js} +4 -4
- package/dist/{chunk-M32URQXV.js → chunk-SIP5DBDN.js} +275 -334
- package/dist/chunk-SIP5DBDN.js.map +1 -0
- package/dist/{chunk-44N6ESJ4.js → chunk-TIDEL77O.js} +2 -2
- package/dist/{chunk-XBMJ35IP.js → chunk-VFZS2HAA.js} +4 -3
- package/dist/chunk-VFZS2HAA.js.map +1 -0
- package/dist/{cli-D_RcqXfZ.d.ts → cli-BWXSPxB9.d.ts} +2 -2
- package/dist/cli.d.ts +3 -3
- package/dist/cli.js +15 -15
- package/dist/config.js +2 -2
- package/dist/explicit-capture.d.ts +1 -1
- package/dist/external-wiki-access.d.ts +2 -2
- package/dist/external-wiki-access.js +4 -3
- package/dist/external-wiki-mcp-tools.d.ts +2 -2
- package/dist/index.d.ts +680 -680
- package/dist/index.js +16 -16
- package/dist/mcp-memory-inspector-app.d.ts +2 -2
- package/dist/operator-toolkit.js +3 -3
- package/dist/{orchestrator-LPGegii3.d.ts → orchestrator-CRR-6sVB.d.ts} +6 -0
- package/dist/orchestrator.d.ts +1 -1
- package/dist/orchestrator.js +17 -17
- package/dist/resume-bundles.js +3 -3
- package/dist/schemas.d.ts +76 -76
- package/dist/shared-context/manager.d.ts +8 -8
- package/dist/skills-registry.js +2 -2
- package/dist/skills-registry.js.map +1 -1
- package/dist/transfer/types.d.ts +66 -66
- package/package.json +2 -2
- package/skills/remnic-memory-workflow/SKILL.md +1 -1
- package/skills/remnic-remember/SKILL.md +1 -1
- package/src/access-http-lcm-compaction.ts +3 -0
- package/src/access-http.test.ts +645 -0
- package/src/access-http.ts +55 -4
- package/src/access-mcp.ts +1 -0
- package/src/access-memory-search-fanout.ts +305 -2
- package/src/access-operations.ts +6 -0
- package/src/access-service-namespace.test.ts +146 -0
- package/src/access-service.ts +39 -40
- package/src/access-surface-catalog.ts +1 -0
- package/src/orchestration/generic-recall-paths.ts +116 -5
- package/src/skills-registry.test.ts +14 -0
- package/src/skills-registry.ts +2 -2
- package/dist/chunk-2DSUT7DZ.js.map +0 -1
- package/dist/chunk-7HXCF4RE.js +0 -72
- package/dist/chunk-7HXCF4RE.js.map +0 -1
- package/dist/chunk-HJ3SVHUW.js.map +0 -1
- package/dist/chunk-M32URQXV.js.map +0 -1
- package/dist/chunk-RCU25Z66.js.map +0 -1
- package/dist/chunk-TQZ4DVBC.js.map +0 -1
- package/dist/chunk-XBMJ35IP.js.map +0 -1
- /package/dist/{chunk-WHWDBTCJ.js.map → chunk-74HN5QUH.js.map} +0 -0
- /package/dist/{chunk-5LRDM4R7.js.map → chunk-G2L5IZV4.js.map} +0 -0
- /package/dist/{chunk-5546W5SI.js.map → chunk-HLKPRWF4.js.map} +0 -0
- /package/dist/{chunk-RVPTS4U5.js.map → chunk-JCNJIXZN.js.map} +0 -0
- /package/dist/{chunk-5R6S4DJZ.js.map → chunk-N5XULCU3.js.map} +0 -0
- /package/dist/{chunk-6H744ZBH.js.map → chunk-QISYTKG4.js.map} +0 -0
- /package/dist/{chunk-AUMWZSE7.js.map → chunk-RN53QBM4.js.map} +0 -0
- /package/dist/{chunk-44N6ESJ4.js.map → chunk-TIDEL77O.js.map} +0 -0
|
@@ -209,7 +209,7 @@ import {
|
|
|
209
209
|
ensureBuiltInWearableConnectors,
|
|
210
210
|
getWearableConnector,
|
|
211
211
|
listWearableConnectors
|
|
212
|
-
} from "./chunk-
|
|
212
|
+
} from "./chunk-G2L5IZV4.js";
|
|
213
213
|
import {
|
|
214
214
|
RoutingRulesStore
|
|
215
215
|
} from "./chunk-XL24QQ63.js";
|
|
@@ -239,7 +239,7 @@ import {
|
|
|
239
239
|
import {
|
|
240
240
|
runNamespaceMaintenanceFanout,
|
|
241
241
|
summarizeNamespaceMaintenanceHealth
|
|
242
|
-
} from "./chunk-
|
|
242
|
+
} from "./chunk-N5XULCU3.js";
|
|
243
243
|
import {
|
|
244
244
|
NamespaceCatalog,
|
|
245
245
|
planNamespaceMaintenance
|
|
@@ -290,7 +290,7 @@ import {
|
|
|
290
290
|
} from "./chunk-64BHFFKZ.js";
|
|
291
291
|
import {
|
|
292
292
|
detectMeetings
|
|
293
|
-
} from "./chunk-
|
|
293
|
+
} from "./chunk-RN53QBM4.js";
|
|
294
294
|
import {
|
|
295
295
|
compileCorrectionRule,
|
|
296
296
|
correctionsFilePath,
|
|
@@ -302,10 +302,6 @@ import {
|
|
|
302
302
|
isValidActivityDate,
|
|
303
303
|
timezoneOffsetIso
|
|
304
304
|
} from "./chunk-7RAJ3GXO.js";
|
|
305
|
-
import {
|
|
306
|
-
assertExternalWikiRootOutsideMemoryDirCanonical,
|
|
307
|
-
isExternalWikiCollectionName
|
|
308
|
-
} from "./chunk-JV3C2MNQ.js";
|
|
309
305
|
import {
|
|
310
306
|
AMBIENT_CAPTURE_PROMPT_RULE,
|
|
311
307
|
isHighImpactPersonalFact
|
|
@@ -325,7 +321,7 @@ import {
|
|
|
325
321
|
} from "./chunk-H3FZVNRN.js";
|
|
326
322
|
import {
|
|
327
323
|
MeetingsInputError
|
|
328
|
-
} from "./chunk-
|
|
324
|
+
} from "./chunk-FQU3HTQM.js";
|
|
329
325
|
import {
|
|
330
326
|
WearablesInputError,
|
|
331
327
|
describeErrorForOperator
|
|
@@ -342,8 +338,11 @@ import {
|
|
|
342
338
|
SessionContextCoordinator,
|
|
343
339
|
capturePassiveCorrections,
|
|
344
340
|
clusterByKey,
|
|
345
|
-
detectPassiveCorrections
|
|
346
|
-
|
|
341
|
+
detectPassiveCorrections,
|
|
342
|
+
filterRecallCandidates,
|
|
343
|
+
isGenericRecallExcludedPath,
|
|
344
|
+
isTopLevelArchivePath
|
|
345
|
+
} from "./chunk-IXH2U2QT.js";
|
|
347
346
|
import {
|
|
348
347
|
importCapsule
|
|
349
348
|
} from "./chunk-A4JMGKCD.js";
|
|
@@ -522,8 +521,6 @@ import {
|
|
|
522
521
|
filterHourlySummaryMarkdownForLocalDay,
|
|
523
522
|
formatDateInTimeZone,
|
|
524
523
|
isActivityDigestPath,
|
|
525
|
-
isArtifactMemoryPath,
|
|
526
|
-
isMeetingRecordPath,
|
|
527
524
|
lifecycleRecallScoreAdjustment,
|
|
528
525
|
mapRecallSourceToXrayServedBy,
|
|
529
526
|
mergeArtifactRecallCandidates,
|
|
@@ -563,6 +560,9 @@ import {
|
|
|
563
560
|
fallbackLlmRuntimeContextFromConfig,
|
|
564
561
|
gatewayTaskChainOptions
|
|
565
562
|
} from "./chunk-C23BYTJV.js";
|
|
563
|
+
import {
|
|
564
|
+
assertExternalWikiRootOutsideMemoryDirCanonical
|
|
565
|
+
} from "./chunk-JV3C2MNQ.js";
|
|
566
566
|
import {
|
|
567
567
|
sanitizeMemoryContent
|
|
568
568
|
} from "./chunk-5GKPFL3S.js";
|
|
@@ -673,7 +673,7 @@ import {
|
|
|
673
673
|
} from "./chunk-3WCASNQZ.js";
|
|
674
674
|
|
|
675
675
|
// src/orchestrator.ts
|
|
676
|
-
import
|
|
676
|
+
import path17 from "path";
|
|
677
677
|
import { createHash as createHash6 } from "crypto";
|
|
678
678
|
|
|
679
679
|
// src/orchestration/tier-migration-coordinator.ts
|
|
@@ -2168,7 +2168,7 @@ var RecallRerankCoordinator = class _RecallRerankCoordinator {
|
|
|
2168
2168
|
namespaces,
|
|
2169
2169
|
{
|
|
2170
2170
|
readNamespaceMemories: async (ns) => (await this.getStorage(ns)).readAllMemories(),
|
|
2171
|
-
readMemoryFrontmatter: async (
|
|
2171
|
+
readMemoryFrontmatter: async (path32, preferredNamespace) => {
|
|
2172
2172
|
if (!fallbackReader) {
|
|
2173
2173
|
for (const ns of namespaces) {
|
|
2174
2174
|
try {
|
|
@@ -2180,7 +2180,7 @@ var RecallRerankCoordinator = class _RecallRerankCoordinator {
|
|
|
2180
2180
|
}
|
|
2181
2181
|
if (!fallbackReader) return null;
|
|
2182
2182
|
const memory = await this.readQmdResultMemory(
|
|
2183
|
-
|
|
2183
|
+
path32,
|
|
2184
2184
|
fallbackReader,
|
|
2185
2185
|
namespaces,
|
|
2186
2186
|
preferredNamespace
|
|
@@ -5092,7 +5092,7 @@ var ExtractionPersistCoordinator = class {
|
|
|
5092
5092
|
// src/orchestration/recall-internal.ts
|
|
5093
5093
|
import { createHash as createHash3 } from "crypto";
|
|
5094
5094
|
import { readFile as readFile2, stat, unlink } from "fs/promises";
|
|
5095
|
-
import
|
|
5095
|
+
import path7 from "path";
|
|
5096
5096
|
|
|
5097
5097
|
// src/orchestration/graph-recall-coordinator.ts
|
|
5098
5098
|
import { createHash as createHash2 } from "crypto";
|
|
@@ -5444,70 +5444,12 @@ ${preview}${suffix}`;
|
|
|
5444
5444
|
${blocks.join("\n\n")}`;
|
|
5445
5445
|
}
|
|
5446
5446
|
|
|
5447
|
-
// src/orchestration/generic-recall-paths.ts
|
|
5448
|
-
import path6 from "path";
|
|
5449
|
-
var CATEGORY_MEMORY_ROOTS = Object.fromEntries(
|
|
5450
|
-
ALL_CATEGORY_DIRS.map((directory) => [directory, true])
|
|
5451
|
-
);
|
|
5452
|
-
var RESERVED_ARCHIVE_ROOTS = { archive: true, namespaces: true };
|
|
5453
|
-
function isQmdCollectionPrefix(prefix, collection, source) {
|
|
5454
|
-
if (typeof collection !== "string" || collection.length === 0) return false;
|
|
5455
|
-
if (prefix.startsWith(`${collection}--`)) return true;
|
|
5456
|
-
if (prefix !== collection) return false;
|
|
5457
|
-
if (source === "qmd") return true;
|
|
5458
|
-
return !Object.hasOwn(CATEGORY_MEMORY_ROOTS, prefix) && !Object.hasOwn(RESERVED_ARCHIVE_ROOTS, prefix);
|
|
5459
|
-
}
|
|
5460
|
-
function normalizeQmdUriPath(relativePath, source) {
|
|
5461
|
-
if (source !== "qmd" || !relativePath.startsWith("qmd://")) return relativePath;
|
|
5462
|
-
try {
|
|
5463
|
-
const parsed = new URL(relativePath);
|
|
5464
|
-
if (parsed.protocol !== "qmd:" || !parsed.hostname) return relativePath;
|
|
5465
|
-
const collection = decodeURIComponent(parsed.hostname);
|
|
5466
|
-
const pathname = decodeURIComponent(parsed.pathname.replace(/^\/+/, ""));
|
|
5467
|
-
return pathname ? `${collection}/${pathname}` : collection;
|
|
5468
|
-
} catch {
|
|
5469
|
-
return relativePath;
|
|
5470
|
-
}
|
|
5471
|
-
}
|
|
5472
|
-
function stripQmdCollectionPrefix(relativePath, policy, source) {
|
|
5473
|
-
const normalized = path6.posix.normalize(normalizeQmdUriPath(relativePath, source).replace(/\\/g, "/"));
|
|
5474
|
-
const slashIndex = normalized.indexOf("/");
|
|
5475
|
-
if (slashIndex <= 0 || slashIndex >= normalized.length - 1) return normalized;
|
|
5476
|
-
const prefix = normalized.slice(0, slashIndex);
|
|
5477
|
-
const matchesHotCollection = isQmdCollectionPrefix(prefix, policy.qmdCollection, source);
|
|
5478
|
-
const matchesColdCollection = isQmdCollectionPrefix(prefix, policy.qmdColdCollection, source);
|
|
5479
|
-
return matchesHotCollection || matchesColdCollection ? normalized.slice(slashIndex + 1) : normalized;
|
|
5480
|
-
}
|
|
5481
|
-
function isTopLevelArchivePath(filePath, policy = {}, source = "filesystem") {
|
|
5482
|
-
const isAbsolutePath = path6.isAbsolute(filePath);
|
|
5483
|
-
const relative = policy.memoryDir && isAbsolutePath ? path6.relative(policy.memoryDir, path6.resolve(filePath)) : filePath;
|
|
5484
|
-
const normalized = !isAbsolutePath ? stripQmdCollectionPrefix(relative, policy, source) : relative;
|
|
5485
|
-
return /^(?:archive|namespaces[\\/][^\\/]+[\\/]archive)(?:[\\/]|$)/i.test(normalized);
|
|
5486
|
-
}
|
|
5487
|
-
function isExternalWikiQmdPath(filePath, source) {
|
|
5488
|
-
if (source !== "qmd") return false;
|
|
5489
|
-
const normalized = normalizeQmdUriPath(filePath, source).replace(/\\/g, "/");
|
|
5490
|
-
const slashIndex = normalized.indexOf("/");
|
|
5491
|
-
const collection = slashIndex === -1 ? normalized : normalized.slice(0, slashIndex);
|
|
5492
|
-
return isExternalWikiCollectionName(collection);
|
|
5493
|
-
}
|
|
5494
|
-
function isGenericRecallExcludedPath(filePath, policy = {}, source = "filesystem") {
|
|
5495
|
-
return isExternalWikiQmdPath(filePath, source) || isArtifactMemoryPath(filePath) || isActivityDigestPath(filePath, policy.memoryDir) || isTopLevelArchivePath(filePath, policy, source) || isMeetingRecordPath(filePath);
|
|
5496
|
-
}
|
|
5497
|
-
function filterRecallCandidates(candidates, options) {
|
|
5498
|
-
const pathPolicy = options.pathPolicy ?? (options.memoryRoot === void 0 ? void 0 : { memoryDir: options.memoryRoot });
|
|
5499
|
-
const scopedByNamespace = options.namespacesEnabled ? candidates.filter(
|
|
5500
|
-
(r) => options.recallNamespaces.includes(r.namespace ?? options.resolveNamespace(r.path))
|
|
5501
|
-
) : candidates;
|
|
5502
|
-
return scopedByNamespace.filter((r) => !isGenericRecallExcludedPath(r.path, pathPolicy, "qmd")).slice(0, Math.max(0, options.limit));
|
|
5503
|
-
}
|
|
5504
|
-
|
|
5505
5447
|
// src/orchestration/recall-profile-storage.ts
|
|
5506
|
-
import
|
|
5448
|
+
import path6 from "path";
|
|
5507
5449
|
function resolveCompositeProfileStorage(options) {
|
|
5508
5450
|
const { profileStorages, memoryDir } = options;
|
|
5509
5451
|
const emptyProfileStorage = new Proxy(
|
|
5510
|
-
{ dir:
|
|
5452
|
+
{ dir: path6.join(memoryDir, ".empty-scope-profile") },
|
|
5511
5453
|
{
|
|
5512
5454
|
get(target, prop) {
|
|
5513
5455
|
if (prop in target) return Reflect.get(target, prop);
|
|
@@ -5876,7 +5818,7 @@ var RecallInternalCoordinator = class {
|
|
|
5876
5818
|
const graphExpandedResultPaths = /* @__PURE__ */ new Set();
|
|
5877
5819
|
const graphSourceLabelsForPath = (resultPath) => {
|
|
5878
5820
|
const labels = [];
|
|
5879
|
-
const normalizedPath = resultPath.split(
|
|
5821
|
+
const normalizedPath = resultPath.split(path7.sep).join("/");
|
|
5880
5822
|
const isEntityPath = normalizedPath.startsWith("entities/") || normalizedPath.includes("/entities/");
|
|
5881
5823
|
if (graphBaselinePaths.has(resultPath)) labels.push("baseline");
|
|
5882
5824
|
if (graphExpandedResultPaths.has(resultPath))
|
|
@@ -7392,11 +7334,11 @@ ${formatted}`;
|
|
|
7392
7334
|
if (!resolveRecallAuxiliaryCapabilities(this.deps.config).compactionReset) return null;
|
|
7393
7335
|
const workspaceDir = compactionWorkspaceDir || this.deps.config.workspaceDir || defaultWorkspaceDir();
|
|
7394
7336
|
const safeSessionKey = sanitizeSessionKeyForFilename(effectiveSessionKey);
|
|
7395
|
-
const signalPath =
|
|
7337
|
+
const signalPath = path7.join(
|
|
7396
7338
|
workspaceDir,
|
|
7397
7339
|
`.compaction-reset-signal-${safeSessionKey}`
|
|
7398
7340
|
);
|
|
7399
|
-
const bootPath =
|
|
7341
|
+
const bootPath = path7.join(workspaceDir, "BOOT.md");
|
|
7400
7342
|
try {
|
|
7401
7343
|
const signalStat = await stat(signalPath).catch(() => null);
|
|
7402
7344
|
if (!signalStat) return null;
|
|
@@ -9626,10 +9568,10 @@ ${tmtNode.summary}`
|
|
|
9626
9568
|
|
|
9627
9569
|
// src/orchestration/recall-search-pipeline.ts
|
|
9628
9570
|
import { createHash as createHash4 } from "crypto";
|
|
9629
|
-
import
|
|
9571
|
+
import path9 from "path";
|
|
9630
9572
|
|
|
9631
9573
|
// src/orchestration/recall-search-prefilter.ts
|
|
9632
|
-
import
|
|
9574
|
+
import path8 from "path";
|
|
9633
9575
|
async function fetchActiveArtifactsForNamespace(deps, namespace, prompt, targetCount) {
|
|
9634
9576
|
const storage = await deps.storageRouter.storageFor(namespace);
|
|
9635
9577
|
let fetchLimit = computeArtifactCandidateFetchLimit(targetCount);
|
|
@@ -9752,7 +9694,7 @@ async function searchEmbeddingFallback(deps, query, limit) {
|
|
|
9752
9694
|
if (hits.length === 0) return [];
|
|
9753
9695
|
const results = [];
|
|
9754
9696
|
for (const hit of hits) {
|
|
9755
|
-
const fullPath =
|
|
9697
|
+
const fullPath = path8.isAbsolute(hit.path) ? hit.path : path8.join(deps.config.memoryDir, hit.path);
|
|
9756
9698
|
const memory = await deps.storage.readMemoryByPath(fullPath);
|
|
9757
9699
|
if (!memory) continue;
|
|
9758
9700
|
results.push({
|
|
@@ -10114,7 +10056,7 @@ var RecallSearchPipelineCoordinator = class {
|
|
|
10114
10056
|
const storage = await this.deps.storageRouter.storageFor(namespace);
|
|
10115
10057
|
const storageDir = typeof storage.dir === "string" && storage.dir ? storage.dir : null;
|
|
10116
10058
|
if (!storageDir) continue;
|
|
10117
|
-
const recallRoot =
|
|
10059
|
+
const recallRoot = path9.resolve(storageDir);
|
|
10118
10060
|
if (seenRecallRoots.has(recallRoot)) continue;
|
|
10119
10061
|
seenRecallRoots.add(recallRoot);
|
|
10120
10062
|
recallRoots.push(recallRoot);
|
|
@@ -10138,8 +10080,8 @@ var RecallSearchPipelineCoordinator = class {
|
|
|
10138
10080
|
if (resolvedCold) scopedResults.push(resolvedCold.result);
|
|
10139
10081
|
continue;
|
|
10140
10082
|
}
|
|
10141
|
-
if (
|
|
10142
|
-
if (recallRoots.some((recallRoot) => isPathInsideStorageRoot(recallRoot,
|
|
10083
|
+
if (path9.isAbsolute(result.path)) {
|
|
10084
|
+
if (recallRoots.some((recallRoot) => isPathInsideStorageRoot(recallRoot, path9.resolve(result.path)))) {
|
|
10143
10085
|
scopedResults.push(result);
|
|
10144
10086
|
}
|
|
10145
10087
|
continue;
|
|
@@ -11228,7 +11170,7 @@ var TurnIngestionCoordinator = class {
|
|
|
11228
11170
|
|
|
11229
11171
|
// src/orchestration/recall-introspection.ts
|
|
11230
11172
|
import { mkdir as mkdir5, readFile as readFile4, writeFile as writeFile5 } from "fs/promises";
|
|
11231
|
-
import
|
|
11173
|
+
import path11 from "path";
|
|
11232
11174
|
|
|
11233
11175
|
// src/taxonomy/default-taxonomy.ts
|
|
11234
11176
|
var DEFAULT_TAXONOMY = {
|
|
@@ -11351,7 +11293,7 @@ function generateResolverDocument(taxonomy) {
|
|
|
11351
11293
|
|
|
11352
11294
|
// src/taxonomy/taxonomy-loader.ts
|
|
11353
11295
|
import { readFile as readFile3, mkdir as mkdir4, writeFile as writeFile4 } from "fs/promises";
|
|
11354
|
-
import
|
|
11296
|
+
import path10 from "path";
|
|
11355
11297
|
var TAXONOMY_DIR = ".taxonomy";
|
|
11356
11298
|
var TAXONOMY_FILE = "taxonomy.json";
|
|
11357
11299
|
var MAX_SLUG_LENGTH = 32;
|
|
@@ -11449,7 +11391,7 @@ function validateTaxonomy(taxonomy) {
|
|
|
11449
11391
|
}
|
|
11450
11392
|
}
|
|
11451
11393
|
async function loadTaxonomy(memoryDir) {
|
|
11452
|
-
const taxonomyPath =
|
|
11394
|
+
const taxonomyPath = path10.join(memoryDir, TAXONOMY_DIR, TAXONOMY_FILE);
|
|
11453
11395
|
let raw;
|
|
11454
11396
|
try {
|
|
11455
11397
|
raw = await readFile3(taxonomyPath, "utf-8");
|
|
@@ -11499,16 +11441,16 @@ async function loadTaxonomy(memoryDir) {
|
|
|
11499
11441
|
}
|
|
11500
11442
|
async function saveTaxonomy(memoryDir, taxonomy) {
|
|
11501
11443
|
validateTaxonomy(taxonomy);
|
|
11502
|
-
const dir =
|
|
11444
|
+
const dir = path10.join(memoryDir, TAXONOMY_DIR);
|
|
11503
11445
|
await mkdir4(dir, { recursive: true });
|
|
11504
|
-
const filePath =
|
|
11446
|
+
const filePath = path10.join(dir, TAXONOMY_FILE);
|
|
11505
11447
|
await writeFile4(filePath, JSON.stringify(taxonomy, null, 2) + "\n", "utf-8");
|
|
11506
11448
|
}
|
|
11507
11449
|
function getTaxonomyDir(memoryDir) {
|
|
11508
|
-
return
|
|
11450
|
+
return path10.join(memoryDir, TAXONOMY_DIR);
|
|
11509
11451
|
}
|
|
11510
11452
|
function getTaxonomyFilePath(memoryDir) {
|
|
11511
|
-
return
|
|
11453
|
+
return path10.join(memoryDir, TAXONOMY_DIR, TAXONOMY_FILE);
|
|
11512
11454
|
}
|
|
11513
11455
|
|
|
11514
11456
|
// src/orchestration/recall-introspection.ts
|
|
@@ -11532,7 +11474,7 @@ var RecallIntrospectionCoordinator = class {
|
|
|
11532
11474
|
}
|
|
11533
11475
|
async getLastGraphRecallSnapshot(namespace) {
|
|
11534
11476
|
const storage = await this.deps.getStorage(namespace);
|
|
11535
|
-
const snapshotPath =
|
|
11477
|
+
const snapshotPath = path11.join(
|
|
11536
11478
|
storage.dir,
|
|
11537
11479
|
"state",
|
|
11538
11480
|
"last_graph_recall.json"
|
|
@@ -11571,7 +11513,7 @@ var RecallIntrospectionCoordinator = class {
|
|
|
11571
11513
|
}
|
|
11572
11514
|
async getLastIntentSnapshot(namespace) {
|
|
11573
11515
|
const storage = await this.deps.getStorage(namespace);
|
|
11574
|
-
const snapshotPath =
|
|
11516
|
+
const snapshotPath = path11.join(storage.dir, "state", "last_intent.json");
|
|
11575
11517
|
try {
|
|
11576
11518
|
const raw = await readFile4(snapshotPath, "utf-8");
|
|
11577
11519
|
const parsed = JSON.parse(raw);
|
|
@@ -11604,7 +11546,7 @@ var RecallIntrospectionCoordinator = class {
|
|
|
11604
11546
|
}
|
|
11605
11547
|
async getLastQmdRecallSnapshot(namespace) {
|
|
11606
11548
|
const storage = await this.deps.getStorage(namespace);
|
|
11607
|
-
const snapshotPath =
|
|
11549
|
+
const snapshotPath = path11.join(
|
|
11608
11550
|
storage.dir,
|
|
11609
11551
|
"state",
|
|
11610
11552
|
"last_qmd_recall.json"
|
|
@@ -11894,12 +11836,12 @@ var RecallIntrospectionCoordinator = class {
|
|
|
11894
11836
|
}
|
|
11895
11837
|
async recordLastIntentSnapshot(options) {
|
|
11896
11838
|
try {
|
|
11897
|
-
const snapshotPath =
|
|
11839
|
+
const snapshotPath = path11.join(
|
|
11898
11840
|
options.storage.dir,
|
|
11899
11841
|
"state",
|
|
11900
11842
|
"last_intent.json"
|
|
11901
11843
|
);
|
|
11902
|
-
await mkdir5(
|
|
11844
|
+
await mkdir5(path11.dirname(snapshotPath), { recursive: true });
|
|
11903
11845
|
await writeFile5(
|
|
11904
11846
|
snapshotPath,
|
|
11905
11847
|
JSON.stringify(options.snapshot, null, 2),
|
|
@@ -11911,12 +11853,12 @@ var RecallIntrospectionCoordinator = class {
|
|
|
11911
11853
|
}
|
|
11912
11854
|
async recordLastQmdRecallSnapshot(options) {
|
|
11913
11855
|
try {
|
|
11914
|
-
const snapshotPath =
|
|
11856
|
+
const snapshotPath = path11.join(
|
|
11915
11857
|
options.storage.dir,
|
|
11916
11858
|
"state",
|
|
11917
11859
|
"last_qmd_recall.json"
|
|
11918
11860
|
);
|
|
11919
|
-
await mkdir5(
|
|
11861
|
+
await mkdir5(path11.dirname(snapshotPath), { recursive: true });
|
|
11920
11862
|
await writeFile5(
|
|
11921
11863
|
snapshotPath,
|
|
11922
11864
|
JSON.stringify(options.snapshot, null, 2),
|
|
@@ -11931,8 +11873,8 @@ var RecallIntrospectionCoordinator = class {
|
|
|
11931
11873
|
const stateDir = await this.deps.resolveStateDirForNamespace(
|
|
11932
11874
|
options.namespace
|
|
11933
11875
|
);
|
|
11934
|
-
const snapshotPath =
|
|
11935
|
-
await mkdir5(
|
|
11876
|
+
const snapshotPath = path11.join(stateDir, "last_intent.json");
|
|
11877
|
+
await mkdir5(path11.dirname(snapshotPath), { recursive: true });
|
|
11936
11878
|
await writeFile5(
|
|
11937
11879
|
snapshotPath,
|
|
11938
11880
|
JSON.stringify(options.snapshot, null, 2),
|
|
@@ -11946,7 +11888,7 @@ var RecallIntrospectionCoordinator = class {
|
|
|
11946
11888
|
|
|
11947
11889
|
// src/orchestration/orchestrator-init.ts
|
|
11948
11890
|
import { readdir as readdir2, stat as stat2, unlink as unlink2 } from "fs/promises";
|
|
11949
|
-
import
|
|
11891
|
+
import path12 from "path";
|
|
11950
11892
|
var OrchestratorInitCoordinator = class {
|
|
11951
11893
|
constructor(deps) {
|
|
11952
11894
|
this.deps = deps;
|
|
@@ -12050,7 +11992,7 @@ var OrchestratorInitCoordinator = class {
|
|
|
12050
11992
|
const files = await readdir2(wsDir).catch(() => []);
|
|
12051
11993
|
for (const f of files) {
|
|
12052
11994
|
if (!f.startsWith(".compaction-reset-signal-")) continue;
|
|
12053
|
-
const fp =
|
|
11995
|
+
const fp = path12.join(wsDir, f);
|
|
12054
11996
|
const s = await stat2(fp).catch(() => null);
|
|
12055
11997
|
if (s && Date.now() - s.mtimeMs >= COMPACTION_SIGNAL_MAX_AGE_MS) {
|
|
12056
11998
|
await unlink2(fp).catch(() => {
|
|
@@ -12402,7 +12344,7 @@ var OrchestratorInitCoordinator = class {
|
|
|
12402
12344
|
};
|
|
12403
12345
|
|
|
12404
12346
|
// src/orchestration/persistence-index.ts
|
|
12405
|
-
import
|
|
12347
|
+
import path13 from "path";
|
|
12406
12348
|
var PersistenceIndexCoordinator = class {
|
|
12407
12349
|
constructor(deps) {
|
|
12408
12350
|
this.deps = deps;
|
|
@@ -12588,7 +12530,7 @@ var PersistenceIndexCoordinator = class {
|
|
|
12588
12530
|
const allMems = allMemsForGraph ?? [];
|
|
12589
12531
|
for (const m of allMems) {
|
|
12590
12532
|
if (m.frontmatter.entityRef === entityRef) {
|
|
12591
|
-
const rel =
|
|
12533
|
+
const rel = path13.relative(storage.dir, m.path);
|
|
12592
12534
|
if (rel !== memoryRelPath) entitySiblings.push(rel);
|
|
12593
12535
|
}
|
|
12594
12536
|
}
|
|
@@ -12737,7 +12679,7 @@ var PersistenceIndexCoordinator = class {
|
|
|
12737
12679
|
|
|
12738
12680
|
// src/orchestration/workspace-ops.ts
|
|
12739
12681
|
import { lstat, mkdir as mkdir6, readFile as readFile5, readdir as readdir3, realpath, writeFile as writeFile6 } from "fs/promises";
|
|
12740
|
-
import
|
|
12682
|
+
import path14 from "path";
|
|
12741
12683
|
|
|
12742
12684
|
// src/maintenance/pattern-reinforcement.ts
|
|
12743
12685
|
function patternReinforcementKey(content) {
|
|
@@ -14644,8 +14586,8 @@ var MeetingsService = class {
|
|
|
14644
14586
|
// src/orchestration/workspace-ops.ts
|
|
14645
14587
|
var MEETINGS_BUILD_DEBOUNCE_MS = 5e3;
|
|
14646
14588
|
function matchesMemoryPath(candidatePath, requestedPath, memoryDir) {
|
|
14647
|
-
const normalizedCandidate =
|
|
14648
|
-
return normalizedCandidate ===
|
|
14589
|
+
const normalizedCandidate = path14.resolve(candidatePath);
|
|
14590
|
+
return normalizedCandidate === path14.resolve(requestedPath) || normalizedCandidate === path14.resolve(memoryDir, requestedPath);
|
|
14649
14591
|
}
|
|
14650
14592
|
function accessTrackingPathCandidates(storageDir, memoryPath) {
|
|
14651
14593
|
const candidates = qmdResultPathCandidates(storageDir, memoryPath);
|
|
@@ -14653,12 +14595,12 @@ function accessTrackingPathCandidates(storageDir, memoryPath) {
|
|
|
14653
14595
|
if (!parts) return candidates;
|
|
14654
14596
|
candidates.push(
|
|
14655
14597
|
...qmdResultPathCandidates(storageDir, parts.relativePath),
|
|
14656
|
-
...qmdResultPathCandidates(
|
|
14598
|
+
...qmdResultPathCandidates(path14.join(storageDir, "cold"), parts.relativePath)
|
|
14657
14599
|
);
|
|
14658
14600
|
return [...new Set(candidates)];
|
|
14659
14601
|
}
|
|
14660
14602
|
function canonicalMemoryPath(memoryPath, memoryDir) {
|
|
14661
|
-
return
|
|
14603
|
+
return path14.resolve(path14.isAbsolute(memoryPath) ? memoryPath : path14.resolve(memoryDir, memoryPath));
|
|
14662
14604
|
}
|
|
14663
14605
|
var WorkspaceOpsCoordinator = class {
|
|
14664
14606
|
constructor(deps) {
|
|
@@ -14740,15 +14682,15 @@ var WorkspaceOpsCoordinator = class {
|
|
|
14740
14682
|
this.deps.lastFileHygieneRunAtMs = now;
|
|
14741
14683
|
if (hygiene.rotateEnabled) {
|
|
14742
14684
|
for (const rel of hygiene.rotatePaths) {
|
|
14743
|
-
const abs =
|
|
14685
|
+
const abs = path14.isAbsolute(rel) ? rel : path14.join(this.deps.config.workspaceDir, rel);
|
|
14744
14686
|
try {
|
|
14745
14687
|
const raw = await readFile5(abs, "utf-8");
|
|
14746
14688
|
if (raw.length > hygiene.rotateMaxBytes) {
|
|
14747
|
-
const archiveDir =
|
|
14689
|
+
const archiveDir = path14.join(
|
|
14748
14690
|
this.deps.config.workspaceDir,
|
|
14749
14691
|
hygiene.archiveDir
|
|
14750
14692
|
);
|
|
14751
|
-
const base =
|
|
14693
|
+
const base = path14.basename(abs);
|
|
14752
14694
|
const prefix = base.toUpperCase().replace(/\.MD$/i, "").replace(/[^A-Z0-9]+/g, "-") || "FILE";
|
|
14753
14695
|
const { newContent } = await rotateMarkdownFileToArchive({
|
|
14754
14696
|
filePath: abs,
|
|
@@ -14773,8 +14715,8 @@ var WorkspaceOpsCoordinator = class {
|
|
|
14773
14715
|
log.warn(w.message);
|
|
14774
14716
|
}
|
|
14775
14717
|
if (hygiene.warningsLogEnabled && warnings.length > 0) {
|
|
14776
|
-
const fp =
|
|
14777
|
-
await mkdir6(
|
|
14718
|
+
const fp = path14.join(this.deps.config.memoryDir, hygiene.warningsLogPath);
|
|
14719
|
+
await mkdir6(path14.dirname(fp), { recursive: true });
|
|
14778
14720
|
const stamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
14779
14721
|
const block = `
|
|
14780
14722
|
|
|
@@ -14814,7 +14756,7 @@ var WorkspaceOpsCoordinator = class {
|
|
|
14814
14756
|
for (const categoryDir of RECALL_FALLBACK_DIRS) {
|
|
14815
14757
|
if (memoryRootReal === null) break;
|
|
14816
14758
|
for (const date of datesToScan) {
|
|
14817
|
-
const dateDir =
|
|
14759
|
+
const dateDir = path14.join(storage.dir, categoryDir, date);
|
|
14818
14760
|
try {
|
|
14819
14761
|
const dirStat = await lstat(dateDir);
|
|
14820
14762
|
if (dirStat.isSymbolicLink() || !dirStat.isDirectory()) continue;
|
|
@@ -14823,7 +14765,7 @@ var WorkspaceOpsCoordinator = class {
|
|
|
14823
14765
|
for (const entry of entries) {
|
|
14824
14766
|
if (entry.isSymbolicLink()) continue;
|
|
14825
14767
|
if (!entry.name.endsWith(".md")) continue;
|
|
14826
|
-
const fullPath =
|
|
14768
|
+
const fullPath = path14.join(dateDir, entry.name);
|
|
14827
14769
|
try {
|
|
14828
14770
|
assertPathInsideRoot(memoryRootReal, await realpath(fullPath), fullPath);
|
|
14829
14771
|
const raw = await readFile5(fullPath, "utf-8");
|
|
@@ -14845,7 +14787,7 @@ var WorkspaceOpsCoordinator = class {
|
|
|
14845
14787
|
facts.push({
|
|
14846
14788
|
path: fullPath,
|
|
14847
14789
|
frontmatter: {
|
|
14848
|
-
id: fm.id ||
|
|
14790
|
+
id: fm.id || path14.basename(entry.name, ".md"),
|
|
14849
14791
|
category: fm.category || "fact",
|
|
14850
14792
|
created,
|
|
14851
14793
|
updated: fm.updated || created,
|
|
@@ -14868,13 +14810,13 @@ var WorkspaceOpsCoordinator = class {
|
|
|
14868
14810
|
return a.frontmatter.created < b.frontmatter.created ? -1 : 1;
|
|
14869
14811
|
});
|
|
14870
14812
|
const hourlySummaries = [];
|
|
14871
|
-
const hourlyBaseDir =
|
|
14813
|
+
const hourlyBaseDir = path14.join(storage.dir, "summaries", "hourly");
|
|
14872
14814
|
try {
|
|
14873
14815
|
const sessionKeys = await readdir3(hourlyBaseDir, { withFileTypes: true });
|
|
14874
14816
|
for (const sk of sessionKeys) {
|
|
14875
14817
|
if (!sk.isDirectory()) continue;
|
|
14876
14818
|
for (const date of datesToScan) {
|
|
14877
|
-
const summaryFile =
|
|
14819
|
+
const summaryFile = path14.join(hourlyBaseDir, sk.name, `${date}.md`);
|
|
14878
14820
|
try {
|
|
14879
14821
|
const raw = await readFile5(summaryFile, "utf-8");
|
|
14880
14822
|
const filtered = filterHourlySummaryMarkdownForLocalDay(
|
|
@@ -15338,18 +15280,18 @@ ${reflectionsContent.trim()}
|
|
|
15338
15280
|
// src/orchestration/namespace-read-fanout.ts
|
|
15339
15281
|
import { existsSync, readFileSync } from "fs";
|
|
15340
15282
|
import { stat as stat3 } from "fs/promises";
|
|
15341
|
-
import
|
|
15283
|
+
import path16 from "path";
|
|
15342
15284
|
|
|
15343
15285
|
// src/orchestration/orchestrator-namespace-scope.ts
|
|
15344
|
-
import
|
|
15286
|
+
import path15 from "path";
|
|
15345
15287
|
function computeSemanticDedupScope(targetStorage, config) {
|
|
15346
15288
|
if (!resolveNamespaceCapabilities(config).namespaces) return {};
|
|
15347
|
-
const memoryDir =
|
|
15348
|
-
const storageDir =
|
|
15289
|
+
const memoryDir = path15.resolve(config.memoryDir);
|
|
15290
|
+
const storageDir = path15.resolve(targetStorage.dir);
|
|
15349
15291
|
if (storageDir === memoryDir) {
|
|
15350
15292
|
return { pathExcludePrefixes: ["namespaces/"] };
|
|
15351
15293
|
}
|
|
15352
|
-
let rel =
|
|
15294
|
+
let rel = path15.relative(memoryDir, storageDir);
|
|
15353
15295
|
if (!rel || rel.startsWith("..")) {
|
|
15354
15296
|
log.debug(
|
|
15355
15297
|
`semantic dedup: target storage dir ${storageDir} is outside memoryDir ${memoryDir}; scoping lookup to absolute path prefix`
|
|
@@ -15402,7 +15344,7 @@ var NamespaceReadFanoutCoordinator = class {
|
|
|
15402
15344
|
loadNamespaceStorageDirHintsFromCatalog() {
|
|
15403
15345
|
if (this.deps.namespaceStorageDirHintsLoaded || !this.deps.namespaceCatalog.enabled) return;
|
|
15404
15346
|
this.deps.namespaceStorageDirHintsLoaded = true;
|
|
15405
|
-
const catalogPath =
|
|
15347
|
+
const catalogPath = path16.join(this.deps.config.memoryDir, "state", "namespaces.jsonl");
|
|
15406
15348
|
if (!existsSync(catalogPath)) return;
|
|
15407
15349
|
let body;
|
|
15408
15350
|
try {
|
|
@@ -15439,7 +15381,7 @@ var NamespaceReadFanoutCoordinator = class {
|
|
|
15439
15381
|
if (!this.deps.storageDirMatchesNamespaceHint(record.namespace, record.storageDir)) {
|
|
15440
15382
|
continue;
|
|
15441
15383
|
}
|
|
15442
|
-
const resolvedStorageDir =
|
|
15384
|
+
const resolvedStorageDir = path16.resolve(record.storageDir);
|
|
15443
15385
|
const current = preferredByStorageDir.get(resolvedStorageDir);
|
|
15444
15386
|
preferredByStorageDir.set(
|
|
15445
15387
|
resolvedStorageDir,
|
|
@@ -15620,12 +15562,12 @@ var NamespaceReadFanoutCoordinator = class {
|
|
|
15620
15562
|
}
|
|
15621
15563
|
async resolveStateDirForNamespace(namespace) {
|
|
15622
15564
|
if (!resolveNamespaceCapabilities(this.deps.config).namespaces) {
|
|
15623
|
-
return
|
|
15565
|
+
return path16.join(this.deps.config.memoryDir, "state");
|
|
15624
15566
|
}
|
|
15625
15567
|
if (namespace !== this.deps.config.defaultNamespace) {
|
|
15626
|
-
return
|
|
15568
|
+
return path16.join(this.deps.config.memoryDir, "namespaces", namespace, "state");
|
|
15627
15569
|
}
|
|
15628
|
-
const candidate =
|
|
15570
|
+
const candidate = path16.join(
|
|
15629
15571
|
this.deps.config.memoryDir,
|
|
15630
15572
|
"namespaces",
|
|
15631
15573
|
this.deps.config.defaultNamespace
|
|
@@ -15633,11 +15575,11 @@ var NamespaceReadFanoutCoordinator = class {
|
|
|
15633
15575
|
try {
|
|
15634
15576
|
const candidateStat = await stat3(candidate);
|
|
15635
15577
|
if (candidateStat.isDirectory()) {
|
|
15636
|
-
return
|
|
15578
|
+
return path16.join(candidate, "state");
|
|
15637
15579
|
}
|
|
15638
15580
|
} catch {
|
|
15639
15581
|
}
|
|
15640
|
-
return
|
|
15582
|
+
return path16.join(this.deps.config.memoryDir, "state");
|
|
15641
15583
|
}
|
|
15642
15584
|
namespaceFromPath(p) {
|
|
15643
15585
|
if (!resolveNamespaceCapabilities(this.deps.config).namespaces) return this.deps.config.defaultNamespace;
|
|
@@ -16416,7 +16358,7 @@ var Orchestrator = class {
|
|
|
16416
16358
|
const defaultNs = normalizeNamespaceIdentity(this.config.defaultNamespace);
|
|
16417
16359
|
if (ns !== defaultNs && !isSafeRouteNamespace(ns)) return;
|
|
16418
16360
|
if (!this.storageDirMatchesNamespaceHint(ns, storageDir)) return;
|
|
16419
|
-
const resolvedStorageDir =
|
|
16361
|
+
const resolvedStorageDir = path17.resolve(storageDir);
|
|
16420
16362
|
let hints = this.namespaceStorageDirHints.get(resolvedStorageDir);
|
|
16421
16363
|
if (!hints) {
|
|
16422
16364
|
hints = /* @__PURE__ */ new Set();
|
|
@@ -16427,21 +16369,21 @@ var Orchestrator = class {
|
|
|
16427
16369
|
storageDirMatchesNamespaceHint(namespace, storageDir) {
|
|
16428
16370
|
const ns = normalizeNamespaceIdentity(namespace);
|
|
16429
16371
|
if (!ns) return false;
|
|
16430
|
-
const resolvedStorageDir =
|
|
16431
|
-
const resolvedMemoryDir =
|
|
16372
|
+
const resolvedStorageDir = path17.resolve(storageDir);
|
|
16373
|
+
const resolvedMemoryDir = path17.resolve(this.config.memoryDir);
|
|
16432
16374
|
const defaultNs = normalizeNamespaceIdentity(this.config.defaultNamespace);
|
|
16433
16375
|
if (resolvedStorageDir === resolvedMemoryDir) return ns === defaultNs;
|
|
16434
|
-
const resolvedNamespacesDir =
|
|
16376
|
+
const resolvedNamespacesDir = path17.join(resolvedMemoryDir, "namespaces");
|
|
16435
16377
|
if (!isPathInsideStorageRoot(resolvedNamespacesDir, resolvedStorageDir)) return false;
|
|
16436
|
-
const rawRoot =
|
|
16437
|
-
const tokenRoot =
|
|
16378
|
+
const rawRoot = path17.resolve(resolvedNamespacesDir, ns);
|
|
16379
|
+
const tokenRoot = path17.resolve(resolvedNamespacesDir, namespaceIdentityToken(ns));
|
|
16438
16380
|
return resolvedStorageDir === rawRoot || resolvedStorageDir === tokenRoot;
|
|
16439
16381
|
}
|
|
16440
16382
|
namespaceStorageDirHintOwnershipRank(record, resolvedStorageDir, configured) {
|
|
16441
|
-
if (resolvedStorageDir ===
|
|
16383
|
+
if (resolvedStorageDir === path17.resolve(this.config.memoryDir)) {
|
|
16442
16384
|
return record.namespace === normalizeNamespaceIdentity(this.config.defaultNamespace) ? 0 : 3;
|
|
16443
16385
|
}
|
|
16444
|
-
const leaf =
|
|
16386
|
+
const leaf = path17.basename(resolvedStorageDir);
|
|
16445
16387
|
const tokenOwnsRoot = namespaceIdentityToken(record.namespace) === leaf;
|
|
16446
16388
|
if (tokenOwnsRoot && configured.has(record.namespace)) return 0;
|
|
16447
16389
|
if (record.namespace === leaf) return 1;
|
|
@@ -16581,7 +16523,7 @@ var Orchestrator = class {
|
|
|
16581
16523
|
StorageManager.setScopedCacheInvalidationDefault(config.memoryDir, scopedCacheInvalidationEnabled);
|
|
16582
16524
|
this.profiler = new ProfilingCollector({
|
|
16583
16525
|
enabled: resolvePipelineProcessingCapabilities(this.config).profiling,
|
|
16584
|
-
storageDir: config.profilingStorageDir ||
|
|
16526
|
+
storageDir: config.profilingStorageDir || path17.join(config.memoryDir, "profiling"),
|
|
16585
16527
|
maxTraces: config.profilingMaxTraces
|
|
16586
16528
|
});
|
|
16587
16529
|
this.namespaceCatalog = new NamespaceCatalog(config);
|
|
@@ -16668,7 +16610,7 @@ var Orchestrator = class {
|
|
|
16668
16610
|
this.compounding = resolveConsolidationCapabilities(config).compounding ? new CompoundingEngine(config, this.storage) : void 0;
|
|
16669
16611
|
this.buffer = new SmartBuffer(config, this.storage);
|
|
16670
16612
|
this.transcript = new TranscriptManager(config);
|
|
16671
|
-
this.conversationIndexDir =
|
|
16613
|
+
this.conversationIndexDir = path17.join(
|
|
16672
16614
|
config.memoryDir,
|
|
16673
16615
|
"conversation-index",
|
|
16674
16616
|
"chunks"
|
|
@@ -16815,7 +16757,7 @@ var Orchestrator = class {
|
|
|
16815
16757
|
saveContentHashIndexes: () => this.saveContentHashIndexes()
|
|
16816
16758
|
});
|
|
16817
16759
|
this.threading = new ThreadingManager(
|
|
16818
|
-
|
|
16760
|
+
path17.join(config.memoryDir, "threads"),
|
|
16819
16761
|
config.threadingGapMinutes
|
|
16820
16762
|
);
|
|
16821
16763
|
const lifecycleCaps = resolveMemoryLifecycleCapabilities(config);
|
|
@@ -18921,9 +18863,9 @@ function readStructuralSymbol(entry) {
|
|
|
18921
18863
|
const rec = entry;
|
|
18922
18864
|
const symbol = typeof rec.symbol === "string" ? rec.symbol.trim() : "";
|
|
18923
18865
|
if (!symbol) return null;
|
|
18924
|
-
const
|
|
18866
|
+
const path32 = typeof rec.path === "string" && rec.path.length > 0 ? rec.path : void 0;
|
|
18925
18867
|
const kind = typeof rec.kind === "string" && rec.kind.length > 0 ? rec.kind : void 0;
|
|
18926
|
-
const item =
|
|
18868
|
+
const item = path32 !== void 0 && kind !== void 0 ? { symbol, path: path32, kind } : path32 !== void 0 ? { symbol, path: path32 } : kind !== void 0 ? { symbol, kind } : { symbol };
|
|
18927
18869
|
return item;
|
|
18928
18870
|
}
|
|
18929
18871
|
function classifySpawnError(err) {
|
|
@@ -18997,7 +18939,7 @@ var DEFAULT_GRACE_PERIOD_DAYS = 7;
|
|
|
18997
18939
|
|
|
18998
18940
|
// src/binary-lifecycle/backend.ts
|
|
18999
18941
|
import fsp from "fs/promises";
|
|
19000
|
-
import
|
|
18942
|
+
import path18 from "path";
|
|
19001
18943
|
var FilesystemBackend = class {
|
|
19002
18944
|
type = "filesystem";
|
|
19003
18945
|
basePath;
|
|
@@ -19005,19 +18947,19 @@ var FilesystemBackend = class {
|
|
|
19005
18947
|
if (!basePath || basePath.trim().length === 0) {
|
|
19006
18948
|
throw new Error("FilesystemBackend requires a non-empty basePath");
|
|
19007
18949
|
}
|
|
19008
|
-
this.basePath =
|
|
18950
|
+
this.basePath = path18.resolve(basePath);
|
|
19009
18951
|
}
|
|
19010
18952
|
resolveRemotePath(remotePath) {
|
|
19011
|
-
const resolved =
|
|
19012
|
-
const relative =
|
|
19013
|
-
if (relative === ".." || relative.startsWith(`..${
|
|
18953
|
+
const resolved = path18.isAbsolute(remotePath) ? path18.resolve(remotePath) : path18.resolve(this.basePath, remotePath);
|
|
18954
|
+
const relative = path18.relative(this.basePath, resolved);
|
|
18955
|
+
if (relative === ".." || relative.startsWith(`..${path18.sep}`) || path18.isAbsolute(relative)) {
|
|
19014
18956
|
throw new Error(`FilesystemBackend remotePath escapes basePath: ${JSON.stringify(remotePath)}`);
|
|
19015
18957
|
}
|
|
19016
18958
|
return resolved;
|
|
19017
18959
|
}
|
|
19018
18960
|
isInsideBase(candidate, realBase) {
|
|
19019
|
-
const relative =
|
|
19020
|
-
return relative === "" || relative !== ".." && !relative.startsWith(`..${
|
|
18961
|
+
const relative = path18.relative(realBase, candidate);
|
|
18962
|
+
return relative === "" || relative !== ".." && !relative.startsWith(`..${path18.sep}`) && !path18.isAbsolute(relative);
|
|
19021
18963
|
}
|
|
19022
18964
|
async realBasePathIfExists() {
|
|
19023
18965
|
try {
|
|
@@ -19046,13 +18988,13 @@ var FilesystemBackend = class {
|
|
|
19046
18988
|
}
|
|
19047
18989
|
async ensureSafeParentDirectory(dest) {
|
|
19048
18990
|
const realBase = await this.ensureBaseDirectory();
|
|
19049
|
-
const destDir =
|
|
19050
|
-
const relativeDir =
|
|
19051
|
-
const segments = relativeDir === "" ? [] : relativeDir.split(
|
|
18991
|
+
const destDir = path18.dirname(dest);
|
|
18992
|
+
const relativeDir = path18.relative(this.basePath, destDir);
|
|
18993
|
+
const segments = relativeDir === "" ? [] : relativeDir.split(path18.sep);
|
|
19052
18994
|
let current = this.basePath;
|
|
19053
18995
|
for (const segment of segments) {
|
|
19054
18996
|
if (segment === "." || segment === "") continue;
|
|
19055
|
-
current =
|
|
18997
|
+
current = path18.join(current, segment);
|
|
19056
18998
|
try {
|
|
19057
18999
|
const stat5 = await fsp.lstat(current);
|
|
19058
19000
|
if (stat5.isSymbolicLink()) {
|
|
@@ -19080,13 +19022,13 @@ var FilesystemBackend = class {
|
|
|
19080
19022
|
if (realBase === null) {
|
|
19081
19023
|
return null;
|
|
19082
19024
|
}
|
|
19083
|
-
const destDir =
|
|
19084
|
-
const relativeDir =
|
|
19085
|
-
const segments = relativeDir === "" ? [] : relativeDir.split(
|
|
19025
|
+
const destDir = path18.dirname(dest);
|
|
19026
|
+
const relativeDir = path18.relative(this.basePath, destDir);
|
|
19027
|
+
const segments = relativeDir === "" ? [] : relativeDir.split(path18.sep);
|
|
19086
19028
|
let current = this.basePath;
|
|
19087
19029
|
for (const segment of segments) {
|
|
19088
19030
|
if (segment === "." || segment === "") continue;
|
|
19089
|
-
current =
|
|
19031
|
+
current = path18.join(current, segment);
|
|
19090
19032
|
let stat5;
|
|
19091
19033
|
try {
|
|
19092
19034
|
stat5 = await fsp.lstat(current);
|
|
@@ -19134,7 +19076,7 @@ var FilesystemBackend = class {
|
|
|
19134
19076
|
return dest;
|
|
19135
19077
|
}
|
|
19136
19078
|
async upload(localPath, remotePath) {
|
|
19137
|
-
if (
|
|
19079
|
+
if (path18.isAbsolute(remotePath)) {
|
|
19138
19080
|
throw new Error(`FilesystemBackend upload remotePath must be relative: ${JSON.stringify(remotePath)}`);
|
|
19139
19081
|
}
|
|
19140
19082
|
const dest = this.resolveRemotePath(remotePath);
|
|
@@ -19207,7 +19149,7 @@ function createBackend(cfg) {
|
|
|
19207
19149
|
|
|
19208
19150
|
// src/binary-lifecycle/scanner.ts
|
|
19209
19151
|
import fsp2 from "fs/promises";
|
|
19210
|
-
import
|
|
19152
|
+
import path19 from "path";
|
|
19211
19153
|
import crypto from "crypto";
|
|
19212
19154
|
function matchesPatterns(filename, patterns) {
|
|
19213
19155
|
const lower = filename.toLowerCase();
|
|
@@ -19232,8 +19174,8 @@ async function scanForBinaries(memoryDir, config, manifest) {
|
|
|
19232
19174
|
return;
|
|
19233
19175
|
}
|
|
19234
19176
|
for (const entry of entries) {
|
|
19235
|
-
const fullPath =
|
|
19236
|
-
const relativePath =
|
|
19177
|
+
const fullPath = path19.join(dir, entry.name);
|
|
19178
|
+
const relativePath = path19.relative(memoryDir, fullPath).split(path19.sep).join("/");
|
|
19237
19179
|
if (entry.isDirectory()) {
|
|
19238
19180
|
if (entry.name === ".binary-lifecycle") continue;
|
|
19239
19181
|
await walk(fullPath);
|
|
@@ -19273,15 +19215,15 @@ async function hashFile(filePath) {
|
|
|
19273
19215
|
|
|
19274
19216
|
// src/binary-lifecycle/manifest.ts
|
|
19275
19217
|
import fsp3 from "fs/promises";
|
|
19276
|
-
import
|
|
19218
|
+
import path20 from "path";
|
|
19277
19219
|
import crypto2 from "crypto";
|
|
19278
19220
|
var MANIFEST_DIR = ".binary-lifecycle";
|
|
19279
19221
|
var MANIFEST_FILE = "manifest.json";
|
|
19280
19222
|
function manifestDir(memoryDir) {
|
|
19281
|
-
return
|
|
19223
|
+
return path20.join(memoryDir, MANIFEST_DIR);
|
|
19282
19224
|
}
|
|
19283
19225
|
function manifestPath(memoryDir) {
|
|
19284
|
-
return
|
|
19226
|
+
return path20.join(memoryDir, MANIFEST_DIR, MANIFEST_FILE);
|
|
19285
19227
|
}
|
|
19286
19228
|
async function readManifest(memoryDir) {
|
|
19287
19229
|
const filePath = manifestPath(memoryDir);
|
|
@@ -19333,13 +19275,13 @@ function emptyManifest() {
|
|
|
19333
19275
|
|
|
19334
19276
|
// src/binary-lifecycle/pipeline.ts
|
|
19335
19277
|
import fsp4 from "fs/promises";
|
|
19336
|
-
import
|
|
19278
|
+
import path21 from "path";
|
|
19337
19279
|
import crypto3 from "crypto";
|
|
19338
19280
|
var historicalIdCache = new HistoricalEntityCanonicalIdCache();
|
|
19339
19281
|
function isRecallCorpusMarkdown(mdPath, memoryDir) {
|
|
19340
|
-
const rel =
|
|
19341
|
-
if (rel.startsWith("..") ||
|
|
19342
|
-
const top = rel.split(
|
|
19282
|
+
const rel = path21.relative(memoryDir, mdPath);
|
|
19283
|
+
if (rel.startsWith("..") || path21.isAbsolute(rel)) return false;
|
|
19284
|
+
const top = rel.split(path21.sep)[0];
|
|
19343
19285
|
return RECALL_FALLBACK_DIRS.includes(top);
|
|
19344
19286
|
}
|
|
19345
19287
|
async function hashFile2(filePath) {
|
|
@@ -19363,13 +19305,13 @@ function escapeRegex(s) {
|
|
|
19363
19305
|
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
19364
19306
|
}
|
|
19365
19307
|
function resolveManifestAssetPath(memoryDir, originalPath) {
|
|
19366
|
-
if (originalPath.length === 0 || originalPath.includes("\0") || originalPath.includes("\\") ||
|
|
19308
|
+
if (originalPath.length === 0 || originalPath.includes("\0") || originalPath.includes("\\") || path21.isAbsolute(originalPath) || path21.win32.isAbsolute(originalPath)) {
|
|
19367
19309
|
return null;
|
|
19368
19310
|
}
|
|
19369
|
-
const memoryRoot =
|
|
19370
|
-
const fullPath =
|
|
19371
|
-
const relative =
|
|
19372
|
-
if (relative === "" || relative === ".." || relative.startsWith(`..${
|
|
19311
|
+
const memoryRoot = path21.resolve(memoryDir);
|
|
19312
|
+
const fullPath = path21.resolve(memoryRoot, originalPath);
|
|
19313
|
+
const relative = path21.relative(memoryRoot, fullPath);
|
|
19314
|
+
if (relative === "" || relative === ".." || relative.startsWith(`..${path21.sep}`) || path21.isAbsolute(relative)) {
|
|
19373
19315
|
return null;
|
|
19374
19316
|
}
|
|
19375
19317
|
return fullPath;
|
|
@@ -19380,7 +19322,7 @@ function validateBinaryLifecycleConfig(config) {
|
|
|
19380
19322
|
}
|
|
19381
19323
|
}
|
|
19382
19324
|
function remotePathForAsset(backend, relPath) {
|
|
19383
|
-
const normalized = relPath.split(
|
|
19325
|
+
const normalized = relPath.split(path21.sep).join("/");
|
|
19384
19326
|
if (backend.type === "filesystem") {
|
|
19385
19327
|
return `.binary-lifecycle/mirrors/${normalized}`;
|
|
19386
19328
|
}
|
|
@@ -19393,11 +19335,11 @@ async function stageMirror(memoryDir, newPaths, backend, assets, log2, dryRun) {
|
|
|
19393
19335
|
let mirrored = 0;
|
|
19394
19336
|
const errors = [];
|
|
19395
19337
|
for (const relPath of newPaths) {
|
|
19396
|
-
const fullPath =
|
|
19338
|
+
const fullPath = path21.join(memoryDir, relPath);
|
|
19397
19339
|
try {
|
|
19398
19340
|
const stat5 = await fsp4.stat(fullPath);
|
|
19399
19341
|
const contentHash = await hashFile2(fullPath);
|
|
19400
|
-
const ext =
|
|
19342
|
+
const ext = path21.extname(relPath);
|
|
19401
19343
|
const mimeType = guessMimeType(ext);
|
|
19402
19344
|
const remotePath = remotePathForAsset(backend, relPath);
|
|
19403
19345
|
let backendLocation = remotePath;
|
|
@@ -19535,7 +19477,7 @@ async function stageRedirect(memoryDir, assets, log2, dryRun, readMarkdownFile,
|
|
|
19535
19477
|
for (const update of updates) {
|
|
19536
19478
|
try {
|
|
19537
19479
|
await withRawEntityPageMutation(memoryDir, update.mdPath, async () => {
|
|
19538
|
-
const stateDir =
|
|
19480
|
+
const stateDir = path21.join(memoryDir, "state");
|
|
19539
19481
|
const kind = classifyEntityRefWritePath(memoryDir, update.mdPath);
|
|
19540
19482
|
if (kind === "memory") {
|
|
19541
19483
|
const idsAtWrite = historicalIdCache.get(stateDir);
|
|
@@ -19629,10 +19571,10 @@ async function countRemainingLocalReferences(memoryDir, asset, assetAbsolute, md
|
|
|
19629
19571
|
return { remaining, errors };
|
|
19630
19572
|
}
|
|
19631
19573
|
function markdownReferencePattern(asset, assetAbsolute, mdPath) {
|
|
19632
|
-
const mdDir =
|
|
19574
|
+
const mdDir = path21.dirname(mdPath);
|
|
19633
19575
|
const candidates = /* @__PURE__ */ new Set();
|
|
19634
19576
|
const addCandidate = (candidate) => {
|
|
19635
|
-
const normalized = candidate.split(
|
|
19577
|
+
const normalized = candidate.split(path21.sep).join("/");
|
|
19636
19578
|
if (normalized.length === 0) return;
|
|
19637
19579
|
candidates.add(normalized);
|
|
19638
19580
|
const isParentTraversal = normalized === ".." || normalized.startsWith("../");
|
|
@@ -19640,10 +19582,10 @@ function markdownReferencePattern(asset, assetAbsolute, mdPath) {
|
|
|
19640
19582
|
candidates.add(`./${normalized}`);
|
|
19641
19583
|
}
|
|
19642
19584
|
};
|
|
19643
|
-
addCandidate(
|
|
19644
|
-
const originalPath = asset.originalPath.split(
|
|
19645
|
-
const originalAsFileRelative =
|
|
19646
|
-
if (
|
|
19585
|
+
addCandidate(path21.relative(mdDir, assetAbsolute));
|
|
19586
|
+
const originalPath = asset.originalPath.split(path21.sep).join("/");
|
|
19587
|
+
const originalAsFileRelative = path21.resolve(mdDir, ...originalPath.split("/"));
|
|
19588
|
+
if (path21.resolve(originalAsFileRelative) === path21.resolve(assetAbsolute)) {
|
|
19647
19589
|
addCandidate(originalPath);
|
|
19648
19590
|
}
|
|
19649
19591
|
addCandidate(`/${originalPath}`);
|
|
@@ -19739,7 +19681,7 @@ async function findMarkdownFiles(dir) {
|
|
|
19739
19681
|
return;
|
|
19740
19682
|
}
|
|
19741
19683
|
for (const entry of entries) {
|
|
19742
|
-
const full =
|
|
19684
|
+
const full = path21.join(current, entry.name);
|
|
19743
19685
|
if (entry.isDirectory()) {
|
|
19744
19686
|
if (entry.name === ".binary-lifecycle") continue;
|
|
19745
19687
|
await walk(full);
|
|
@@ -19814,7 +19756,7 @@ async function runBinaryLifecyclePipeline(memoryDir, config, backend, log2, opts
|
|
|
19814
19756
|
|
|
19815
19757
|
// src/projection/index.ts
|
|
19816
19758
|
import fs from "fs";
|
|
19817
|
-
import
|
|
19759
|
+
import path22 from "path";
|
|
19818
19760
|
var VALID_PROJECTION_CATEGORIES = new Set(ALL_CATEGORY_KEYS);
|
|
19819
19761
|
async function generateContextTree(options) {
|
|
19820
19762
|
const startTime = Date.now();
|
|
@@ -19829,8 +19771,8 @@ async function generateContextTree(options) {
|
|
|
19829
19771
|
let nodesGenerated = 0;
|
|
19830
19772
|
let nodesSkipped = 0;
|
|
19831
19773
|
const categoryCounts = {};
|
|
19832
|
-
const resolvedMemoryDir =
|
|
19833
|
-
const resolvedOutputDir =
|
|
19774
|
+
const resolvedMemoryDir = path22.resolve(memoryDir);
|
|
19775
|
+
const resolvedOutputDir = path22.resolve(outputDir);
|
|
19834
19776
|
const requestedCategories = validateProjectionCategories(filterCategories);
|
|
19835
19777
|
const realMemoryDir = assertSafeMemoryRoot(resolvedMemoryDir);
|
|
19836
19778
|
assertNotSymlink(resolvedOutputDir, "context tree outputDir");
|
|
@@ -19868,7 +19810,7 @@ async function generateContextTree(options) {
|
|
|
19868
19810
|
}
|
|
19869
19811
|
}
|
|
19870
19812
|
if (includeEntities) {
|
|
19871
|
-
const entitiesDir =
|
|
19813
|
+
const entitiesDir = path22.join(memoryDir, "entities");
|
|
19872
19814
|
if (fs.existsSync(entitiesDir)) {
|
|
19873
19815
|
assertSafeInputRoot(realMemoryDir, entitiesDir, "entities root");
|
|
19874
19816
|
categoryCounts["entity"] = 0;
|
|
@@ -19880,7 +19822,7 @@ async function generateContextTree(options) {
|
|
|
19880
19822
|
continue;
|
|
19881
19823
|
}
|
|
19882
19824
|
const content = fs.readFileSync(filePath, "utf8");
|
|
19883
|
-
const fileName =
|
|
19825
|
+
const fileName = path22.basename(filePath, ".md");
|
|
19884
19826
|
const node = projectEntityNode(fileName, content);
|
|
19885
19827
|
const outputPath = resolveContainedOutputPath(realOutputDir, "entities", `${fileName}.md`);
|
|
19886
19828
|
writeProjectedContent(realOutputDir, outputPath, node.content);
|
|
@@ -19892,7 +19834,7 @@ async function generateContextTree(options) {
|
|
|
19892
19834
|
}
|
|
19893
19835
|
const shouldIncludeQuestions = includeQuestions && (requestedCategories === void 0 || requestedCategories.includes("question"));
|
|
19894
19836
|
if (shouldIncludeQuestions) {
|
|
19895
|
-
const questionsDir =
|
|
19837
|
+
const questionsDir = path22.join(memoryDir, "questions");
|
|
19896
19838
|
if (fs.existsSync(questionsDir)) {
|
|
19897
19839
|
assertSafeInputRoot(realMemoryDir, questionsDir, "questions root");
|
|
19898
19840
|
categoryCounts["question"] = 0;
|
|
@@ -19933,8 +19875,8 @@ async function generateContextTree(options) {
|
|
|
19933
19875
|
};
|
|
19934
19876
|
}
|
|
19935
19877
|
function isPathInside(root, candidate) {
|
|
19936
|
-
const relative =
|
|
19937
|
-
return relative === "" || !relative.startsWith("..") && !
|
|
19878
|
+
const relative = path22.relative(root, candidate);
|
|
19879
|
+
return relative === "" || !relative.startsWith("..") && !path22.isAbsolute(relative);
|
|
19938
19880
|
}
|
|
19939
19881
|
function assertNotSymlink(targetPath, label) {
|
|
19940
19882
|
try {
|
|
@@ -19971,12 +19913,12 @@ function assertSafeInputRoot(realMemoryDir, targetPath, label) {
|
|
|
19971
19913
|
}
|
|
19972
19914
|
function assertSafeOutputTarget(realOutputDir, outputPath) {
|
|
19973
19915
|
let current = realOutputDir;
|
|
19974
|
-
const relative =
|
|
19975
|
-
if (relative.startsWith("..") ||
|
|
19916
|
+
const relative = path22.relative(realOutputDir, outputPath);
|
|
19917
|
+
if (relative.startsWith("..") || path22.isAbsolute(relative)) {
|
|
19976
19918
|
throw new Error(`context tree output path escapes outputDir: ${outputPath}`);
|
|
19977
19919
|
}
|
|
19978
|
-
for (const segment of relative.split(
|
|
19979
|
-
current =
|
|
19920
|
+
for (const segment of relative.split(path22.sep).filter(Boolean)) {
|
|
19921
|
+
current = path22.join(current, segment);
|
|
19980
19922
|
try {
|
|
19981
19923
|
const stat5 = fs.lstatSync(current);
|
|
19982
19924
|
if (stat5.isSymbolicLink()) {
|
|
@@ -20006,17 +19948,17 @@ function validateProjectionCategories(categories) {
|
|
|
20006
19948
|
return validated;
|
|
20007
19949
|
}
|
|
20008
19950
|
function resolveContainedOutputPath(outputRoot, ...segments) {
|
|
20009
|
-
const resolved =
|
|
20010
|
-
const relative =
|
|
20011
|
-
if (relative === "" || !relative.startsWith("..") && !
|
|
19951
|
+
const resolved = path22.resolve(outputRoot, ...segments);
|
|
19952
|
+
const relative = path22.relative(outputRoot, resolved);
|
|
19953
|
+
if (relative === "" || !relative.startsWith("..") && !path22.isAbsolute(relative)) {
|
|
20012
19954
|
return resolved;
|
|
20013
19955
|
}
|
|
20014
19956
|
throw new Error(`context tree output path escapes outputDir: ${segments.join("/")}`);
|
|
20015
19957
|
}
|
|
20016
19958
|
function writeProjectedContent(realOutputDir, outputPath, generatedContent) {
|
|
20017
19959
|
assertSafeOutputTarget(realOutputDir, outputPath);
|
|
20018
|
-
fs.mkdirSync(
|
|
20019
|
-
const realParent = fs.realpathSync(
|
|
19960
|
+
fs.mkdirSync(path22.dirname(outputPath), { recursive: true });
|
|
19961
|
+
const realParent = fs.realpathSync(path22.dirname(outputPath));
|
|
20020
19962
|
if (!isPathInside(realOutputDir, realParent)) {
|
|
20021
19963
|
throw new Error(`context tree output path escapes outputDir: ${outputPath}`);
|
|
20022
19964
|
}
|
|
@@ -20055,7 +19997,7 @@ function walkR(dir, realMemoryDir) {
|
|
|
20055
19997
|
const results = [];
|
|
20056
19998
|
function walk(directory) {
|
|
20057
19999
|
for (const entry of fs.readdirSync(directory, { withFileTypes: true })) {
|
|
20058
|
-
const fullPath =
|
|
20000
|
+
const fullPath = path22.join(directory, entry.name);
|
|
20059
20001
|
if (entry.isSymbolicLink()) {
|
|
20060
20002
|
throw new Error(`context tree input path contains symlink: ${fullPath}`);
|
|
20061
20003
|
}
|
|
@@ -20108,13 +20050,13 @@ function extractBody(content) {
|
|
|
20108
20050
|
}
|
|
20109
20051
|
function projectNode(filePath, category, fm, rawContent) {
|
|
20110
20052
|
const body = extractBody(rawContent);
|
|
20111
|
-
const fileName =
|
|
20112
|
-
const dateDir =
|
|
20053
|
+
const fileName = path22.basename(filePath, ".md");
|
|
20054
|
+
const dateDir = path22.basename(path22.dirname(filePath));
|
|
20113
20055
|
let relPath;
|
|
20114
20056
|
if (/^\d{4}-\d{2}-\d{2}$/.test(dateDir)) {
|
|
20115
|
-
relPath =
|
|
20057
|
+
relPath = path22.join(category, dateDir, `${fileName}.md`);
|
|
20116
20058
|
} else {
|
|
20117
|
-
relPath =
|
|
20059
|
+
relPath = path22.join(category, `${fileName}.md`);
|
|
20118
20060
|
}
|
|
20119
20061
|
const generatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
20120
20062
|
const md = `# ${fm.id}
|
|
@@ -20160,7 +20102,7 @@ function projectEntityNode(fileName, content) {
|
|
|
20160
20102
|
${content}
|
|
20161
20103
|
`;
|
|
20162
20104
|
return {
|
|
20163
|
-
path:
|
|
20105
|
+
path: path22.join("entities", `${fileName}.md`),
|
|
20164
20106
|
category: "entity",
|
|
20165
20107
|
title: fileName,
|
|
20166
20108
|
content: md,
|
|
@@ -20213,7 +20155,7 @@ function generateIndex(categoryCounts, outputDir) {
|
|
|
20213
20155
|
|
|
20214
20156
|
// src/onboarding/index.ts
|
|
20215
20157
|
import fs2 from "fs";
|
|
20216
|
-
import
|
|
20158
|
+
import path23 from "path";
|
|
20217
20159
|
var LANGUAGE_RULES = [
|
|
20218
20160
|
{
|
|
20219
20161
|
language: "TypeScript",
|
|
@@ -20315,7 +20257,7 @@ function onboard(options) {
|
|
|
20315
20257
|
maxDepth = 6,
|
|
20316
20258
|
excludeDirs = []
|
|
20317
20259
|
} = options;
|
|
20318
|
-
const directory =
|
|
20260
|
+
const directory = path23.resolve(options.directory ?? process.cwd());
|
|
20319
20261
|
let rootStat;
|
|
20320
20262
|
try {
|
|
20321
20263
|
rootStat = fs2.statSync(directory);
|
|
@@ -20357,7 +20299,7 @@ function walkDir(root, exclude, maxDepth) {
|
|
|
20357
20299
|
}
|
|
20358
20300
|
for (const entry of entries) {
|
|
20359
20301
|
if (exclude.has(entry.name)) continue;
|
|
20360
|
-
const fullPath =
|
|
20302
|
+
const fullPath = path23.join(dir, entry.name);
|
|
20361
20303
|
if (entry.isDirectory()) {
|
|
20362
20304
|
walk(fullPath, depth + 1);
|
|
20363
20305
|
} else if (entry.isFile()) {
|
|
@@ -20372,11 +20314,11 @@ function detectLanguages(files, root) {
|
|
|
20372
20314
|
const results = [];
|
|
20373
20315
|
const extCounts = /* @__PURE__ */ new Map();
|
|
20374
20316
|
for (const f of files) {
|
|
20375
|
-
const ext =
|
|
20317
|
+
const ext = path23.extname(f).toLowerCase();
|
|
20376
20318
|
if (ext) extCounts.set(ext, (extCounts.get(ext) ?? 0) + 1);
|
|
20377
20319
|
}
|
|
20378
20320
|
const rootFiles = new Set(
|
|
20379
|
-
files.filter((f) =>
|
|
20321
|
+
files.filter((f) => path23.dirname(f) === root).map((f) => path23.basename(f))
|
|
20380
20322
|
);
|
|
20381
20323
|
for (const rule of LANGUAGE_RULES) {
|
|
20382
20324
|
const evidence = [];
|
|
@@ -20420,7 +20362,7 @@ function detectLanguages(files, root) {
|
|
|
20420
20362
|
}
|
|
20421
20363
|
function detectShape(files, root) {
|
|
20422
20364
|
const rootFiles = new Set(
|
|
20423
|
-
files.filter((f) =>
|
|
20365
|
+
files.filter((f) => path23.dirname(f) === root).map((f) => path23.basename(f))
|
|
20424
20366
|
);
|
|
20425
20367
|
const rootDirs = /* @__PURE__ */ new Set();
|
|
20426
20368
|
try {
|
|
@@ -20431,7 +20373,7 @@ function detectShape(files, root) {
|
|
|
20431
20373
|
}
|
|
20432
20374
|
const evidence = [];
|
|
20433
20375
|
if (rootFiles.has("package.json")) {
|
|
20434
|
-
const pkg = readJsonSafe(
|
|
20376
|
+
const pkg = readJsonSafe(path23.join(root, "package.json"));
|
|
20435
20377
|
if (pkg?.workspaces) {
|
|
20436
20378
|
evidence.push("package.json has workspaces");
|
|
20437
20379
|
return { shape: "monorepo", evidence };
|
|
@@ -20445,13 +20387,13 @@ function detectShape(files, root) {
|
|
|
20445
20387
|
evidence.push("workspace manifest found");
|
|
20446
20388
|
return { shape: "workspace", evidence };
|
|
20447
20389
|
}
|
|
20448
|
-
const cargoToml = readTomlWorkspace(
|
|
20390
|
+
const cargoToml = readTomlWorkspace(path23.join(root, "Cargo.toml"));
|
|
20449
20391
|
if (cargoToml) {
|
|
20450
20392
|
evidence.push("Cargo.toml has workspace");
|
|
20451
20393
|
return { shape: "workspace", evidence };
|
|
20452
20394
|
}
|
|
20453
20395
|
if (rootFiles.has("package.json")) {
|
|
20454
|
-
const pkg = readJsonSafe(
|
|
20396
|
+
const pkg = readJsonSafe(path23.join(root, "package.json"));
|
|
20455
20397
|
if (pkg?.exports || pkg?.main) {
|
|
20456
20398
|
if (pkg?.bin) {
|
|
20457
20399
|
evidence.push("package.json has bin");
|
|
@@ -20485,8 +20427,8 @@ function discoverDocs(files, root) {
|
|
|
20485
20427
|
{ pattern: /^\.editorconfig$/i, kind: "config" }
|
|
20486
20428
|
];
|
|
20487
20429
|
for (const filePath of files) {
|
|
20488
|
-
const basename =
|
|
20489
|
-
const relPath =
|
|
20430
|
+
const basename = path23.basename(filePath).toLowerCase();
|
|
20431
|
+
const relPath = path23.relative(root, filePath);
|
|
20490
20432
|
let kind;
|
|
20491
20433
|
for (const { pattern, kind: k } of docPatterns) {
|
|
20492
20434
|
if (pattern.test(basename)) {
|
|
@@ -20498,7 +20440,7 @@ function discoverDocs(files, root) {
|
|
|
20498
20440
|
kind = "docs";
|
|
20499
20441
|
}
|
|
20500
20442
|
if (!kind && (basename.endsWith(".md") || basename.endsWith(".mdx"))) {
|
|
20501
|
-
if (
|
|
20443
|
+
if (path23.dirname(relPath) === "." || isUnderDocsDir(relPath)) {
|
|
20502
20444
|
kind = "docs";
|
|
20503
20445
|
}
|
|
20504
20446
|
}
|
|
@@ -20519,7 +20461,7 @@ function discoverDocs(files, root) {
|
|
|
20519
20461
|
return docs;
|
|
20520
20462
|
}
|
|
20521
20463
|
function isUnderDocsDir(relPath) {
|
|
20522
|
-
const parts = relPath.split(
|
|
20464
|
+
const parts = relPath.split(path23.sep);
|
|
20523
20465
|
return parts[0] === "docs" || parts[0] === "doc" || parts[0] === "documentation";
|
|
20524
20466
|
}
|
|
20525
20467
|
function buildPlan(languages, shape, docs, _root) {
|
|
@@ -20563,7 +20505,7 @@ function readTomlWorkspace(filePath) {
|
|
|
20563
20505
|
|
|
20564
20506
|
// src/curation/index.ts
|
|
20565
20507
|
import fs3 from "fs";
|
|
20566
|
-
import
|
|
20508
|
+
import path24 from "path";
|
|
20567
20509
|
import crypto4 from "crypto";
|
|
20568
20510
|
async function curate(options) {
|
|
20569
20511
|
const startTime = Date.now();
|
|
@@ -20654,12 +20596,12 @@ function resolveTargets(targetPath) {
|
|
|
20654
20596
|
const extensions = /* @__PURE__ */ new Set([".md", ".txt", ".mdx", ".rst"]);
|
|
20655
20597
|
function walk(dir) {
|
|
20656
20598
|
for (const entry of fs3.readdirSync(dir, { withFileTypes: true })) {
|
|
20657
|
-
const fullPath =
|
|
20599
|
+
const fullPath = path24.join(dir, entry.name);
|
|
20658
20600
|
if (entry.isDirectory()) {
|
|
20659
20601
|
if (entry.name !== "node_modules" && entry.name !== ".git") {
|
|
20660
20602
|
walk(fullPath);
|
|
20661
20603
|
}
|
|
20662
|
-
} else if (extensions.has(
|
|
20604
|
+
} else if (extensions.has(path24.extname(entry.name).toLowerCase())) {
|
|
20663
20605
|
results.push(fullPath);
|
|
20664
20606
|
}
|
|
20665
20607
|
}
|
|
@@ -20668,12 +20610,12 @@ function resolveTargets(targetPath) {
|
|
|
20668
20610
|
return results;
|
|
20669
20611
|
}
|
|
20670
20612
|
function resolveProvenanceRoot(targetPath) {
|
|
20671
|
-
const resolvedTarget =
|
|
20613
|
+
const resolvedTarget = path24.resolve(targetPath);
|
|
20672
20614
|
const stat5 = fs3.statSync(resolvedTarget);
|
|
20673
|
-
return stat5.isFile() ?
|
|
20615
|
+
return stat5.isFile() ? path24.dirname(resolvedTarget) : resolvedTarget;
|
|
20674
20616
|
}
|
|
20675
20617
|
function extractStatements(content, filePath, projectRoot, source, sourceFileHash, categoryOverride, confidence, entityRef, tags) {
|
|
20676
|
-
const relativePath =
|
|
20618
|
+
const relativePath = path24.relative(projectRoot, path24.resolve(filePath)) || path24.basename(filePath);
|
|
20677
20619
|
const statements = [];
|
|
20678
20620
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
20679
20621
|
const paragraphs = content.split(/\n{2,}/).map((p) => p.trim()).filter((p) => p.length > 20 && p.length < 2e3);
|
|
@@ -20767,7 +20709,7 @@ function loadExistingMemories(memoryDir) {
|
|
|
20767
20709
|
if (!fs3.existsSync(memoryDir)) return result;
|
|
20768
20710
|
const dirs = ALL_CATEGORY_DIRS;
|
|
20769
20711
|
for (const dir of dirs) {
|
|
20770
|
-
const fullDir =
|
|
20712
|
+
const fullDir = path24.join(memoryDir, dir);
|
|
20771
20713
|
if (!fs3.existsSync(fullDir)) continue;
|
|
20772
20714
|
walkFiles(fullDir, (filePath) => {
|
|
20773
20715
|
const content = readFileSafe(filePath);
|
|
@@ -20790,11 +20732,11 @@ function writeStatement(stmt, memoryDir) {
|
|
|
20790
20732
|
const now = /* @__PURE__ */ new Date();
|
|
20791
20733
|
const dateDir = now.toISOString().split("T")[0];
|
|
20792
20734
|
const categoryDir = getCategoryDir(memoryDir, stmt.category);
|
|
20793
|
-
const dir =
|
|
20735
|
+
const dir = path24.join(categoryDir, dateDir);
|
|
20794
20736
|
fs3.mkdirSync(dir, { recursive: true });
|
|
20795
20737
|
const fileName = `${stmt.category}-${Date.now()}-${stmt.id.slice(0, 8)}.md`;
|
|
20796
|
-
const filePath =
|
|
20797
|
-
const historicalIds = historicalIdCache2.get(
|
|
20738
|
+
const filePath = path24.join(dir, fileName);
|
|
20739
|
+
const historicalIds = historicalIdCache2.get(path24.join(memoryDir, "state"));
|
|
20798
20740
|
const rawBody = `${[
|
|
20799
20741
|
"---",
|
|
20800
20742
|
`id: ${stmt.id}`,
|
|
@@ -20817,7 +20759,7 @@ ${stmt.content}
|
|
|
20817
20759
|
fs3.writeFileSync(filePath, body);
|
|
20818
20760
|
try {
|
|
20819
20761
|
repairContentAfterJournalMoveSync({
|
|
20820
|
-
stateDir:
|
|
20762
|
+
stateDir: path24.join(memoryDir, "state"),
|
|
20821
20763
|
cache: historicalIdCache2,
|
|
20822
20764
|
idsAtWrite: historicalIds,
|
|
20823
20765
|
rawContent: rawBody,
|
|
@@ -20878,7 +20820,7 @@ function extractBody2(content) {
|
|
|
20878
20820
|
}
|
|
20879
20821
|
function walkFiles(dir, callback) {
|
|
20880
20822
|
for (const entry of fs3.readdirSync(dir, { withFileTypes: true })) {
|
|
20881
|
-
const fullPath =
|
|
20823
|
+
const fullPath = path24.join(dir, entry.name);
|
|
20882
20824
|
if (entry.isDirectory()) {
|
|
20883
20825
|
walkFiles(fullPath, callback);
|
|
20884
20826
|
} else if (entry.name.endsWith(".md")) {
|
|
@@ -20889,7 +20831,7 @@ function walkFiles(dir, callback) {
|
|
|
20889
20831
|
|
|
20890
20832
|
// src/dedup/index.ts
|
|
20891
20833
|
import fs4 from "fs";
|
|
20892
|
-
import
|
|
20834
|
+
import path25 from "path";
|
|
20893
20835
|
import crypto5 from "crypto";
|
|
20894
20836
|
var DEFAULT_DEDUP_THRESHOLD = 0.85;
|
|
20895
20837
|
var DEFAULT_MAX_LOAD = 1e4;
|
|
@@ -21031,7 +20973,7 @@ function loadMemories(memoryDir, categories, maxLoad = 1e4) {
|
|
|
21031
20973
|
const memoryRootReal = fs4.realpathSync(memoryDir);
|
|
21032
20974
|
for (const category of allCategories) {
|
|
21033
20975
|
if (result.length >= maxLoad) break;
|
|
21034
|
-
const dir =
|
|
20976
|
+
const dir = path25.join(memoryDir, category);
|
|
21035
20977
|
if (!fs4.existsSync(dir)) continue;
|
|
21036
20978
|
const categoryStat = fs4.lstatSync(dir);
|
|
21037
20979
|
if (categoryStat.isSymbolicLink()) {
|
|
@@ -21092,15 +21034,15 @@ function extractBody3(content) {
|
|
|
21092
21034
|
return match ? match[1].trim() : content.trim();
|
|
21093
21035
|
}
|
|
21094
21036
|
function assertPathInsideRoot2(rootReal, targetReal, sourcePath) {
|
|
21095
|
-
const rel =
|
|
21096
|
-
if (rel === "" || !rel.startsWith("..") && !
|
|
21037
|
+
const rel = path25.relative(rootReal, targetReal);
|
|
21038
|
+
if (rel === "" || !rel.startsWith("..") && !path25.isAbsolute(rel)) {
|
|
21097
21039
|
return;
|
|
21098
21040
|
}
|
|
21099
21041
|
throw new Error(`Refusing to scan memory path outside root: ${sourcePath}`);
|
|
21100
21042
|
}
|
|
21101
21043
|
function walkMdFiles(dir, memoryRootReal, categoryRootReal, callback) {
|
|
21102
21044
|
for (const entry of fs4.readdirSync(dir, { withFileTypes: true })) {
|
|
21103
|
-
const fullPath =
|
|
21045
|
+
const fullPath = path25.join(dir, entry.name);
|
|
21104
21046
|
const entryStat = fs4.lstatSync(fullPath);
|
|
21105
21047
|
if (entryStat.isSymbolicLink()) {
|
|
21106
21048
|
throw new Error(`Refusing to scan symlinked memory path: ${fullPath}`);
|
|
@@ -21118,10 +21060,10 @@ function walkMdFiles(dir, memoryRootReal, categoryRootReal, callback) {
|
|
|
21118
21060
|
|
|
21119
21061
|
// src/review/index.ts
|
|
21120
21062
|
import fs5 from "fs";
|
|
21121
|
-
import
|
|
21063
|
+
import path26 from "path";
|
|
21122
21064
|
var historicalIdCache3 = new HistoricalEntityCanonicalIdCache();
|
|
21123
21065
|
function writeReviewFileCanonicalized(memoryDir, filePath, content) {
|
|
21124
|
-
const stateDir =
|
|
21066
|
+
const stateDir = path26.join(memoryDir, "state");
|
|
21125
21067
|
const idsAtWrite = historicalIdCache3.get(stateDir);
|
|
21126
21068
|
let originalBytes = null;
|
|
21127
21069
|
try {
|
|
@@ -21163,8 +21105,8 @@ function realMemoryRoot(memoryDir) {
|
|
|
21163
21105
|
}
|
|
21164
21106
|
}
|
|
21165
21107
|
function isPathInside2(rootReal, candidateReal) {
|
|
21166
|
-
const relative =
|
|
21167
|
-
return relative === "" || !!relative && !relative.startsWith("..") && !
|
|
21108
|
+
const relative = path26.relative(rootReal, candidateReal);
|
|
21109
|
+
return relative === "" || !!relative && !relative.startsWith("..") && !path26.isAbsolute(relative);
|
|
21168
21110
|
}
|
|
21169
21111
|
function isSafeDirectory(rootReal, dir) {
|
|
21170
21112
|
try {
|
|
@@ -21207,7 +21149,7 @@ function listReviewItems(options) {
|
|
|
21207
21149
|
if (filterReason && item.reviewReason !== filterReason) return;
|
|
21208
21150
|
items.push(item);
|
|
21209
21151
|
};
|
|
21210
|
-
const suggestionsDir =
|
|
21152
|
+
const suggestionsDir = path26.join(memoryDir, "suggestions");
|
|
21211
21153
|
if (!isLimitReached() && fs5.existsSync(suggestionsDir) && isSafeDirectory(rootReal, suggestionsDir)) {
|
|
21212
21154
|
walkMd(rootReal, suggestionsDir, (filePath, content) => {
|
|
21213
21155
|
if (isLimitReached()) return true;
|
|
@@ -21228,7 +21170,7 @@ function listReviewItems(options) {
|
|
|
21228
21170
|
return isLimitReached();
|
|
21229
21171
|
});
|
|
21230
21172
|
}
|
|
21231
|
-
const reviewDir =
|
|
21173
|
+
const reviewDir = path26.join(memoryDir, "review");
|
|
21232
21174
|
if (!isLimitReached() && fs5.existsSync(reviewDir) && isSafeDirectory(rootReal, reviewDir)) {
|
|
21233
21175
|
walkMd(rootReal, reviewDir, (filePath, content) => {
|
|
21234
21176
|
if (isLimitReached()) return true;
|
|
@@ -21253,7 +21195,7 @@ function listReviewItems(options) {
|
|
|
21253
21195
|
const categories = ALL_CATEGORY_DIRS;
|
|
21254
21196
|
for (const category of categories) {
|
|
21255
21197
|
if (isLimitReached()) break;
|
|
21256
|
-
const dir =
|
|
21198
|
+
const dir = path26.join(memoryDir, category);
|
|
21257
21199
|
if (!fs5.existsSync(dir) || !isSafeDirectory(rootReal, dir)) continue;
|
|
21258
21200
|
walkMd(rootReal, dir, (filePath, content) => {
|
|
21259
21201
|
if (isLimitReached()) return true;
|
|
@@ -21335,9 +21277,9 @@ function approveItem(memoryDir, itemId, options) {
|
|
|
21335
21277
|
const targetDir = getCategoryDir(memoryDir, category);
|
|
21336
21278
|
const dateDir = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
21337
21279
|
ensureSafeDirectory(rootReal, targetDir);
|
|
21338
|
-
const outputPath =
|
|
21339
|
-
ensureSafeDirectory(rootReal,
|
|
21340
|
-
const reviewStateDir =
|
|
21280
|
+
const outputPath = path26.join(targetDir, dateDir, path26.basename(found.filePath));
|
|
21281
|
+
ensureSafeDirectory(rootReal, path26.dirname(outputPath));
|
|
21282
|
+
const reviewStateDir = path26.join(memoryDir, "state");
|
|
21341
21283
|
const idsAtWrite = historicalIdCache3.get(reviewStateDir);
|
|
21342
21284
|
const promotedWritten = canonicalizeEntityRefFrontmatter(updatedContent, idsAtWrite);
|
|
21343
21285
|
const promotedPath = writeFileWithoutClobber(outputPath, promotedWritten, itemId);
|
|
@@ -21414,13 +21356,13 @@ function findReviewFileById(memoryDir, id, options = {}) {
|
|
|
21414
21356
|
const rootReal = realMemoryRoot(memoryDir);
|
|
21415
21357
|
if (!rootReal) return null;
|
|
21416
21358
|
for (const loc of ["suggestions", "review"]) {
|
|
21417
|
-
const dir =
|
|
21359
|
+
const dir = path26.join(memoryDir, loc);
|
|
21418
21360
|
if (!fs5.existsSync(dir) || !isSafeDirectory(rootReal, dir)) continue;
|
|
21419
21361
|
const found = findFileById(rootReal, dir, id);
|
|
21420
21362
|
if (found) return { filePath: found, location: "queue" };
|
|
21421
21363
|
}
|
|
21422
21364
|
for (const category of ALL_CATEGORY_DIRS) {
|
|
21423
|
-
const dir =
|
|
21365
|
+
const dir = path26.join(memoryDir, category);
|
|
21424
21366
|
if (!fs5.existsSync(dir) || !isSafeDirectory(rootReal, dir)) continue;
|
|
21425
21367
|
const found = findFileById(rootReal, dir, id, (fm) => isLowConfidenceReviewCandidate(fm, options));
|
|
21426
21368
|
if (found) return { filePath: found, location: "category" };
|
|
@@ -21496,10 +21438,10 @@ function readFileSafe3(filePath) {
|
|
|
21496
21438
|
}
|
|
21497
21439
|
}
|
|
21498
21440
|
function writeFileWithoutClobber(basePath, content, discriminator) {
|
|
21499
|
-
const parsed =
|
|
21441
|
+
const parsed = path26.parse(basePath);
|
|
21500
21442
|
const safeDiscriminator = sanitizeFilePart(discriminator);
|
|
21501
21443
|
for (let attempt = 0; attempt < 1e3; attempt++) {
|
|
21502
|
-
const candidate = attempt === 0 ? basePath :
|
|
21444
|
+
const candidate = attempt === 0 ? basePath : path26.join(
|
|
21503
21445
|
parsed.dir,
|
|
21504
21446
|
`${parsed.name}-${safeDiscriminator}${attempt === 1 ? "" : `-${attempt}`}${parsed.ext || ".md"}`
|
|
21505
21447
|
);
|
|
@@ -21555,7 +21497,7 @@ function extractBody4(content) {
|
|
|
21555
21497
|
function walkMd(rootReal, dir, callback) {
|
|
21556
21498
|
if (!isSafeDirectory(rootReal, dir)) return false;
|
|
21557
21499
|
for (const entry of fs5.readdirSync(dir, { withFileTypes: true })) {
|
|
21558
|
-
const fullPath =
|
|
21500
|
+
const fullPath = path26.join(dir, entry.name);
|
|
21559
21501
|
if (entry.isSymbolicLink()) continue;
|
|
21560
21502
|
if (entry.isDirectory()) {
|
|
21561
21503
|
if (walkMd(rootReal, fullPath, callback)) return true;
|
|
@@ -21570,7 +21512,7 @@ function walkMdPaths(rootReal, dir) {
|
|
|
21570
21512
|
const results = [];
|
|
21571
21513
|
if (!isSafeDirectory(rootReal, dir)) return results;
|
|
21572
21514
|
for (const entry of fs5.readdirSync(dir, { withFileTypes: true })) {
|
|
21573
|
-
const fullPath =
|
|
21515
|
+
const fullPath = path26.join(dir, entry.name);
|
|
21574
21516
|
if (entry.isSymbolicLink()) continue;
|
|
21575
21517
|
if (entry.isDirectory()) {
|
|
21576
21518
|
results.push(...walkMdPaths(rootReal, fullPath));
|
|
@@ -21583,7 +21525,7 @@ function walkMdPaths(rootReal, dir) {
|
|
|
21583
21525
|
|
|
21584
21526
|
// src/sync/index.ts
|
|
21585
21527
|
import fs6 from "fs";
|
|
21586
|
-
import
|
|
21528
|
+
import path27 from "path";
|
|
21587
21529
|
import crypto6 from "crypto";
|
|
21588
21530
|
var DEFAULT_EXTENSIONS = /* @__PURE__ */ new Set([".md", ".txt", ".mdx", ".rst"]);
|
|
21589
21531
|
var DEFAULT_EXCLUDE2 = /* @__PURE__ */ new Set([
|
|
@@ -21605,7 +21547,7 @@ function syncChanges(options) {
|
|
|
21605
21547
|
} = options;
|
|
21606
21548
|
const extSet = new Set(extensions);
|
|
21607
21549
|
const excludeSet = /* @__PURE__ */ new Set([...DEFAULT_EXCLUDE2, ...excludeDirs]);
|
|
21608
|
-
const stateFilePath = options.stateFile ??
|
|
21550
|
+
const stateFilePath = options.stateFile ?? path27.join(memoryDir, ".sync-state.json");
|
|
21609
21551
|
const prevState = loadState(stateFilePath);
|
|
21610
21552
|
const currentFiles = scanFiles(sourceDir, extSet, excludeSet);
|
|
21611
21553
|
const changes = computeDiff(currentFiles, prevState.fileHashes, sourceDir);
|
|
@@ -21621,7 +21563,7 @@ function syncChanges(options) {
|
|
|
21621
21563
|
for (const [relPath, hash] of Object.entries(currentFiles)) {
|
|
21622
21564
|
newState.fileHashes[relPath] = hash;
|
|
21623
21565
|
}
|
|
21624
|
-
fs6.mkdirSync(
|
|
21566
|
+
fs6.mkdirSync(path27.dirname(stateFilePath), { recursive: true });
|
|
21625
21567
|
fs6.writeFileSync(stateFilePath, JSON.stringify(newState, null, 2));
|
|
21626
21568
|
}
|
|
21627
21569
|
return {
|
|
@@ -21687,13 +21629,13 @@ function scanFiles(root, extensions, exclude) {
|
|
|
21687
21629
|
}
|
|
21688
21630
|
for (const entry of entries) {
|
|
21689
21631
|
if (exclude.has(entry.name)) continue;
|
|
21690
|
-
const fullPath =
|
|
21632
|
+
const fullPath = path27.join(dir, entry.name);
|
|
21691
21633
|
if (entry.isDirectory()) {
|
|
21692
21634
|
walk(fullPath);
|
|
21693
21635
|
} else if (entry.isFile()) {
|
|
21694
|
-
const ext =
|
|
21636
|
+
const ext = path27.extname(entry.name).toLowerCase();
|
|
21695
21637
|
if (!extensions.has(ext)) continue;
|
|
21696
|
-
const relPath =
|
|
21638
|
+
const relPath = path27.relative(root, fullPath);
|
|
21697
21639
|
try {
|
|
21698
21640
|
const content = fs6.readFileSync(fullPath, "utf8");
|
|
21699
21641
|
result[relPath] = hashContent3(content);
|
|
@@ -21708,7 +21650,7 @@ function scanFiles(root, extensions, exclude) {
|
|
|
21708
21650
|
function computeDiff(current, previous, sourceDir) {
|
|
21709
21651
|
const changes = [];
|
|
21710
21652
|
for (const [relPath, hash] of Object.entries(current)) {
|
|
21711
|
-
const fullPath =
|
|
21653
|
+
const fullPath = path27.join(sourceDir, relPath);
|
|
21712
21654
|
if (!(relPath in previous)) {
|
|
21713
21655
|
let size = 0;
|
|
21714
21656
|
try {
|
|
@@ -21741,7 +21683,7 @@ function computeDiff(current, previous, sourceDir) {
|
|
|
21741
21683
|
for (const relPath of Object.keys(previous)) {
|
|
21742
21684
|
if (!(relPath in current)) {
|
|
21743
21685
|
changes.push({
|
|
21744
|
-
filePath:
|
|
21686
|
+
filePath: path27.join(sourceDir, relPath),
|
|
21745
21687
|
relativePath: relPath,
|
|
21746
21688
|
type: "deleted",
|
|
21747
21689
|
currentHash: "",
|
|
@@ -21771,21 +21713,21 @@ function hashContent3(content) {
|
|
|
21771
21713
|
import { spawnSync } from "child_process";
|
|
21772
21714
|
import crypto7 from "crypto";
|
|
21773
21715
|
import fs7 from "fs";
|
|
21774
|
-
import
|
|
21716
|
+
import path28 from "path";
|
|
21775
21717
|
var historicalIdCache4 = new HistoricalEntityCanonicalIdCache();
|
|
21776
21718
|
var MANIFEST_VERSION = 1;
|
|
21777
21719
|
var MANIFEST_LOCK_STALE_MS = 3e4;
|
|
21778
21720
|
var MANIFEST_LOCK_TIMEOUT_MS = MANIFEST_LOCK_STALE_MS + 1e4;
|
|
21779
21721
|
var MANIFEST_LOCK_SLEEP_MS = 20;
|
|
21780
21722
|
function normalizeSpaceMemoryDir(memoryDir) {
|
|
21781
|
-
return
|
|
21723
|
+
return path28.resolve(memoryDir);
|
|
21782
21724
|
}
|
|
21783
21725
|
function getSpacesDir(baseDir) {
|
|
21784
21726
|
const homeDir = baseDir ?? resolveHomeDir();
|
|
21785
|
-
return
|
|
21727
|
+
return path28.join(homeDir, ".config", "engram", "spaces");
|
|
21786
21728
|
}
|
|
21787
21729
|
function getManifestPath(baseDir) {
|
|
21788
|
-
return
|
|
21730
|
+
return path28.join(getSpacesDir(baseDir), "manifest.json");
|
|
21789
21731
|
}
|
|
21790
21732
|
function loadManifest(baseDir, memoryDirOverride) {
|
|
21791
21733
|
if (fs7.existsSync(getManifestPath(baseDir))) {
|
|
@@ -21832,9 +21774,9 @@ function readManifestUnlocked(baseDir, memoryDirOverride, options = {}) {
|
|
|
21832
21774
|
}
|
|
21833
21775
|
function saveManifestUnlocked(manifest, baseDir) {
|
|
21834
21776
|
const manifestPath2 = getManifestPath(baseDir);
|
|
21835
|
-
const manifestDir2 =
|
|
21777
|
+
const manifestDir2 = path28.dirname(manifestPath2);
|
|
21836
21778
|
fs7.mkdirSync(manifestDir2, { recursive: true });
|
|
21837
|
-
const tempPath =
|
|
21779
|
+
const tempPath = path28.join(manifestDir2, `.manifest.${process.pid}.${Date.now()}.${crypto7.randomUUID()}.tmp`);
|
|
21838
21780
|
try {
|
|
21839
21781
|
fs7.writeFileSync(tempPath, `${JSON.stringify(manifest, null, 2)}
|
|
21840
21782
|
`, { flag: "wx" });
|
|
@@ -21849,7 +21791,7 @@ function saveManifestUnlocked(manifest, baseDir) {
|
|
|
21849
21791
|
}
|
|
21850
21792
|
function withManifestLock(baseDir, operation) {
|
|
21851
21793
|
const lockDir = `${getManifestPath(baseDir)}.lock`;
|
|
21852
|
-
fs7.mkdirSync(
|
|
21794
|
+
fs7.mkdirSync(path28.dirname(lockDir), { recursive: true });
|
|
21853
21795
|
const lockOwner = acquireManifestLock(lockDir);
|
|
21854
21796
|
try {
|
|
21855
21797
|
return operation();
|
|
@@ -21875,7 +21817,7 @@ function acquireManifestLock(lockDir) {
|
|
|
21875
21817
|
try {
|
|
21876
21818
|
fs7.mkdirSync(lockDir, { recursive: false });
|
|
21877
21819
|
try {
|
|
21878
|
-
fs7.writeFileSync(
|
|
21820
|
+
fs7.writeFileSync(path28.join(lockDir, "owner"), `${owner}
|
|
21879
21821
|
`, { flag: "wx" });
|
|
21880
21822
|
} catch (error) {
|
|
21881
21823
|
fs7.rmSync(lockDir, { recursive: true, force: true });
|
|
@@ -21905,7 +21847,7 @@ function acquireManifestLock(lockDir) {
|
|
|
21905
21847
|
}
|
|
21906
21848
|
function releaseManifestLock(lockDir, owner) {
|
|
21907
21849
|
try {
|
|
21908
|
-
const ownerPath =
|
|
21850
|
+
const ownerPath = path28.join(lockDir, "owner");
|
|
21909
21851
|
if (fs7.readFileSync(ownerPath, "utf8").trim() === owner) {
|
|
21910
21852
|
fs7.rmSync(lockDir, { recursive: true, force: true });
|
|
21911
21853
|
}
|
|
@@ -21921,7 +21863,7 @@ function removeStaleManifestLock(lockDir) {
|
|
|
21921
21863
|
try {
|
|
21922
21864
|
fs7.mkdirSync(reclaimDir, { recursive: false });
|
|
21923
21865
|
try {
|
|
21924
|
-
fs7.writeFileSync(
|
|
21866
|
+
fs7.writeFileSync(path28.join(reclaimDir, "owner"), `${reclaimOwner}
|
|
21925
21867
|
`, { flag: "wx" });
|
|
21926
21868
|
} catch (error) {
|
|
21927
21869
|
fs7.rmSync(reclaimDir, { recursive: true, force: true });
|
|
@@ -21996,7 +21938,7 @@ function readManifestLockSnapshot(lockDir) {
|
|
|
21996
21938
|
throw error;
|
|
21997
21939
|
}
|
|
21998
21940
|
try {
|
|
21999
|
-
const owner = fs7.readFileSync(
|
|
21941
|
+
const owner = fs7.readFileSync(path28.join(lockDir, "owner"), "utf8").trim();
|
|
22000
21942
|
return { mtimeMs: stat5.mtimeMs, owner };
|
|
22001
21943
|
} catch (error) {
|
|
22002
21944
|
if (error.code === "ENOENT") {
|
|
@@ -22068,8 +22010,8 @@ function sleepSync(ms) {
|
|
|
22068
22010
|
}
|
|
22069
22011
|
function createPersonalSpace(baseDir, memoryDirOverride) {
|
|
22070
22012
|
const homeDir = baseDir ?? resolveHomeDir();
|
|
22071
|
-
const standalonePath =
|
|
22072
|
-
const openclawPath =
|
|
22013
|
+
const standalonePath = path28.join(homeDir, ".engram", "memory");
|
|
22014
|
+
const openclawPath = path28.join(homeDir, ".openclaw", "workspace", "memory", "local");
|
|
22073
22015
|
const memoryDir = memoryDirOverride ?? readEnvVar("REMNIC_MEMORY_DIR") ?? readEnvVar("ENGRAM_MEMORY_DIR") ?? (fs7.existsSync(standalonePath) ? standalonePath : fs7.existsSync(openclawPath) ? openclawPath : standalonePath);
|
|
22074
22016
|
const normalizedMemoryDir = normalizeSpaceMemoryDir(memoryDir);
|
|
22075
22017
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -22098,7 +22040,7 @@ function createSpace(options) {
|
|
|
22098
22040
|
const id = options.name.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-");
|
|
22099
22041
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
22100
22042
|
const memoryDir = normalizeSpaceMemoryDir(
|
|
22101
|
-
options.memoryDir ??
|
|
22043
|
+
options.memoryDir ?? path28.join(getSpacesDir(options.baseDir), id, "memory")
|
|
22102
22044
|
);
|
|
22103
22045
|
const space = updateManifest(options.baseDir, (manifest) => {
|
|
22104
22046
|
if (manifest.spaces.some((s) => s.id === id)) {
|
|
@@ -22319,14 +22261,14 @@ async function mergeSpaces(sourceSpaceId, targetSpaceId, options) {
|
|
|
22319
22261
|
};
|
|
22320
22262
|
}
|
|
22321
22263
|
function getAuditLog(baseDir) {
|
|
22322
|
-
const auditPath =
|
|
22264
|
+
const auditPath = path28.join(getSpacesDir(baseDir), "audit.jsonl");
|
|
22323
22265
|
if (!fs7.existsSync(auditPath)) return [];
|
|
22324
22266
|
const lines = fs7.readFileSync(auditPath, "utf8").trim().split("\n");
|
|
22325
22267
|
return lines.filter((l) => l.trim()).map((l) => JSON.parse(l));
|
|
22326
22268
|
}
|
|
22327
22269
|
function appendAudit(entry, baseDir) {
|
|
22328
|
-
const auditPath =
|
|
22329
|
-
fs7.mkdirSync(
|
|
22270
|
+
const auditPath = path28.join(getSpacesDir(baseDir), "audit.jsonl");
|
|
22271
|
+
fs7.mkdirSync(path28.dirname(auditPath), { recursive: true });
|
|
22330
22272
|
const full = {
|
|
22331
22273
|
id: crypto7.randomUUID(),
|
|
22332
22274
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -22347,11 +22289,11 @@ async function copyMemories(sourceDir, targetDir, options) {
|
|
|
22347
22289
|
sourceFiles.filter((p) => {
|
|
22348
22290
|
const rp = safeRealpath(p);
|
|
22349
22291
|
if (!rp || !isPathInsideRoot(rp, sourceRoot)) return false;
|
|
22350
|
-
const rel =
|
|
22351
|
-
const mapped =
|
|
22292
|
+
const rel = path28.relative(sourceRoot, rp);
|
|
22293
|
+
const mapped = path28.resolve(targetRoot, rel);
|
|
22352
22294
|
if (!isPathInsideRoot(mapped, targetRoot)) return false;
|
|
22353
22295
|
return classifyEntityRefWritePath(targetRoot, mapped) === "entity";
|
|
22354
|
-
}).map((p) =>
|
|
22296
|
+
}).map((p) => path28.basename(p, ".md"))
|
|
22355
22297
|
);
|
|
22356
22298
|
const firstEntityId = sourceEntityIds.values().next().value;
|
|
22357
22299
|
if (firstEntityId === void 0) {
|
|
@@ -22359,7 +22301,7 @@ async function copyMemories(sourceDir, targetDir, options) {
|
|
|
22359
22301
|
}
|
|
22360
22302
|
return withRawEntityPageMutation(
|
|
22361
22303
|
targetRoot,
|
|
22362
|
-
|
|
22304
|
+
path28.join(targetRoot, "entities", `${firstEntityId}.md`),
|
|
22363
22305
|
async () => copyPreparedMemories(
|
|
22364
22306
|
sourceFiles,
|
|
22365
22307
|
sourceRoot,
|
|
@@ -22386,14 +22328,14 @@ function copyPreparedMemories(sourceFiles, sourceRoot, targetRoot, sourceEntityI
|
|
|
22386
22328
|
continue;
|
|
22387
22329
|
}
|
|
22388
22330
|
const content = fs7.readFileSync(sourcePath, "utf8");
|
|
22389
|
-
const relativePath =
|
|
22390
|
-
const targetPath =
|
|
22331
|
+
const relativePath = path28.relative(sourceRoot, sourceRealPath);
|
|
22332
|
+
const targetPath = path28.resolve(targetRoot, relativePath);
|
|
22391
22333
|
if (!isPathInsideRoot(targetPath, targetRoot)) {
|
|
22392
22334
|
skipped++;
|
|
22393
22335
|
continue;
|
|
22394
22336
|
}
|
|
22395
22337
|
const targetKind = classifyEntityRefWritePath(targetRoot, targetPath);
|
|
22396
|
-
const idsAtCompare = historicalIdCache4.get(
|
|
22338
|
+
const idsAtCompare = historicalIdCache4.get(path28.join(targetRoot, "state"));
|
|
22397
22339
|
const sourceRef = targetKind === "memory" ? readEntityRefFromFrontmatter(content) : null;
|
|
22398
22340
|
const refHasSourceClaimant = sourceRef !== null && sourceEntityIds.has(sourceRef);
|
|
22399
22341
|
const canonicalContent = targetKind === "memory" && !refHasSourceClaimant ? canonicalizeEntityRefFrontmatter(content, idsAtCompare) : content;
|
|
@@ -22420,7 +22362,7 @@ function copyPreparedMemories(sourceFiles, sourceRoot, targetRoot, sourceEntityI
|
|
|
22420
22362
|
if (fs7.existsSync(targetPath) && !options?.force) {
|
|
22421
22363
|
const targetContent = fs7.readFileSync(targetPath, "utf8");
|
|
22422
22364
|
const targetHash = hashContent4(targetContent);
|
|
22423
|
-
if (hashContent4(canonicalContent) === targetHash && historicalIdCache4.get(
|
|
22365
|
+
if (hashContent4(canonicalContent) === targetHash && historicalIdCache4.get(path28.join(targetRoot, "state")) === idsAtCompare) {
|
|
22424
22366
|
skipped++;
|
|
22425
22367
|
continue;
|
|
22426
22368
|
}
|
|
@@ -22436,13 +22378,13 @@ function copyPreparedMemories(sourceFiles, sourceRoot, targetRoot, sourceEntityI
|
|
|
22436
22378
|
continue;
|
|
22437
22379
|
}
|
|
22438
22380
|
}
|
|
22439
|
-
fs7.mkdirSync(
|
|
22440
|
-
const targetParentRealPath = safeRealpath(
|
|
22381
|
+
fs7.mkdirSync(path28.dirname(targetPath), { recursive: true });
|
|
22382
|
+
const targetParentRealPath = safeRealpath(path28.dirname(targetPath));
|
|
22441
22383
|
if (!targetParentRealPath || !isPathInsideRoot(targetParentRealPath, targetRoot)) {
|
|
22442
22384
|
skipped++;
|
|
22443
22385
|
continue;
|
|
22444
22386
|
}
|
|
22445
|
-
const stateDir =
|
|
22387
|
+
const stateDir = path28.join(targetRoot, "state");
|
|
22446
22388
|
if (targetKind === "memory" && !refHasSourceClaimant) {
|
|
22447
22389
|
const idsAtWrite = historicalIdCache4.get(stateDir);
|
|
22448
22390
|
const written = canonicalizeEntityRefFrontmatter(content, idsAtWrite);
|
|
@@ -22486,7 +22428,7 @@ function copyPreparedMemories(sourceFiles, sourceRoot, targetRoot, sourceEntityI
|
|
|
22486
22428
|
bumpMemoryCorpusVersionForDir(targetRoot);
|
|
22487
22429
|
}
|
|
22488
22430
|
if (reconcileNeeded) {
|
|
22489
|
-
requestEntityCanonicalIdReconcileSync(
|
|
22431
|
+
requestEntityCanonicalIdReconcileSync(path28.join(targetRoot, "state"));
|
|
22490
22432
|
}
|
|
22491
22433
|
return { merged, conflicts, skipped };
|
|
22492
22434
|
}
|
|
@@ -22497,7 +22439,7 @@ function walkMd2(dir) {
|
|
|
22497
22439
|
const results = [];
|
|
22498
22440
|
function walk(d) {
|
|
22499
22441
|
for (const entry of fs7.readdirSync(d, { withFileTypes: true })) {
|
|
22500
|
-
const fullPath =
|
|
22442
|
+
const fullPath = path28.join(d, entry.name);
|
|
22501
22443
|
if (entry.isSymbolicLink()) {
|
|
22502
22444
|
continue;
|
|
22503
22445
|
}
|
|
@@ -22526,8 +22468,8 @@ function safeRealpath(filePath) {
|
|
|
22526
22468
|
}
|
|
22527
22469
|
}
|
|
22528
22470
|
function isPathInsideRoot(candidatePath, rootPath) {
|
|
22529
|
-
const relative =
|
|
22530
|
-
return relative === "" || !relative.startsWith("..") && !
|
|
22471
|
+
const relative = path28.relative(rootPath, candidatePath);
|
|
22472
|
+
return relative === "" || !relative.startsWith("..") && !path28.isAbsolute(relative);
|
|
22531
22473
|
}
|
|
22532
22474
|
function parseSimpleFrontmatter(content) {
|
|
22533
22475
|
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
@@ -22648,7 +22590,7 @@ var REMNIC_RECALL_DECISION_RULES = `## When to Use Recall vs Direct Read
|
|
|
22648
22590
|
// src/memory-extension/codex-publisher.ts
|
|
22649
22591
|
import fs8 from "fs";
|
|
22650
22592
|
import os from "os";
|
|
22651
|
-
import
|
|
22593
|
+
import path29 from "path";
|
|
22652
22594
|
var REMNIC_EXTENSION_DIR_NAME = "remnic";
|
|
22653
22595
|
function resolveEnvHome(env) {
|
|
22654
22596
|
if (env === void 0) return resolveHomeDir();
|
|
@@ -22657,12 +22599,12 @@ function resolveEnvHome(env) {
|
|
|
22657
22599
|
function expandTildeWithHome(input, homeDir) {
|
|
22658
22600
|
if (input === "~") return homeDir;
|
|
22659
22601
|
if (input.startsWith("~/") || input.startsWith("~\\")) {
|
|
22660
|
-
return
|
|
22602
|
+
return path29.join(homeDir, input.slice(2));
|
|
22661
22603
|
}
|
|
22662
22604
|
return input;
|
|
22663
22605
|
}
|
|
22664
22606
|
function normalizeHostRoot(input, homeDir) {
|
|
22665
|
-
return
|
|
22607
|
+
return path29.resolve(expandTildeWithHome(input.trim(), homeDir));
|
|
22666
22608
|
}
|
|
22667
22609
|
var CodexMemoryExtensionPublisher = class {
|
|
22668
22610
|
hostId = "codex";
|
|
@@ -22676,12 +22618,12 @@ var CodexMemoryExtensionPublisher = class {
|
|
|
22676
22618
|
async resolveExtensionRoot(env) {
|
|
22677
22619
|
const homeDir = resolveEnvHome(env);
|
|
22678
22620
|
const codexHomeInput = env === void 0 ? readEnvVar("CODEX_HOME")?.trim() : env.CODEX_HOME?.trim();
|
|
22679
|
-
const codexHome = codexHomeInput ? normalizeHostRoot(codexHomeInput, homeDir) :
|
|
22680
|
-
return
|
|
22621
|
+
const codexHome = codexHomeInput ? normalizeHostRoot(codexHomeInput, homeDir) : path29.resolve(homeDir, ".codex");
|
|
22622
|
+
return path29.join(codexHome, "memories_extensions", REMNIC_EXTENSION_DIR_NAME);
|
|
22681
22623
|
}
|
|
22682
22624
|
async isHostAvailable() {
|
|
22683
22625
|
try {
|
|
22684
|
-
const home = readEnvVar("CODEX_HOME")?.trim() ||
|
|
22626
|
+
const home = readEnvVar("CODEX_HOME")?.trim() || path29.join(resolveHomeDir(), ".codex");
|
|
22685
22627
|
return fs8.existsSync(home);
|
|
22686
22628
|
} catch {
|
|
22687
22629
|
return false;
|
|
@@ -22732,7 +22674,7 @@ When running inside the Codex phase-2 consolidation sandbox:
|
|
|
22732
22674
|
}
|
|
22733
22675
|
async publish(ctx) {
|
|
22734
22676
|
const extensionRoot = await this.resolveExtensionRoot();
|
|
22735
|
-
const instructionsPath =
|
|
22677
|
+
const instructionsPath = path29.join(extensionRoot, "instructions.md");
|
|
22736
22678
|
const filesWritten = [];
|
|
22737
22679
|
const skipped = [];
|
|
22738
22680
|
ctx.log.info(`Publishing Codex memory extension to ${extensionRoot}`);
|
|
@@ -23108,7 +23050,7 @@ async function generateActivityMemories(date, digestBody, config, deps) {
|
|
|
23108
23050
|
// src/session-summaries/index.ts
|
|
23109
23051
|
import { createHash as createHash7 } from "crypto";
|
|
23110
23052
|
import { lstat as lstat2, mkdir as mkdir7, readFile as readFile6, readdir as readdir4, rename, rm, stat as stat4, writeFile as writeFile7 } from "fs/promises";
|
|
23111
|
-
import
|
|
23053
|
+
import path30 from "path";
|
|
23112
23054
|
|
|
23113
23055
|
// src/session-summaries/adapters.ts
|
|
23114
23056
|
var VALID_ROLES = /* @__PURE__ */ new Set(["user", "assistant", "tool", "system", "other"]);
|
|
@@ -23613,7 +23555,7 @@ function shortHash(value, length = 16) {
|
|
|
23613
23555
|
async function listTranscriptFiles(root, maxFiles) {
|
|
23614
23556
|
const out = [];
|
|
23615
23557
|
let truncated = false;
|
|
23616
|
-
const entrySortKey = (entryName, isDirectory) => isDirectory ? `${entryName}${
|
|
23558
|
+
const entrySortKey = (entryName, isDirectory) => isDirectory ? `${entryName}${path30.sep}` : entryName;
|
|
23617
23559
|
async function visit(dir) {
|
|
23618
23560
|
if (truncated) return;
|
|
23619
23561
|
const entries = (await readdir4(dir, { withFileTypes: true })).sort(
|
|
@@ -23623,13 +23565,13 @@ async function listTranscriptFiles(root, maxFiles) {
|
|
|
23623
23565
|
if (truncated) return;
|
|
23624
23566
|
if (entry.name.startsWith(".")) continue;
|
|
23625
23567
|
if (entry.isSymbolicLink()) continue;
|
|
23626
|
-
const fullPath =
|
|
23568
|
+
const fullPath = path30.join(dir, entry.name);
|
|
23627
23569
|
if (entry.isDirectory()) {
|
|
23628
23570
|
await visit(fullPath);
|
|
23629
23571
|
continue;
|
|
23630
23572
|
}
|
|
23631
23573
|
if (!entry.isFile()) continue;
|
|
23632
|
-
const ext =
|
|
23574
|
+
const ext = path30.extname(entry.name).toLowerCase();
|
|
23633
23575
|
if (!SUPPORTED_EXTENSIONS.has(ext)) continue;
|
|
23634
23576
|
out.push(fullPath);
|
|
23635
23577
|
if (out.length > maxFiles) {
|
|
@@ -23656,7 +23598,7 @@ function normalizeInputDir(inputDir) {
|
|
|
23656
23598
|
if (typeof inputDir !== "string" || inputDir.trim().length === 0) {
|
|
23657
23599
|
throw new Error("inputDir must be a non-empty string");
|
|
23658
23600
|
}
|
|
23659
|
-
return
|
|
23601
|
+
return path30.resolve(expandTildePath(inputDir.trim()));
|
|
23660
23602
|
}
|
|
23661
23603
|
function initRoleCounts() {
|
|
23662
23604
|
return {
|
|
@@ -23813,11 +23755,11 @@ async function collectLocalSessionSummaries(options) {
|
|
|
23813
23755
|
continue;
|
|
23814
23756
|
}
|
|
23815
23757
|
seenFileHashes.add(fileHash);
|
|
23816
|
-
const fileExtension =
|
|
23758
|
+
const fileExtension = path30.extname(filePath).toLowerCase();
|
|
23817
23759
|
const parsed = await adapter.parseFile(
|
|
23818
23760
|
{
|
|
23819
23761
|
content,
|
|
23820
|
-
fileName:
|
|
23762
|
+
fileName: path30.basename(filePath),
|
|
23821
23763
|
fileExtension,
|
|
23822
23764
|
fileRef: fileHash
|
|
23823
23765
|
},
|
|
@@ -23873,7 +23815,7 @@ async function collectLocalSessionSummaries(options) {
|
|
|
23873
23815
|
}
|
|
23874
23816
|
async function readRedactionConfig(pathLike) {
|
|
23875
23817
|
if (!pathLike) return void 0;
|
|
23876
|
-
const raw = await readFile6(
|
|
23818
|
+
const raw = await readFile6(path30.resolve(expandTildePath(pathLike)), "utf-8");
|
|
23877
23819
|
const parsed = JSON.parse(raw);
|
|
23878
23820
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
23879
23821
|
throw new Error("redaction config must be a JSON object");
|
|
@@ -23886,15 +23828,15 @@ function toJsonl(drafts) {
|
|
|
23886
23828
|
}
|
|
23887
23829
|
function defaultDraftOutputPath(memoryDir, generatedAt) {
|
|
23888
23830
|
const stamp = generatedAt.replace(/[:.]/g, "-");
|
|
23889
|
-
return
|
|
23890
|
-
|
|
23831
|
+
return path30.join(
|
|
23832
|
+
path30.resolve(expandTildePath(memoryDir)),
|
|
23891
23833
|
"state",
|
|
23892
23834
|
"session-summary-drafts",
|
|
23893
23835
|
`session-summaries-${stamp}.jsonl`
|
|
23894
23836
|
);
|
|
23895
23837
|
}
|
|
23896
23838
|
async function writeDrafts(filePath, drafts) {
|
|
23897
|
-
await mkdir7(
|
|
23839
|
+
await mkdir7(path30.dirname(filePath), { recursive: true });
|
|
23898
23840
|
const tempPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
|
|
23899
23841
|
try {
|
|
23900
23842
|
await writeFile7(tempPath, toJsonl(drafts), "utf-8");
|
|
@@ -23912,7 +23854,7 @@ async function runLocalSessionSummaryCliCommand(options) {
|
|
|
23912
23854
|
});
|
|
23913
23855
|
const wroteFiles = [];
|
|
23914
23856
|
if (options.output) {
|
|
23915
|
-
const outputPath =
|
|
23857
|
+
const outputPath = path30.resolve(expandTildePath(options.output));
|
|
23916
23858
|
await writeDrafts(outputPath, report.drafts);
|
|
23917
23859
|
wroteFiles.push(outputPath);
|
|
23918
23860
|
}
|
|
@@ -23947,19 +23889,19 @@ async function runLocalSessionSummaryCliCommand(options) {
|
|
|
23947
23889
|
|
|
23948
23890
|
// src/transfer/capsule-fork.ts
|
|
23949
23891
|
import { lstat as lstat3, mkdir as mkdir8, readFile as readFile7, realpath as realpath2, writeFile as writeFile8 } from "fs/promises";
|
|
23950
|
-
import
|
|
23892
|
+
import path31 from "path";
|
|
23951
23893
|
async function forkCapsule(opts) {
|
|
23952
23894
|
validateForkId(opts.forkId);
|
|
23953
|
-
const rootAbs =
|
|
23895
|
+
const rootAbs = path31.resolve(opts.targetRoot);
|
|
23954
23896
|
await assertIsDirectoryNotSymlink(rootAbs, "forkCapsule", "targetRoot");
|
|
23955
|
-
const forkDirAbs =
|
|
23897
|
+
const forkDirAbs = path31.join(rootAbs, "forks", opts.forkId);
|
|
23956
23898
|
const forkEntryExists = await pathEntryExists(forkDirAbs);
|
|
23957
23899
|
if (forkEntryExists) {
|
|
23958
23900
|
throw new Error(
|
|
23959
23901
|
`forkCapsule: fork path already exists \u2014 forkId "${opts.forkId}" is already in use at: ${forkDirAbs}`
|
|
23960
23902
|
);
|
|
23961
23903
|
}
|
|
23962
|
-
const archiveAbs =
|
|
23904
|
+
const archiveAbs = path31.resolve(opts.sourceArchive);
|
|
23963
23905
|
const importResult = await importCapsule({
|
|
23964
23906
|
archivePath: archiveAbs,
|
|
23965
23907
|
root: rootAbs,
|
|
@@ -23981,10 +23923,10 @@ async function forkCapsule(opts) {
|
|
|
23981
23923
|
importedRecords: importResult.imported.length,
|
|
23982
23924
|
skippedRecords: importResult.skipped.length
|
|
23983
23925
|
};
|
|
23984
|
-
const lineagePath =
|
|
23926
|
+
const lineagePath = path31.join(forkDirAbs, "lineage.json");
|
|
23985
23927
|
const rootReal = await realpath2(rootAbs);
|
|
23986
23928
|
await assertRealpathInsideRoot(rootReal, lineagePath, `forks/${opts.forkId}/lineage.json`, "forkCapsule");
|
|
23987
|
-
await mkdir8(
|
|
23929
|
+
await mkdir8(path31.dirname(lineagePath), { recursive: true });
|
|
23988
23930
|
await writeFile8(lineagePath, JSON.stringify(lineage, null, 2) + "\n", "utf-8");
|
|
23989
23931
|
return {
|
|
23990
23932
|
archivePath: archiveAbs,
|
|
@@ -23998,11 +23940,11 @@ async function readForkLineage(targetRoot, forkId) {
|
|
|
23998
23940
|
if (typeof forkId !== "string" || forkId.length === 0 || forkId.length > 64 || !CAPSULE_ID_PATTERN.test(forkId)) {
|
|
23999
23941
|
return null;
|
|
24000
23942
|
}
|
|
24001
|
-
const rootAbs =
|
|
23943
|
+
const rootAbs = path31.resolve(targetRoot);
|
|
24002
23944
|
const rootReal = await realpath2(rootAbs).catch(() => rootAbs);
|
|
24003
|
-
const lineagePath =
|
|
24004
|
-
const rel =
|
|
24005
|
-
if (rel.startsWith("..") ||
|
|
23945
|
+
const lineagePath = path31.join(rootReal, "forks", forkId, "lineage.json");
|
|
23946
|
+
const rel = path31.relative(rootReal, lineagePath);
|
|
23947
|
+
if (rel.startsWith("..") || path31.isAbsolute(rel)) {
|
|
24006
23948
|
return null;
|
|
24007
23949
|
}
|
|
24008
23950
|
if (!await isLineagePathContained(rootReal, lineagePath)) {
|
|
@@ -24043,19 +23985,19 @@ async function pathEntryExists(absPath) {
|
|
|
24043
23985
|
async function isLineagePathContained(rootReal, lineagePath) {
|
|
24044
23986
|
let existing = lineagePath;
|
|
24045
23987
|
const suffix = [];
|
|
24046
|
-
while (existing !==
|
|
23988
|
+
while (existing !== path31.dirname(existing)) {
|
|
24047
23989
|
const st = await lstat3(existing).catch(() => null);
|
|
24048
23990
|
if (st !== null) break;
|
|
24049
|
-
suffix.unshift(
|
|
24050
|
-
existing =
|
|
23991
|
+
suffix.unshift(path31.basename(existing));
|
|
23992
|
+
existing = path31.dirname(existing);
|
|
24051
23993
|
}
|
|
24052
23994
|
const existingReal = await realpath2(existing).catch(() => existing);
|
|
24053
|
-
const targetReal = suffix.length > 0 ?
|
|
24054
|
-
const rel =
|
|
23995
|
+
const targetReal = suffix.length > 0 ? path31.join(existingReal, ...suffix) : existingReal;
|
|
23996
|
+
const rel = path31.relative(rootReal, targetReal);
|
|
24055
23997
|
if (rel === "") return true;
|
|
24056
23998
|
if (rel === "..") return false;
|
|
24057
|
-
if (rel.startsWith(`..${
|
|
24058
|
-
if (
|
|
23999
|
+
if (rel.startsWith(`..${path31.sep}`)) return false;
|
|
24000
|
+
if (path31.isAbsolute(rel)) return false;
|
|
24059
24001
|
return true;
|
|
24060
24002
|
}
|
|
24061
24003
|
|
|
@@ -24172,7 +24114,6 @@ export {
|
|
|
24172
24114
|
mergeGraphExpandedResults,
|
|
24173
24115
|
graphPathRelativeToStorage,
|
|
24174
24116
|
blendGraphExpandedRecallScore,
|
|
24175
|
-
filterRecallCandidates,
|
|
24176
24117
|
Orchestrator
|
|
24177
24118
|
};
|
|
24178
|
-
//# sourceMappingURL=chunk-
|
|
24119
|
+
//# sourceMappingURL=chunk-SIP5DBDN.js.map
|