@remnic/core 10.0.66 → 10.0.68
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.js +16 -16
- package/dist/access-authorization-probe.js +17 -17
- package/dist/access-boundary.js +16 -16
- package/dist/access-cli.js +60 -60
- package/dist/access-extraction-force-flush.js +16 -16
- package/dist/access-http-briefing.js +17 -17
- package/dist/access-http-query.js +18 -18
- package/dist/access-http.js +33 -33
- package/dist/access-identity-continuity-surface.js +16 -16
- package/dist/access-lcm-surface.js +16 -16
- package/dist/access-mcp.js +26 -26
- package/dist/access-namespace-preflight.js +16 -16
- package/dist/access-observe-write-surface.js +16 -16
- package/dist/access-operations-batch.js +17 -17
- package/dist/access-operations.js +24 -24
- package/dist/access-recall-concurrency.js +16 -16
- package/dist/access-recall-diagnostics.js +2 -2
- package/dist/access-recall-response.js +16 -16
- package/dist/access-recall-surface.js +16 -16
- package/dist/access-service.js +16 -16
- package/dist/access-surface-catalog.js +18 -18
- package/dist/active-recall.js +3 -3
- package/dist/briefing.js +3 -3
- package/dist/buffer.js +2 -2
- package/dist/causal-consolidation.js +4 -4
- package/dist/{chunk-KISOMGY2.js → chunk-3RHU5MD7.js} +2 -2
- package/dist/{chunk-3H25IRJJ.js → chunk-4MPAKYZU.js} +2 -2
- package/dist/{chunk-IPCSZLLF.js → chunk-4NV7O76Q.js} +2 -2
- package/dist/{chunk-BH7NVSEC.js → chunk-4SOWMA55.js} +3 -3
- package/dist/{chunk-GROHOWR5.js → chunk-5MGKGEL7.js} +2 -2
- package/dist/{chunk-ZPLQ27MY.js → chunk-5UM4H64E.js} +2 -2
- package/dist/{chunk-2DNFRLLL.js → chunk-5Y6VA6X2.js} +2 -2
- package/dist/{chunk-RAU25Q6J.js → chunk-6WKWL53V.js} +13 -13
- package/dist/{chunk-KFPJIKUW.js → chunk-75DCOS6I.js} +23 -23
- package/dist/{chunk-25QK3LR2.js → chunk-7O2MC42R.js} +2 -2
- package/dist/{chunk-7ETWIBTO.js → chunk-ADYP7HXE.js} +3 -3
- package/dist/{chunk-FUDKGJDN.js → chunk-AVGDYYMA.js} +2 -2
- package/dist/{chunk-ECF627KC.js → chunk-AYJQ644F.js} +2 -2
- package/dist/{chunk-T763ADEK.js → chunk-B3MWELZ3.js} +2 -2
- package/dist/{chunk-DRTSPRWL.js → chunk-B4DXREWC.js} +2 -2
- package/dist/{chunk-5UEGL5BF.js → chunk-CI3MAAIY.js} +2 -2
- package/dist/{chunk-JYXFIILI.js → chunk-CTH2CQCB.js} +2 -2
- package/dist/{chunk-UVHXLVFJ.js → chunk-EURPSF4Y.js} +2 -2
- package/dist/{chunk-VPEA63FC.js → chunk-EWJZZDRG.js} +2 -2
- package/dist/{chunk-BOZQAUAJ.js → chunk-EXQJMFRF.js} +2 -2
- package/dist/{chunk-XMBDI725.js → chunk-FAF4A76Q.js} +684 -529
- package/dist/chunk-FAF4A76Q.js.map +1 -0
- package/dist/{chunk-VC65GNUS.js → chunk-GGD2YDS6.js} +2 -2
- package/dist/{chunk-5JABRT5G.js → chunk-GHHQLSSY.js} +3 -3
- package/dist/{chunk-FMYAU5MP.js → chunk-GJ4HU6LK.js} +2 -2
- package/dist/{chunk-3NJJQAL3.js → chunk-H5DIRCZP.js} +12 -12
- package/dist/{chunk-434E4BTO.js → chunk-HH73M65H.js} +3 -3
- package/dist/{chunk-LIGZO7XN.js → chunk-HPB5TF55.js} +2 -2
- package/dist/{chunk-E4QIX2OB.js → chunk-IAGVM7EY.js} +2 -2
- package/dist/{chunk-VC7GKR2V.js → chunk-IG3EZ3TF.js} +2 -2
- package/dist/{chunk-QAN5ZDRS.js → chunk-IVUVQPTQ.js} +2 -2
- package/dist/{chunk-XOFIJGB2.js → chunk-IZBIDPMY.js} +2 -2
- package/dist/{chunk-HFEGRMFG.js → chunk-JLGBJ4AX.js} +7 -7
- package/dist/{chunk-BBHKN2CN.js → chunk-JLMOH5JA.js} +2 -2
- package/dist/{chunk-TPCRDPUY.js → chunk-KZSGBWOJ.js} +2 -2
- package/dist/{chunk-SHHZWSSE.js → chunk-KZZ5EZ7O.js} +2 -2
- package/dist/{chunk-A5FOXI3B.js → chunk-LN4X2NDA.js} +2 -2
- package/dist/{chunk-5ZHFPUBC.js → chunk-MOIJWWNA.js} +8 -8
- package/dist/{chunk-KO224R36.js → chunk-NCZGGGWI.js} +2 -2
- package/dist/{chunk-XVQVF2TK.js → chunk-NHWDTOBN.js} +269 -230
- package/dist/chunk-NHWDTOBN.js.map +1 -0
- package/dist/{chunk-7ZTGMEXF.js → chunk-O5ZINWW3.js} +2 -2
- package/dist/{chunk-WWH7GJ42.js → chunk-OCK4D5PC.js} +2 -2
- package/dist/{chunk-G6L3REL3.js → chunk-OPFVXM2D.js} +2 -2
- package/dist/{chunk-FR7PK7ED.js → chunk-P4TV3TQ2.js} +2 -2
- package/dist/{chunk-ZGHPELZ6.js → chunk-PMDOGXA2.js} +2 -2
- package/dist/{chunk-NM2II57L.js → chunk-PRKNAIGZ.js} +2 -1
- package/dist/chunk-PRKNAIGZ.js.map +1 -0
- package/dist/{chunk-F32JRMX2.js → chunk-QGFR73SN.js} +2 -2
- package/dist/{chunk-QNZPYH36.js → chunk-R2BIVU2Z.js} +352 -290
- package/dist/chunk-R2BIVU2Z.js.map +1 -0
- package/dist/{chunk-HG3CG557.js → chunk-RLVI2M5Q.js} +2 -2
- package/dist/{chunk-SH6ZYUTX.js → chunk-SXTVZ6JL.js} +2 -2
- package/dist/{chunk-CLSKGTAT.js → chunk-TECK5IVY.js} +2 -2
- package/dist/{chunk-SNS3DWG6.js → chunk-TVE7W67N.js} +2 -2
- package/dist/{chunk-KYSSUY66.js → chunk-U2CAGMUD.js} +2 -2
- package/dist/{chunk-XLCEFUAU.js → chunk-UVVFPCPX.js} +2 -2
- package/dist/{chunk-PL75KQGF.js → chunk-UW6LBFYN.js} +5 -5
- package/dist/{chunk-SEA56G6S.js → chunk-V4XE263I.js} +1 -1
- package/dist/chunk-V4XE263I.js.map +1 -0
- package/dist/{chunk-VSZNPAGL.js → chunk-V6SBA5O7.js} +3 -3
- package/dist/{chunk-B7VD36TI.js → chunk-WHROVQ5Q.js} +3 -3
- package/dist/{chunk-LDHR465K.js → chunk-Y3XPSGNF.js} +2 -2
- package/dist/{chunk-E6VQJ75T.js → chunk-ZORS5BG5.js} +4 -4
- package/dist/{chunk-KXY4HW2Y.js → chunk-ZXF3O7P4.js} +2 -2
- package/dist/cli.js +46 -46
- package/dist/coding/export-okf-codegraph.js +2 -2
- package/dist/compounding/engine.js +4 -4
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +3 -3
- package/dist/connectors/codex-materialize-runner.js +3 -3
- package/dist/connectors/index.js +3 -3
- package/dist/convergence-refresh.js +5 -5
- package/dist/corpus-watermark.js +5 -5
- package/dist/entity-retrieval.js +3 -3
- package/dist/external-wiki-access.js +17 -17
- package/dist/extraction.js +6 -6
- package/dist/harmonic-retrieval.js +3 -3
- package/dist/index.js +60 -60
- package/dist/location/index.js +5 -5
- package/dist/maintenance/memory-governance.js +3 -3
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +3 -3
- package/dist/maintenance/rebuild-memory-projection-runner.js +5 -5
- package/dist/maintenance/rebuild-memory-projection.js +4 -4
- package/dist/memory-browse-operations.js +17 -17
- package/dist/namespaces/migrate.js +4 -4
- package/dist/namespaces/storage.js +3 -3
- package/dist/operator-doctor-corpus.js +6 -6
- package/dist/operator-toolkit.js +12 -12
- package/dist/orchestration/buffer-drain-runner.js +60 -60
- package/dist/orchestration/consolidation-run.d.ts.map +1 -1
- package/dist/orchestration/extraction-drain.d.ts +4 -4
- package/dist/orchestration/extraction-drain.d.ts.map +1 -1
- package/dist/orchestration/extraction-persist.d.ts.map +1 -1
- package/dist/orchestration/extraction-queue-coordinator.d.ts +67 -33
- package/dist/orchestration/extraction-queue-coordinator.d.ts.map +1 -1
- package/dist/orchestration/extraction-run.d.ts +1 -8
- package/dist/orchestration/extraction-run.d.ts.map +1 -1
- package/dist/orchestration/fact-dedup-window.d.ts +49 -0
- package/dist/orchestration/fact-dedup-window.d.ts.map +1 -0
- package/dist/orchestration/maintenance.js +13 -13
- package/dist/orchestration/provider-breaker.d.ts +58 -0
- package/dist/orchestration/provider-breaker.d.ts.map +1 -0
- package/dist/orchestrator.js +60 -60
- package/dist/recall-explain-renderer.js +3 -3
- package/dist/recall-navigate-access.js +2 -2
- package/dist/recall-navigate-disclosure.js +2 -2
- package/dist/recall-navigate.js +2 -2
- package/dist/recall-navigation-operations.js +17 -17
- package/dist/recall-navigation.js +16 -16
- package/dist/recall-xray-cli.js +4 -4
- package/dist/recall-xray-renderer.js +3 -3
- package/dist/recall-xray.js +2 -2
- package/dist/resume-bundles.js +4 -4
- package/dist/semantic-consolidation.js +4 -4
- package/dist/semantic-rule-promotion.js +3 -3
- package/dist/semantic-rule-verifier.js +3 -3
- package/dist/source-agent-qualifier.js +5 -5
- package/dist/standup/build.js +3 -3
- package/dist/storage/profile-mutation.d.ts +25 -0
- package/dist/storage/profile-mutation.d.ts.map +1 -0
- package/dist/storage.d.ts +4 -6
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +2 -2
- package/dist/support-passport/index.js +19 -19
- package/dist/transfer/export-okf.js +3 -3
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -1
- package/dist/verified-recall.js +3 -3
- package/dist/who-knows-cli.js +4 -4
- package/dist/who-knows.js +3 -3
- package/package.json +2 -2
- package/src/buffer-drain-handover.test.ts +3 -3
- package/src/buffer-drop-extraction-chunk.test.ts +0 -1
- package/src/config.test.ts +12 -0
- package/src/config.ts +2 -0
- package/src/extraction-parallel-dedup.test.ts +185 -0
- package/src/fact-dedup-window.test.ts +116 -0
- package/src/orchestration/consolidation-profile-race.test.ts +178 -0
- package/src/orchestration/consolidation-run.ts +19 -7
- package/src/orchestration/extraction-drain.ts +10 -3
- package/src/orchestration/extraction-persist.ts +156 -161
- package/src/orchestration/extraction-queue-coordinator.ts +167 -56
- package/src/orchestration/extraction-run.ts +50 -93
- package/src/orchestration/fact-dedup-window.ts +122 -0
- package/src/orchestration/provider-breaker.test.ts +111 -0
- package/src/orchestration/provider-breaker.ts +158 -0
- package/src/orchestration/turn-ingestion.ts +5 -5
- package/src/orchestrator-extraction-queue.test.ts +179 -8
- package/src/orchestrator.ts +1 -1
- package/src/storage/profile-mutation.ts +119 -0
- package/src/storage-append-profile.test.ts +114 -0
- package/src/storage.ts +17 -48
- package/src/types.ts +2 -0
- package/dist/chunk-NM2II57L.js.map +0 -1
- package/dist/chunk-QNZPYH36.js.map +0 -1
- package/dist/chunk-SEA56G6S.js.map +0 -1
- package/dist/chunk-XMBDI725.js.map +0 -1
- package/dist/chunk-XVQVF2TK.js.map +0 -1
- /package/dist/{chunk-KISOMGY2.js.map → chunk-3RHU5MD7.js.map} +0 -0
- /package/dist/{chunk-3H25IRJJ.js.map → chunk-4MPAKYZU.js.map} +0 -0
- /package/dist/{chunk-IPCSZLLF.js.map → chunk-4NV7O76Q.js.map} +0 -0
- /package/dist/{chunk-BH7NVSEC.js.map → chunk-4SOWMA55.js.map} +0 -0
- /package/dist/{chunk-GROHOWR5.js.map → chunk-5MGKGEL7.js.map} +0 -0
- /package/dist/{chunk-ZPLQ27MY.js.map → chunk-5UM4H64E.js.map} +0 -0
- /package/dist/{chunk-2DNFRLLL.js.map → chunk-5Y6VA6X2.js.map} +0 -0
- /package/dist/{chunk-RAU25Q6J.js.map → chunk-6WKWL53V.js.map} +0 -0
- /package/dist/{chunk-KFPJIKUW.js.map → chunk-75DCOS6I.js.map} +0 -0
- /package/dist/{chunk-25QK3LR2.js.map → chunk-7O2MC42R.js.map} +0 -0
- /package/dist/{chunk-7ETWIBTO.js.map → chunk-ADYP7HXE.js.map} +0 -0
- /package/dist/{chunk-FUDKGJDN.js.map → chunk-AVGDYYMA.js.map} +0 -0
- /package/dist/{chunk-ECF627KC.js.map → chunk-AYJQ644F.js.map} +0 -0
- /package/dist/{chunk-T763ADEK.js.map → chunk-B3MWELZ3.js.map} +0 -0
- /package/dist/{chunk-DRTSPRWL.js.map → chunk-B4DXREWC.js.map} +0 -0
- /package/dist/{chunk-5UEGL5BF.js.map → chunk-CI3MAAIY.js.map} +0 -0
- /package/dist/{chunk-JYXFIILI.js.map → chunk-CTH2CQCB.js.map} +0 -0
- /package/dist/{chunk-UVHXLVFJ.js.map → chunk-EURPSF4Y.js.map} +0 -0
- /package/dist/{chunk-VPEA63FC.js.map → chunk-EWJZZDRG.js.map} +0 -0
- /package/dist/{chunk-BOZQAUAJ.js.map → chunk-EXQJMFRF.js.map} +0 -0
- /package/dist/{chunk-VC65GNUS.js.map → chunk-GGD2YDS6.js.map} +0 -0
- /package/dist/{chunk-5JABRT5G.js.map → chunk-GHHQLSSY.js.map} +0 -0
- /package/dist/{chunk-FMYAU5MP.js.map → chunk-GJ4HU6LK.js.map} +0 -0
- /package/dist/{chunk-3NJJQAL3.js.map → chunk-H5DIRCZP.js.map} +0 -0
- /package/dist/{chunk-434E4BTO.js.map → chunk-HH73M65H.js.map} +0 -0
- /package/dist/{chunk-LIGZO7XN.js.map → chunk-HPB5TF55.js.map} +0 -0
- /package/dist/{chunk-E4QIX2OB.js.map → chunk-IAGVM7EY.js.map} +0 -0
- /package/dist/{chunk-VC7GKR2V.js.map → chunk-IG3EZ3TF.js.map} +0 -0
- /package/dist/{chunk-QAN5ZDRS.js.map → chunk-IVUVQPTQ.js.map} +0 -0
- /package/dist/{chunk-XOFIJGB2.js.map → chunk-IZBIDPMY.js.map} +0 -0
- /package/dist/{chunk-HFEGRMFG.js.map → chunk-JLGBJ4AX.js.map} +0 -0
- /package/dist/{chunk-BBHKN2CN.js.map → chunk-JLMOH5JA.js.map} +0 -0
- /package/dist/{chunk-TPCRDPUY.js.map → chunk-KZSGBWOJ.js.map} +0 -0
- /package/dist/{chunk-SHHZWSSE.js.map → chunk-KZZ5EZ7O.js.map} +0 -0
- /package/dist/{chunk-A5FOXI3B.js.map → chunk-LN4X2NDA.js.map} +0 -0
- /package/dist/{chunk-5ZHFPUBC.js.map → chunk-MOIJWWNA.js.map} +0 -0
- /package/dist/{chunk-KO224R36.js.map → chunk-NCZGGGWI.js.map} +0 -0
- /package/dist/{chunk-7ZTGMEXF.js.map → chunk-O5ZINWW3.js.map} +0 -0
- /package/dist/{chunk-WWH7GJ42.js.map → chunk-OCK4D5PC.js.map} +0 -0
- /package/dist/{chunk-G6L3REL3.js.map → chunk-OPFVXM2D.js.map} +0 -0
- /package/dist/{chunk-FR7PK7ED.js.map → chunk-P4TV3TQ2.js.map} +0 -0
- /package/dist/{chunk-ZGHPELZ6.js.map → chunk-PMDOGXA2.js.map} +0 -0
- /package/dist/{chunk-F32JRMX2.js.map → chunk-QGFR73SN.js.map} +0 -0
- /package/dist/{chunk-HG3CG557.js.map → chunk-RLVI2M5Q.js.map} +0 -0
- /package/dist/{chunk-SH6ZYUTX.js.map → chunk-SXTVZ6JL.js.map} +0 -0
- /package/dist/{chunk-CLSKGTAT.js.map → chunk-TECK5IVY.js.map} +0 -0
- /package/dist/{chunk-SNS3DWG6.js.map → chunk-TVE7W67N.js.map} +0 -0
- /package/dist/{chunk-KYSSUY66.js.map → chunk-U2CAGMUD.js.map} +0 -0
- /package/dist/{chunk-XLCEFUAU.js.map → chunk-UVVFPCPX.js.map} +0 -0
- /package/dist/{chunk-PL75KQGF.js.map → chunk-UW6LBFYN.js.map} +0 -0
- /package/dist/{chunk-VSZNPAGL.js.map → chunk-V6SBA5O7.js.map} +0 -0
- /package/dist/{chunk-B7VD36TI.js.map → chunk-WHROVQ5Q.js.map} +0 -0
- /package/dist/{chunk-LDHR465K.js.map → chunk-Y3XPSGNF.js.map} +0 -0
- /package/dist/{chunk-E6VQJ75T.js.map → chunk-ZORS5BG5.js.map} +0 -0
- /package/dist/{chunk-KXY4HW2Y.js.map → chunk-ZXF3O7P4.js.map} +0 -0
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
import {
|
|
14
14
|
ActivityStore,
|
|
15
15
|
MaintenanceScheduler
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-JLGBJ4AX.js";
|
|
17
17
|
import {
|
|
18
18
|
runPeerProfileReasoner
|
|
19
19
|
} from "./chunk-I74SUMNI.js";
|
|
@@ -32,7 +32,7 @@ import {
|
|
|
32
32
|
import {
|
|
33
33
|
CompoundingEngine,
|
|
34
34
|
defaultTierMigrationCycleBudget
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-GHHQLSSY.js";
|
|
36
36
|
import {
|
|
37
37
|
SharedContextManager
|
|
38
38
|
} from "./chunk-5KBIOI4G.js";
|
|
@@ -175,7 +175,7 @@ import {
|
|
|
175
175
|
} from "./chunk-VA3GNAWQ.js";
|
|
176
176
|
import {
|
|
177
177
|
ExtractionEngine
|
|
178
|
-
} from "./chunk-
|
|
178
|
+
} from "./chunk-LN4X2NDA.js";
|
|
179
179
|
import {
|
|
180
180
|
parseMemoryActionEligibilityContext
|
|
181
181
|
} from "./chunk-JHU4EYDV.js";
|
|
@@ -210,7 +210,7 @@ import {
|
|
|
210
210
|
buildEntityRecallSection,
|
|
211
211
|
entityRecentTranscriptLookbackHours,
|
|
212
212
|
readRecentEntityTranscriptEntries
|
|
213
|
-
} from "./chunk-
|
|
213
|
+
} from "./chunk-NCZGGGWI.js";
|
|
214
214
|
import {
|
|
215
215
|
planEpisodeWindowsWithFallback
|
|
216
216
|
} from "./chunk-T3GIETKV.js";
|
|
@@ -225,7 +225,7 @@ import {
|
|
|
225
225
|
} from "./chunk-7G5NTS7F.js";
|
|
226
226
|
import {
|
|
227
227
|
refreshConvergedNamespaces
|
|
228
|
-
} from "./chunk-
|
|
228
|
+
} from "./chunk-OCK4D5PC.js";
|
|
229
229
|
import {
|
|
230
230
|
builtInConnectorPackageSpecifier,
|
|
231
231
|
ensureBuiltInWearableConnectors,
|
|
@@ -234,7 +234,7 @@ import {
|
|
|
234
234
|
runTimelinePublishCli,
|
|
235
235
|
screenCandidateFact,
|
|
236
236
|
summarizeVaultPublish
|
|
237
|
-
} from "./chunk-
|
|
237
|
+
} from "./chunk-75DCOS6I.js";
|
|
238
238
|
import {
|
|
239
239
|
normalizeReplaySessionKey
|
|
240
240
|
} from "./chunk-AJVLDJU6.js";
|
|
@@ -244,14 +244,14 @@ import {
|
|
|
244
244
|
import {
|
|
245
245
|
compareVerifiedEpisodeResults,
|
|
246
246
|
searchVerifiedEpisodes
|
|
247
|
-
} from "./chunk-
|
|
247
|
+
} from "./chunk-KZZ5EZ7O.js";
|
|
248
248
|
import {
|
|
249
249
|
ThreadingManager
|
|
250
250
|
} from "./chunk-VHSQU3RO.js";
|
|
251
251
|
import {
|
|
252
252
|
compareVerifiedSemanticRuleResults,
|
|
253
253
|
searchVerifiedSemanticRules
|
|
254
|
-
} from "./chunk-
|
|
254
|
+
} from "./chunk-TVE7W67N.js";
|
|
255
255
|
import {
|
|
256
256
|
searchWorkProductLedgerEntries
|
|
257
257
|
} from "./chunk-B2NXOVZN.js";
|
|
@@ -264,10 +264,10 @@ import {
|
|
|
264
264
|
import {
|
|
265
265
|
runNamespaceMaintenanceFanout,
|
|
266
266
|
summarizeNamespaceMaintenanceHealth
|
|
267
|
-
} from "./chunk-
|
|
267
|
+
} from "./chunk-MOIJWWNA.js";
|
|
268
268
|
import {
|
|
269
269
|
planNamespaceMaintenance
|
|
270
|
-
} from "./chunk-
|
|
270
|
+
} from "./chunk-HH73M65H.js";
|
|
271
271
|
import {
|
|
272
272
|
isAboveImportanceThreshold,
|
|
273
273
|
scoreImportance
|
|
@@ -296,10 +296,10 @@ import {
|
|
|
296
296
|
materializeAfterSemanticConsolidation,
|
|
297
297
|
parseConsolidationResponse,
|
|
298
298
|
parseOperatorAwareConsolidationResponse
|
|
299
|
-
} from "./chunk-
|
|
299
|
+
} from "./chunk-AYJQ644F.js";
|
|
300
300
|
import {
|
|
301
301
|
SmartBuffer
|
|
302
|
-
} from "./chunk-
|
|
302
|
+
} from "./chunk-4MPAKYZU.js";
|
|
303
303
|
import {
|
|
304
304
|
semanticChunkContent
|
|
305
305
|
} from "./chunk-2GBFKHBZ.js";
|
|
@@ -335,7 +335,7 @@ import {
|
|
|
335
335
|
embeddingsFromCosineHits,
|
|
336
336
|
normalizeConnectorScope,
|
|
337
337
|
runSeedGraduationPass
|
|
338
|
-
} from "./chunk-
|
|
338
|
+
} from "./chunk-PRKNAIGZ.js";
|
|
339
339
|
import {
|
|
340
340
|
compileCorrectionRule,
|
|
341
341
|
correctionsFilePath,
|
|
@@ -373,7 +373,7 @@ import {
|
|
|
373
373
|
} from "./chunk-QW27DOHG.js";
|
|
374
374
|
import {
|
|
375
375
|
MeetingsInputError
|
|
376
|
-
} from "./chunk-
|
|
376
|
+
} from "./chunk-H5DIRCZP.js";
|
|
377
377
|
import {
|
|
378
378
|
WearablesInputError,
|
|
379
379
|
describeErrorForOperator
|
|
@@ -391,7 +391,7 @@ import {
|
|
|
391
391
|
} from "./chunk-W7K5BP3M.js";
|
|
392
392
|
import {
|
|
393
393
|
NamespaceCatalog
|
|
394
|
-
} from "./chunk-
|
|
394
|
+
} from "./chunk-CI3MAAIY.js";
|
|
395
395
|
import {
|
|
396
396
|
RecallResultFormatter,
|
|
397
397
|
SessionContextCoordinator,
|
|
@@ -400,7 +400,7 @@ import {
|
|
|
400
400
|
detectPassiveCorrections,
|
|
401
401
|
renderSessionExperiencePreview,
|
|
402
402
|
scoreSessionExperienceForPrompt
|
|
403
|
-
} from "./chunk-
|
|
403
|
+
} from "./chunk-6WKWL53V.js";
|
|
404
404
|
import {
|
|
405
405
|
importCapsule
|
|
406
406
|
} from "./chunk-QDZWQBLU.js";
|
|
@@ -429,7 +429,7 @@ import {
|
|
|
429
429
|
} from "./chunk-MUHGYV2V.js";
|
|
430
430
|
import {
|
|
431
431
|
buildXraySnapshot
|
|
432
|
-
} from "./chunk-
|
|
432
|
+
} from "./chunk-7O2MC42R.js";
|
|
433
433
|
import {
|
|
434
434
|
objectiveStateStoreOverrideForNamespace,
|
|
435
435
|
searchObjectiveStateSnapshots
|
|
@@ -443,7 +443,7 @@ import {
|
|
|
443
443
|
} from "./chunk-BJLCV2P3.js";
|
|
444
444
|
import {
|
|
445
445
|
searchHarmonicRetrieval
|
|
446
|
-
} from "./chunk-
|
|
446
|
+
} from "./chunk-EXQJMFRF.js";
|
|
447
447
|
import {
|
|
448
448
|
ProfilingCollector
|
|
449
449
|
} from "./chunk-DOWACHYO.js";
|
|
@@ -466,7 +466,7 @@ import {
|
|
|
466
466
|
} from "./chunk-NVKO5YKP.js";
|
|
467
467
|
import {
|
|
468
468
|
NamespaceStorageRouter
|
|
469
|
-
} from "./chunk-
|
|
469
|
+
} from "./chunk-5UM4H64E.js";
|
|
470
470
|
import {
|
|
471
471
|
pruneOrphanCueAnchors
|
|
472
472
|
} from "./chunk-LXATZLSC.js";
|
|
@@ -480,7 +480,7 @@ import {
|
|
|
480
480
|
ExtractionDeadlineError,
|
|
481
481
|
ExtractionRunCoordinator,
|
|
482
482
|
classifyExtractionOrigin
|
|
483
|
-
} from "./chunk-
|
|
483
|
+
} from "./chunk-R2BIVU2Z.js";
|
|
484
484
|
import {
|
|
485
485
|
ARTIFACT_STATUS_CACHE_TTL_MS,
|
|
486
486
|
BulkImportBatchPartialFailureError,
|
|
@@ -532,7 +532,7 @@ import {
|
|
|
532
532
|
} from "./chunk-74AY3S7U.js";
|
|
533
533
|
import {
|
|
534
534
|
buildChainFollowupGenerator
|
|
535
|
-
} from "./chunk-
|
|
535
|
+
} from "./chunk-IAGVM7EY.js";
|
|
536
536
|
import {
|
|
537
537
|
decideLifecycleTransition,
|
|
538
538
|
resolveLifecycleState
|
|
@@ -577,7 +577,7 @@ import {
|
|
|
577
577
|
reconstructFusionInputs,
|
|
578
578
|
selfDeps,
|
|
579
579
|
serializeFusionDay
|
|
580
|
-
} from "./chunk-
|
|
580
|
+
} from "./chunk-NHWDTOBN.js";
|
|
581
581
|
import {
|
|
582
582
|
bodyIsEscaped,
|
|
583
583
|
decodeTranscriptBody,
|
|
@@ -707,7 +707,7 @@ import {
|
|
|
707
707
|
} from "./chunk-PJKTFXE2.js";
|
|
708
708
|
import {
|
|
709
709
|
confidenceTier
|
|
710
|
-
} from "./chunk-
|
|
710
|
+
} from "./chunk-V4XE263I.js";
|
|
711
711
|
import {
|
|
712
712
|
extractJsonCandidates
|
|
713
713
|
} from "./chunk-YBA52OKG.js";
|
|
@@ -796,6 +796,7 @@ import {
|
|
|
796
796
|
assertRealpathInsideRoot
|
|
797
797
|
} from "./chunk-GCGJW34D.js";
|
|
798
798
|
import {
|
|
799
|
+
serializeMutations,
|
|
799
800
|
withHeldFileLock
|
|
800
801
|
} from "./chunk-EBV6VXKF.js";
|
|
801
802
|
import {
|
|
@@ -890,7 +891,7 @@ import {
|
|
|
890
891
|
} from "./chunk-3WCASNQZ.js";
|
|
891
892
|
|
|
892
893
|
// src/orchestrator.ts
|
|
893
|
-
import
|
|
894
|
+
import path24 from "path";
|
|
894
895
|
import { createHash as createHash10 } from "crypto";
|
|
895
896
|
|
|
896
897
|
// src/orchestration/buffer-swap.ts
|
|
@@ -1077,35 +1078,51 @@ var TierMigrationCoordinator = class {
|
|
|
1077
1078
|
|
|
1078
1079
|
// src/orchestration/extraction-queue-coordinator.ts
|
|
1079
1080
|
var ExtractionQueueCoordinator = class {
|
|
1081
|
+
/** Maximum tasks that run at the same time (config `extractionQueueConcurrency`). */
|
|
1082
|
+
concurrency;
|
|
1080
1083
|
/**
|
|
1081
|
-
* Background
|
|
1082
|
-
*
|
|
1084
|
+
* Background queue for extractions (agent_end optimization). Queue stores
|
|
1085
|
+
* tasks that resolve when extraction should run.
|
|
1083
1086
|
*/
|
|
1084
1087
|
queue = [];
|
|
1085
|
-
/** Whether the
|
|
1088
|
+
/** Whether the drain loop is currently running. */
|
|
1086
1089
|
processing = false;
|
|
1087
1090
|
accepting = true;
|
|
1088
|
-
|
|
1091
|
+
/** Buffer keys with a task currently running (per-key exclusion). */
|
|
1092
|
+
activeKeys = /* @__PURE__ */ new Set();
|
|
1093
|
+
/** Preempt slots of the currently running tasks, keyed by slot identity. */
|
|
1094
|
+
preemptSlots = /* @__PURE__ */ new Map();
|
|
1095
|
+
preemptSeq = 0;
|
|
1096
|
+
/** Resolves the processor's park while a new task arrives mid-drain. */
|
|
1097
|
+
wake;
|
|
1098
|
+
constructor(concurrency = 1) {
|
|
1099
|
+
this.concurrency = Number.isInteger(concurrency) && concurrency >= 1 ? concurrency : 1;
|
|
1100
|
+
}
|
|
1089
1101
|
/** Current queue depth (idle-wait + test seam). */
|
|
1090
1102
|
get length() {
|
|
1091
1103
|
return this.queue.length;
|
|
1092
1104
|
}
|
|
1093
|
-
/** Whether the
|
|
1105
|
+
/** Whether the drain loop is currently running (idle-wait + test seam). */
|
|
1094
1106
|
get isProcessing() {
|
|
1095
1107
|
return this.processing;
|
|
1096
1108
|
}
|
|
1109
|
+
/** How many tasks may run at once (test seam + diagnostics). */
|
|
1110
|
+
get maxConcurrency() {
|
|
1111
|
+
return this.concurrency;
|
|
1112
|
+
}
|
|
1097
1113
|
/**
|
|
1098
|
-
* Enqueue a task and start the
|
|
1114
|
+
* Enqueue a task and start the processor when capacity is free. This is
|
|
1099
1115
|
* the production entry point — the orchestrator's `queueBufferedExtraction`
|
|
1100
|
-
* builds each task closure and hands it here.
|
|
1116
|
+
* builds each task closure and hands it here with its buffer key.
|
|
1101
1117
|
*/
|
|
1102
1118
|
enqueue(task, options) {
|
|
1103
1119
|
if (!this.accepting) return false;
|
|
1120
|
+
const entry = { run: task, key: options?.key };
|
|
1104
1121
|
if (options?.front) {
|
|
1105
|
-
this.preemptRunning();
|
|
1106
|
-
this.queue.unshift(
|
|
1122
|
+
this.preemptRunning(options.key);
|
|
1123
|
+
this.queue.unshift(entry);
|
|
1107
1124
|
} else {
|
|
1108
|
-
this.queue.push(
|
|
1125
|
+
this.queue.push(entry);
|
|
1109
1126
|
}
|
|
1110
1127
|
if (!this.processing) {
|
|
1111
1128
|
this.processing = true;
|
|
@@ -1113,27 +1130,28 @@ var ExtractionQueueCoordinator = class {
|
|
|
1113
1130
|
this.logExtractionQueueFailure(err, "processor");
|
|
1114
1131
|
this.processing = false;
|
|
1115
1132
|
});
|
|
1133
|
+
} else {
|
|
1134
|
+
this.wake?.();
|
|
1116
1135
|
}
|
|
1117
1136
|
return true;
|
|
1118
1137
|
}
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
preemptRunning() {
|
|
1127
|
-
const abort = this.runningPreempt;
|
|
1128
|
-
this.runningPreempt = void 0;
|
|
1138
|
+
preemptRunning(preferredKey) {
|
|
1139
|
+
const armed = Array.from(this.preemptSlots.values()).filter((slot) => slot.armed !== void 0);
|
|
1140
|
+
if (armed.length === 0) return;
|
|
1141
|
+
const preferred = preferredKey !== void 0 ? armed.find((slot) => slot.key === preferredKey) : void 0;
|
|
1142
|
+
const chosen = preferred ?? armed.reduce((a, b) => (b.armed?.seq ?? -1) > (a.armed?.seq ?? -1) ? b : a);
|
|
1143
|
+
const abort = chosen.armed?.abort;
|
|
1144
|
+
chosen.armed = void 0;
|
|
1129
1145
|
abort?.();
|
|
1130
1146
|
}
|
|
1131
|
-
runPreemptable(preemptable, parent, run) {
|
|
1132
|
-
const
|
|
1133
|
-
if (preemptable
|
|
1134
|
-
|
|
1147
|
+
runPreemptable(preempt, preemptable, parent, run) {
|
|
1148
|
+
const preemptController = new AbortController();
|
|
1149
|
+
if (preemptable && preempt) {
|
|
1150
|
+
preempt.arm(() => preemptController.abort(preemptedExtractionError()));
|
|
1151
|
+
}
|
|
1152
|
+
const signal = parent ? AbortSignal.any([parent, preemptController.signal]) : preemptController.signal;
|
|
1135
1153
|
return Promise.resolve(run(signal)).finally(() => {
|
|
1136
|
-
if (preemptable)
|
|
1154
|
+
if (preemptable && preempt) preempt.disarm();
|
|
1137
1155
|
});
|
|
1138
1156
|
}
|
|
1139
1157
|
/** Stop new producers from entering the queue. */
|
|
@@ -1153,28 +1171,75 @@ var ExtractionQueueCoordinator = class {
|
|
|
1153
1171
|
return true;
|
|
1154
1172
|
}
|
|
1155
1173
|
/**
|
|
1156
|
-
* Background
|
|
1157
|
-
*
|
|
1158
|
-
*
|
|
1159
|
-
*
|
|
1160
|
-
* semantics directly.
|
|
1174
|
+
* Background queue processor. Runs up to `concurrency` tasks at a time,
|
|
1175
|
+
* never two tasks with the same entry key. Called automatically when items
|
|
1176
|
+
* are queued via `enqueue`; also exposed for the characterization tests
|
|
1177
|
+
* that push raw tasks and assert drain semantics directly.
|
|
1161
1178
|
*/
|
|
1162
1179
|
async processQueue() {
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1180
|
+
const inFlight = /* @__PURE__ */ new Set();
|
|
1181
|
+
try {
|
|
1182
|
+
while (this.queue.length > 0 || inFlight.size > 0) {
|
|
1183
|
+
while (inFlight.size < this.concurrency) {
|
|
1184
|
+
const entry = this.takeRunnable();
|
|
1185
|
+
if (!entry) break;
|
|
1186
|
+
const running = this.runEntry(entry).finally(() => {
|
|
1187
|
+
inFlight.delete(running);
|
|
1188
|
+
});
|
|
1189
|
+
inFlight.add(running);
|
|
1190
|
+
}
|
|
1191
|
+
if (inFlight.size === 0) break;
|
|
1192
|
+
const { promise: wakePromise, resolve: wake } = Promise.withResolvers();
|
|
1193
|
+
this.wake = wake;
|
|
1166
1194
|
try {
|
|
1167
|
-
await
|
|
1168
|
-
}
|
|
1169
|
-
this.
|
|
1195
|
+
await Promise.race([wakePromise, ...inFlight]);
|
|
1196
|
+
} finally {
|
|
1197
|
+
this.wake = void 0;
|
|
1170
1198
|
}
|
|
1171
1199
|
}
|
|
1200
|
+
} finally {
|
|
1201
|
+
this.processing = false;
|
|
1202
|
+
}
|
|
1203
|
+
}
|
|
1204
|
+
/** Take the next queue entry whose key is not already running (FIFO within a key). */
|
|
1205
|
+
takeRunnable() {
|
|
1206
|
+
for (let index = 0; index < this.queue.length; index += 1) {
|
|
1207
|
+
const entry = this.queue[index];
|
|
1208
|
+
if (entry.key !== void 0 && this.activeKeys.has(entry.key)) continue;
|
|
1209
|
+
this.queue.splice(index, 1);
|
|
1210
|
+
if (entry.key !== void 0) this.activeKeys.add(entry.key);
|
|
1211
|
+
return entry;
|
|
1212
|
+
}
|
|
1213
|
+
return void 0;
|
|
1214
|
+
}
|
|
1215
|
+
/** Run one entry with its own preempt slot; failures are classified + logged. */
|
|
1216
|
+
async runEntry(entry) {
|
|
1217
|
+
const slot = {};
|
|
1218
|
+
this.preemptSlots.set(slot, { key: entry.key });
|
|
1219
|
+
try {
|
|
1220
|
+
await entry.run(this.createPreemptHandle(slot));
|
|
1221
|
+
} catch (err) {
|
|
1222
|
+
this.logExtractionQueueFailure(err, "task");
|
|
1223
|
+
} finally {
|
|
1224
|
+
this.preemptSlots.delete(slot);
|
|
1225
|
+
if (entry.key !== void 0) this.activeKeys.delete(entry.key);
|
|
1172
1226
|
}
|
|
1173
|
-
|
|
1227
|
+
}
|
|
1228
|
+
createPreemptHandle(slot) {
|
|
1229
|
+
return {
|
|
1230
|
+
arm: (abort) => {
|
|
1231
|
+
const state = this.preemptSlots.get(slot);
|
|
1232
|
+
if (state) state.armed = { abort, seq: this.preemptSeq++ };
|
|
1233
|
+
},
|
|
1234
|
+
disarm: () => {
|
|
1235
|
+
const state = this.preemptSlots.get(slot);
|
|
1236
|
+
if (state) state.armed = void 0;
|
|
1237
|
+
}
|
|
1238
|
+
};
|
|
1174
1239
|
}
|
|
1175
1240
|
/**
|
|
1176
1241
|
* Classify + log a failure from either the per-task catch inside
|
|
1177
|
-
* `
|
|
1242
|
+
* `runEntry` or the outer `processQueue().catch(...)` in
|
|
1178
1243
|
* `enqueue()`. Issue #549: `throwIfRecallAborted`
|
|
1179
1244
|
* (used throughout `runExtraction`) raises an Error whose `name` is
|
|
1180
1245
|
* `"AbortError"`. That path fires when `before_reset` aborts a
|
|
@@ -1227,12 +1292,13 @@ var ExtractionQueueCoordinator = class {
|
|
|
1227
1292
|
* pre-extraction `this.extractionQueue.push(...)` used by the
|
|
1228
1293
|
* characterization tests that drive the drain manually via `processQueue`.
|
|
1229
1294
|
*/
|
|
1230
|
-
pushRaw(task) {
|
|
1231
|
-
this.queue.push(task);
|
|
1295
|
+
pushRaw(task, options) {
|
|
1296
|
+
this.queue.push({ run: task, key: options?.key });
|
|
1297
|
+
this.wake?.();
|
|
1232
1298
|
}
|
|
1233
1299
|
/** Remove + return the front task (test seam for the flush deadline tests). */
|
|
1234
1300
|
shift() {
|
|
1235
|
-
return this.queue.shift();
|
|
1301
|
+
return this.queue.shift()?.run;
|
|
1236
1302
|
}
|
|
1237
1303
|
/**
|
|
1238
1304
|
* Force the processor-busy flag so `enqueue` does not auto-start the
|
|
@@ -2495,7 +2561,7 @@ var RecallRerankCoordinator = class _RecallRerankCoordinator {
|
|
|
2495
2561
|
namespaces,
|
|
2496
2562
|
{
|
|
2497
2563
|
readNamespaceMemories: async (ns) => (await this.getStorage(ns)).readAllMemories(),
|
|
2498
|
-
readMemoryFrontmatter: async (
|
|
2564
|
+
readMemoryFrontmatter: async (path42, preferredNamespace) => {
|
|
2499
2565
|
if (!fallbackReader) {
|
|
2500
2566
|
for (const ns of namespaces) {
|
|
2501
2567
|
try {
|
|
@@ -2507,7 +2573,7 @@ var RecallRerankCoordinator = class _RecallRerankCoordinator {
|
|
|
2507
2573
|
}
|
|
2508
2574
|
if (!fallbackReader) return null;
|
|
2509
2575
|
const memory = await this.readQmdResultMemory(
|
|
2510
|
-
|
|
2576
|
+
path42,
|
|
2511
2577
|
fallbackReader,
|
|
2512
2578
|
namespaces,
|
|
2513
2579
|
preferredNamespace
|
|
@@ -4798,11 +4864,20 @@ var ConsolidationRunCoordinator = class {
|
|
|
4798
4864
|
profileConsolidationTargetLines
|
|
4799
4865
|
);
|
|
4800
4866
|
if (profileResult) {
|
|
4801
|
-
await storage.
|
|
4802
|
-
|
|
4803
|
-
|
|
4804
|
-
`profile.md consolidated: removed ${profileResult.removedCount} items \u2014 ${profileResult.summary}`
|
|
4867
|
+
const outcome = await storage.commitConsolidatedProfile(
|
|
4868
|
+
currentProfile,
|
|
4869
|
+
profileResult.consolidatedProfile
|
|
4805
4870
|
);
|
|
4871
|
+
if (outcome === "conflict") {
|
|
4872
|
+
log.info(
|
|
4873
|
+
"profile.md changed during consolidation \u2014 skipping stale rewrite (retries next pass)"
|
|
4874
|
+
);
|
|
4875
|
+
} else {
|
|
4876
|
+
memoryItemMutated = true;
|
|
4877
|
+
log.info(
|
|
4878
|
+
`profile.md consolidated: removed ${profileResult.removedCount} items \u2014 ${profileResult.summary}`
|
|
4879
|
+
);
|
|
4880
|
+
}
|
|
4806
4881
|
}
|
|
4807
4882
|
}
|
|
4808
4883
|
}
|
|
@@ -4895,6 +4970,78 @@ ${texts.map((t, i) => `[${i + 1}] ${t}`).join("\n\n")}`;
|
|
|
4895
4970
|
}
|
|
4896
4971
|
};
|
|
4897
4972
|
|
|
4973
|
+
// src/orchestration/fact-dedup-window.ts
|
|
4974
|
+
import path5 from "path";
|
|
4975
|
+
|
|
4976
|
+
// src/orchestration/extraction-persist-citation.ts
|
|
4977
|
+
function normalizeStoredHashSource(raw, citationEnabled, citationTemplate) {
|
|
4978
|
+
return ContentHashIndex.normalizeContent(
|
|
4979
|
+
sanitizeMemoryContent(
|
|
4980
|
+
citationEnabled && hasCitationForTemplate(raw, citationTemplate) ? stripCitationForTemplate(raw, citationTemplate) : raw
|
|
4981
|
+
).text
|
|
4982
|
+
);
|
|
4983
|
+
}
|
|
4984
|
+
function applyInlineCitation(content, citationEnabled, citationTemplate, citationContextBase) {
|
|
4985
|
+
if (!citationEnabled) return content;
|
|
4986
|
+
if (typeof content !== "string" || content.length === 0) return content;
|
|
4987
|
+
const citationContext = {
|
|
4988
|
+
...citationContextBase,
|
|
4989
|
+
ts: (/* @__PURE__ */ new Date()).toISOString()
|
|
4990
|
+
};
|
|
4991
|
+
return attachCitation(content, citationContext, citationTemplate);
|
|
4992
|
+
}
|
|
4993
|
+
|
|
4994
|
+
// src/orchestration/fact-dedup-window.ts
|
|
4995
|
+
function matchesActiveConnectorDuplicate(memory, opts) {
|
|
4996
|
+
if (memory.frontmatter.category !== opts.category) return false;
|
|
4997
|
+
if ((memory.frontmatter.status ?? "active") !== "active") return false;
|
|
4998
|
+
if (normalizeStoredHashSource(stripAttributesSuffix(memory.content ?? ""), opts.citationEnabled, opts.citationTemplate) !== ContentHashIndex.normalizeContent(opts.contentHashDedupKey)) return false;
|
|
4999
|
+
return (memory.frontmatter.sourceConnector?.trim() || void 0) === opts.connector;
|
|
5000
|
+
}
|
|
5001
|
+
async function confirmActiveFactDuplicate(probe, storage, opts) {
|
|
5002
|
+
let needsCorpusConfirm;
|
|
5003
|
+
try {
|
|
5004
|
+
if (!await probe.hasContentHashDedup(storage, opts.contentHashDedupKey)) {
|
|
5005
|
+
if (await storage.isFactContentHashAuthoritative()) return false;
|
|
5006
|
+
needsCorpusConfirm = true;
|
|
5007
|
+
} else {
|
|
5008
|
+
needsCorpusConfirm = true;
|
|
5009
|
+
}
|
|
5010
|
+
} catch {
|
|
5011
|
+
needsCorpusConfirm = true;
|
|
5012
|
+
}
|
|
5013
|
+
try {
|
|
5014
|
+
const [hotMems, coldMems] = await Promise.all([
|
|
5015
|
+
storage.readAllMemories(),
|
|
5016
|
+
storage.readAllColdMemories()
|
|
5017
|
+
]);
|
|
5018
|
+
return hotMems.some((m) => matchesActiveConnectorDuplicate(m, opts)) || coldMems.some((m) => matchesActiveConnectorDuplicate(m, opts));
|
|
5019
|
+
} catch (err) {
|
|
5020
|
+
log.warn(
|
|
5021
|
+
`connector-aware dedup scan failed for storage ${storage.dir}; writing fail-open: ${err instanceof Error ? err.message : String(err)}`
|
|
5022
|
+
);
|
|
5023
|
+
return false;
|
|
5024
|
+
}
|
|
5025
|
+
}
|
|
5026
|
+
async function persistUnderFactDedupWindow(storageDir, recheck, write) {
|
|
5027
|
+
return serializeMutations(
|
|
5028
|
+
`fact-dedup:${storageDir}`,
|
|
5029
|
+
() => withHeldFileLock(
|
|
5030
|
+
path5.join(storageDir, "fact-dedup.lock"),
|
|
5031
|
+
// Bounded: the window holds one corpus confirm + one memory write, not a
|
|
5032
|
+
// scan-length lock (catalog round 5 adoption note).
|
|
5033
|
+
{ staleMs: 5e3, maxWaitMs: 2e3, pollMs: 50 },
|
|
5034
|
+
async (acquired) => {
|
|
5035
|
+
if (!acquired) {
|
|
5036
|
+
throw new Error(`fact write skipped: fact-dedup.lock not acquired (${storageDir})`);
|
|
5037
|
+
}
|
|
5038
|
+
if (await recheck()) return { suppressed: true };
|
|
5039
|
+
return { suppressed: false, result: await write() };
|
|
5040
|
+
}
|
|
5041
|
+
)
|
|
5042
|
+
);
|
|
5043
|
+
}
|
|
5044
|
+
|
|
4898
5045
|
// src/orchestration/extraction-injection-gate.ts
|
|
4899
5046
|
function serializeInjectionScreenCandidate(candidate) {
|
|
4900
5047
|
const body = candidate.category === "procedure" ? buildProcedurePersistBody(candidate.content, candidate.procedureSteps) : candidate.content;
|
|
@@ -5571,7 +5718,7 @@ async function retireStaleMergedTargetPromotionCopies(args) {
|
|
|
5571
5718
|
}
|
|
5572
5719
|
|
|
5573
5720
|
// src/orchestration/semantic-merge-persist.ts
|
|
5574
|
-
import
|
|
5721
|
+
import path6 from "path";
|
|
5575
5722
|
|
|
5576
5723
|
// src/orchestration/semantic-merge-commit-effects.ts
|
|
5577
5724
|
import { readFile as readFile3 } from "fs/promises";
|
|
@@ -6291,11 +6438,11 @@ async function runMergedTargetPostEffects(deps, storage, merge, input) {
|
|
|
6291
6438
|
if (inferMemoryStatus(committed.frontmatter, committed.path) !== "active") return signals;
|
|
6292
6439
|
const entityRef = committed.frontmatter.entityRef;
|
|
6293
6440
|
const rawBody = rawPreCitationMergedBody(deps, merge.mergedContent);
|
|
6294
|
-
const memoryRelPath =
|
|
6441
|
+
const memoryRelPath = path6.relative(storage.dir, committed.path);
|
|
6295
6442
|
input.graphContext.memoryPathById.set(merge.targetId, memoryRelPath);
|
|
6296
6443
|
const all = input.graphContext.allMemsForGraph;
|
|
6297
6444
|
if (Array.isArray(all)) {
|
|
6298
|
-
const entry = all.find((m) =>
|
|
6445
|
+
const entry = all.find((m) => path6.relative(storage.dir, m.path) === memoryRelPath);
|
|
6299
6446
|
if (entry) entry.content = rawBody;
|
|
6300
6447
|
}
|
|
6301
6448
|
const rewriteTypes = [];
|
|
@@ -6339,7 +6486,7 @@ async function runMergedTargetPostEffects(deps, storage, merge, input) {
|
|
|
6339
6486
|
}
|
|
6340
6487
|
|
|
6341
6488
|
// src/orchestration/extraction-anchor-snapshot.ts
|
|
6342
|
-
import
|
|
6489
|
+
import path7 from "path";
|
|
6343
6490
|
var ExtractionAnchorSnapshot = class {
|
|
6344
6491
|
constructor(options = {}) {
|
|
6345
6492
|
this.options = options;
|
|
@@ -6377,7 +6524,7 @@ var ExtractionAnchorSnapshot = class {
|
|
|
6377
6524
|
if (!cached) return;
|
|
6378
6525
|
const snapshot = await cached;
|
|
6379
6526
|
const relativePath = resolvePersistedMemoryRelativePath({ memoryId, pathById, category });
|
|
6380
|
-
let memory = await storage.readMemoryByPath(
|
|
6527
|
+
let memory = await storage.readMemoryByPath(path7.join(storage.dir, relativePath));
|
|
6381
6528
|
if (!memory) memory = await storage.getMemoryByIdIncludingArchived(memoryId);
|
|
6382
6529
|
if (!memory) return;
|
|
6383
6530
|
const existingIndex = snapshot.findIndex((entry) => entry.frontmatter.id === memoryId);
|
|
@@ -6397,24 +6544,6 @@ var ExtractionAnchorSnapshot = class {
|
|
|
6397
6544
|
}
|
|
6398
6545
|
};
|
|
6399
6546
|
|
|
6400
|
-
// src/orchestration/extraction-persist-citation.ts
|
|
6401
|
-
function normalizeStoredHashSource(raw, citationEnabled, citationTemplate) {
|
|
6402
|
-
return ContentHashIndex.normalizeContent(
|
|
6403
|
-
sanitizeMemoryContent(
|
|
6404
|
-
citationEnabled && hasCitationForTemplate(raw, citationTemplate) ? stripCitationForTemplate(raw, citationTemplate) : raw
|
|
6405
|
-
).text
|
|
6406
|
-
);
|
|
6407
|
-
}
|
|
6408
|
-
function applyInlineCitation(content, citationEnabled, citationTemplate, citationContextBase) {
|
|
6409
|
-
if (!citationEnabled) return content;
|
|
6410
|
-
if (typeof content !== "string" || content.length === 0) return content;
|
|
6411
|
-
const citationContext = {
|
|
6412
|
-
...citationContextBase,
|
|
6413
|
-
ts: (/* @__PURE__ */ new Date()).toISOString()
|
|
6414
|
-
};
|
|
6415
|
-
return attachCitation(content, citationContext, citationTemplate);
|
|
6416
|
-
}
|
|
6417
|
-
|
|
6418
6547
|
// src/orchestration/extraction-persist.ts
|
|
6419
6548
|
var ExtractionPersistCoordinator = class {
|
|
6420
6549
|
constructor(deps) {
|
|
@@ -7322,81 +7451,83 @@ var ExtractionPersistCoordinator = class {
|
|
|
7322
7451
|
fact.tags
|
|
7323
7452
|
);
|
|
7324
7453
|
let exactDuplicate = false;
|
|
7325
|
-
let needsCorpusConfirm = false;
|
|
7326
7454
|
try {
|
|
7327
7455
|
exactDuplicate = await this.deps.hasContentHashDedup(targetStorage, contentHashDedupKey);
|
|
7328
|
-
if (factDedupEnabled && !exactDuplicate) {
|
|
7329
|
-
if (await targetStorage.isFactContentHashAuthoritative()) {
|
|
7330
|
-
exactDuplicate = await this.deps.hasContentHashDedup(targetStorage, contentHashDedupKey);
|
|
7331
|
-
} else {
|
|
7332
|
-
needsCorpusConfirm = true;
|
|
7333
|
-
}
|
|
7334
|
-
}
|
|
7335
7456
|
} catch (err) {
|
|
7336
|
-
|
|
7457
|
+
exactDuplicate = false;
|
|
7337
7458
|
log.warn(
|
|
7338
7459
|
`content-hash dedup lookup unavailable for storage ${targetStorage.dir}; confirming against corpus: ${err}`
|
|
7339
7460
|
);
|
|
7340
7461
|
}
|
|
7341
|
-
|
|
7342
|
-
|
|
7343
|
-
|
|
7344
|
-
|
|
7345
|
-
|
|
7346
|
-
|
|
7347
|
-
|
|
7348
|
-
|
|
7349
|
-
|
|
7350
|
-
|
|
7351
|
-
|
|
7352
|
-
|
|
7353
|
-
|
|
7354
|
-
exactDuplicate = hotMems.some(matchesActiveDuplicate) || coldMems.some(matchesActiveDuplicate);
|
|
7355
|
-
} catch (err) {
|
|
7356
|
-
log.warn(
|
|
7357
|
-
`connector-aware dedup scan failed for storage ${targetStorage.dir}; writing fail-open: ${err instanceof Error ? err.message : String(err)}`
|
|
7358
|
-
);
|
|
7359
|
-
exactDuplicate = false;
|
|
7360
|
-
}
|
|
7462
|
+
const raceDedupOpts = (key) => ({
|
|
7463
|
+
category: writeCategory,
|
|
7464
|
+
contentHashDedupKey: key,
|
|
7465
|
+
connector: sourceContext?.sourceConnector?.trim() || void 0,
|
|
7466
|
+
citationEnabled,
|
|
7467
|
+
citationTemplate
|
|
7468
|
+
});
|
|
7469
|
+
if (factDedupEnabled) {
|
|
7470
|
+
exactDuplicate = await confirmActiveFactDuplicate(
|
|
7471
|
+
{ hasContentHashDedup: (storage2, key) => this.deps.hasContentHashDedup(storage2, key) },
|
|
7472
|
+
targetStorage,
|
|
7473
|
+
raceDedupOpts(contentHashDedupKey)
|
|
7474
|
+
);
|
|
7361
7475
|
}
|
|
7362
|
-
|
|
7363
|
-
|
|
7364
|
-
|
|
7365
|
-
|
|
7366
|
-
|
|
7367
|
-
|
|
7368
|
-
|
|
7369
|
-
|
|
7370
|
-
|
|
7371
|
-
|
|
7372
|
-
|
|
7373
|
-
|
|
7374
|
-
|
|
7375
|
-
|
|
7376
|
-
|
|
7377
|
-
|
|
7378
|
-
|
|
7379
|
-
|
|
7380
|
-
|
|
7381
|
-
|
|
7382
|
-
|
|
7383
|
-
|
|
7384
|
-
|
|
7385
|
-
content: fact.content,
|
|
7386
|
-
category: writeCategory,
|
|
7387
|
-
confidence: fact.confidence,
|
|
7388
|
-
entityRef: fact.entityRef,
|
|
7389
|
-
structuredAttributes: fact.structuredAttributes,
|
|
7390
|
-
sourceConnector: sourceContext?.sourceConnector,
|
|
7391
|
-
bounds: {
|
|
7392
|
-
invalidAt: biTemporal.validUntil,
|
|
7393
|
-
validFrom: biTemporal.validFrom,
|
|
7394
|
-
observedAt: biTemporal.observedAt,
|
|
7395
|
-
eventTimeSource: biTemporal.eventTimeSource
|
|
7396
|
-
}
|
|
7397
|
-
});
|
|
7398
|
-
}
|
|
7476
|
+
const finalizeOnWindowFailure = async (err) => {
|
|
7477
|
+
await finalizeCommittedWrites(true).catch(
|
|
7478
|
+
(finalizeErr) => log.warn(`committed-write finalization after fact-dedup window failure failed: ${finalizeErr}`)
|
|
7479
|
+
);
|
|
7480
|
+
throw err;
|
|
7481
|
+
};
|
|
7482
|
+
const raceRecheck = (storage2, key) => () => {
|
|
7483
|
+
if (!factDedupEnabled || injectionScreenStatus === "pending_review") return Promise.resolve(false);
|
|
7484
|
+
return confirmActiveFactDuplicate(
|
|
7485
|
+
{ hasContentHashDedup: (s, k) => this.deps.hasContentHashDedup(s, k) },
|
|
7486
|
+
storage2,
|
|
7487
|
+
raceDedupOpts(key)
|
|
7488
|
+
);
|
|
7489
|
+
};
|
|
7490
|
+
const backfillDuplicateTemporalBounds = async () => {
|
|
7491
|
+
if (!(biTemporal && writeCategory === "fact" && (biTemporal.validUntil || biTemporal.validFrom))) return;
|
|
7492
|
+
const fr = faithfulnessResultsByFactIndex?.get(factLoopIndex);
|
|
7493
|
+
const faithfulnessWouldPending = faithfulnessMode === "enforce" && fr?.ok === true && (fr.verdict === "unsupported" || fr.verdict === "contradicted");
|
|
7494
|
+
const requireSpansWouldPending = this.deps.config.provenance?.requireSpans === true && fact.requireSpansPending === true;
|
|
7495
|
+
const judgeVerdict = judgeVerdictsByFactIndex?.get(factLoopIndex);
|
|
7496
|
+
const judgeWouldGate = !this.deps.config.extractionJudgeShadow && judgeVerdict !== void 0 && !judgeVerdict.durable;
|
|
7497
|
+
if (!isAboveImportanceThreshold(importance.level, this.deps.config.extractionMinImportanceLevel) || faithfulnessWouldPending || requireSpansWouldPending || judgeWouldGate) {
|
|
7498
|
+
return;
|
|
7399
7499
|
}
|
|
7500
|
+
await this.deps.backfillTemporalBoundsOnDedupHit(
|
|
7501
|
+
targetStorage,
|
|
7502
|
+
contentHashDedupKey,
|
|
7503
|
+
{
|
|
7504
|
+
invalidAt: biTemporal.validUntil,
|
|
7505
|
+
// #1707 thread 2 — carry the corrected start bound too.
|
|
7506
|
+
validFrom: biTemporal.validFrom,
|
|
7507
|
+
observedAt: biTemporal.observedAt,
|
|
7508
|
+
eventTimeSource: biTemporal.eventTimeSource
|
|
7509
|
+
},
|
|
7510
|
+
fact.entityRef,
|
|
7511
|
+
sourceContext?.sourceConnector
|
|
7512
|
+
);
|
|
7513
|
+
await backfillTemporalBoundsOnPromotionCopies({
|
|
7514
|
+
sourceStorage: targetStorage,
|
|
7515
|
+
content: fact.content,
|
|
7516
|
+
category: writeCategory,
|
|
7517
|
+
confidence: fact.confidence,
|
|
7518
|
+
entityRef: fact.entityRef,
|
|
7519
|
+
structuredAttributes: fact.structuredAttributes,
|
|
7520
|
+
sourceConnector: sourceContext?.sourceConnector,
|
|
7521
|
+
bounds: {
|
|
7522
|
+
invalidAt: biTemporal.validUntil,
|
|
7523
|
+
validFrom: biTemporal.validFrom,
|
|
7524
|
+
observedAt: biTemporal.observedAt,
|
|
7525
|
+
eventTimeSource: biTemporal.eventTimeSource
|
|
7526
|
+
}
|
|
7527
|
+
});
|
|
7528
|
+
};
|
|
7529
|
+
if (exactDuplicate && injectionScreenStatus !== "pending_review") {
|
|
7530
|
+
await backfillDuplicateTemporalBounds();
|
|
7400
7531
|
log.debug(
|
|
7401
7532
|
`dedup: skipping duplicate fact "${fact.content.slice(0, 60)}\u2026" in storage ${targetStorage.dir}`
|
|
7402
7533
|
);
|
|
@@ -7605,27 +7736,38 @@ var ExtractionPersistCoordinator = class {
|
|
|
7605
7736
|
},
|
|
7606
7737
|
{ source: extractionWriteSource }
|
|
7607
7738
|
);
|
|
7608
|
-
const
|
|
7609
|
-
|
|
7610
|
-
|
|
7611
|
-
|
|
7612
|
-
|
|
7613
|
-
|
|
7614
|
-
|
|
7615
|
-
|
|
7616
|
-
|
|
7617
|
-
|
|
7618
|
-
|
|
7619
|
-
|
|
7620
|
-
|
|
7621
|
-
|
|
7622
|
-
|
|
7623
|
-
|
|
7624
|
-
|
|
7625
|
-
|
|
7626
|
-
|
|
7627
|
-
|
|
7628
|
-
|
|
7739
|
+
const parentWriteOutcome = await persistUnderFactDedupWindow(
|
|
7740
|
+
targetStorage.dir,
|
|
7741
|
+
raceRecheck(targetStorage, contentHashDedupKey),
|
|
7742
|
+
async () => targetStorage.writeSealedMemory(parentWriteEnvelope, {
|
|
7743
|
+
importance,
|
|
7744
|
+
supersedes,
|
|
7745
|
+
links: links.length > 0 ? links : void 0,
|
|
7746
|
+
intentGoal: inferredIntent?.goal,
|
|
7747
|
+
intentActionType: inferredIntent?.actionType,
|
|
7748
|
+
intentEntityTypes: inferredIntent?.entityTypes,
|
|
7749
|
+
memoryKind: memoryKind2,
|
|
7750
|
+
...biTemporal ? { observedAt: biTemporal.observedAt, eventTimeSource: biTemporal.eventTimeSource, ...biTemporal.validUntil ? { invalidAt: biTemporal.validUntil } : {} } : {},
|
|
7751
|
+
contentHashSource: rawChunkedContent,
|
|
7752
|
+
// Faithfulness gate (issue #1576).
|
|
7753
|
+
...faithfulnessFm ? { faithfulness: faithfulnessFm } : {},
|
|
7754
|
+
...faithfulnessEnforceStatus ? { status: faithfulnessEnforceStatus } : {},
|
|
7755
|
+
// Claim-level provenance spans (issue #1575 PR 2).
|
|
7756
|
+
...fact.sources && fact.sources.length > 0 ? { sources: fact.sources } : {},
|
|
7757
|
+
...fact.provenance ? { provenance: fact.provenance } : {},
|
|
7758
|
+
// PR #2016: never defer here — fallible chunk/artifact writes follow this
|
|
7759
|
+
// durable parent .md; flush the hash now so a throw can't strand it (dup).
|
|
7760
|
+
deferHashIndexSave: false,
|
|
7761
|
+
...factToolScoped ? { toolScoped: true } : {}
|
|
7762
|
+
})
|
|
7763
|
+
).catch(finalizeOnWindowFailure);
|
|
7764
|
+
if (parentWriteOutcome.suppressed) {
|
|
7765
|
+
await backfillDuplicateTemporalBounds();
|
|
7766
|
+
log.info(`dedup: raced duplicate suppressed in fact-dedup window (chunked parent) for storage ${targetStorage.dir}`);
|
|
7767
|
+
dedupedCount++;
|
|
7768
|
+
continue;
|
|
7769
|
+
}
|
|
7770
|
+
const parentWrite = parentWriteOutcome.result;
|
|
7629
7771
|
const parentId = parentWrite.id;
|
|
7630
7772
|
const tombstoneBlocked2 = parentWrite.tombstoneBlocked;
|
|
7631
7773
|
const postWriteGuard2 = faithfulnessEnforceStatus === "pending_review" || tombstoneBlocked2;
|
|
@@ -7914,29 +8056,51 @@ var ExtractionPersistCoordinator = class {
|
|
|
7914
8056
|
},
|
|
7915
8057
|
{ source: extractionWriteSource }
|
|
7916
8058
|
);
|
|
7917
|
-
const
|
|
7918
|
-
|
|
7919
|
-
|
|
7920
|
-
|
|
7921
|
-
|
|
7922
|
-
|
|
7923
|
-
|
|
7924
|
-
|
|
7925
|
-
|
|
7926
|
-
|
|
7927
|
-
|
|
7928
|
-
|
|
7929
|
-
|
|
7930
|
-
|
|
7931
|
-
|
|
7932
|
-
|
|
7933
|
-
|
|
7934
|
-
|
|
7935
|
-
|
|
7936
|
-
|
|
7937
|
-
|
|
7938
|
-
|
|
7939
|
-
|
|
8059
|
+
const factWriteOutcome = await persistUnderFactDedupWindow(
|
|
8060
|
+
targetStorage.dir,
|
|
8061
|
+
raceRecheck(targetStorage, contentHashDedupKey),
|
|
8062
|
+
async () => {
|
|
8063
|
+
const factWrite2 = await targetStorage.writeSealedMemory(factWriteEnvelope, {
|
|
8064
|
+
importance,
|
|
8065
|
+
supersedes,
|
|
8066
|
+
links: links.length > 0 ? links : void 0,
|
|
8067
|
+
intentGoal: inferredIntent?.goal,
|
|
8068
|
+
intentActionType: inferredIntent?.actionType,
|
|
8069
|
+
intentEntityTypes: inferredIntent?.entityTypes,
|
|
8070
|
+
memoryKind,
|
|
8071
|
+
...biTemporal ? { observedAt: biTemporal.observedAt, eventTimeSource: biTemporal.eventTimeSource, ...biTemporal.validUntil ? { invalidAt: biTemporal.validUntil } : {} } : {},
|
|
8072
|
+
contentHashSource: writeCategory === "fact" ? fact.content : void 0,
|
|
8073
|
+
// Faithfulness gate (issue #1576).
|
|
8074
|
+
...faithfulnessFm ? { faithfulness: faithfulnessFm } : {},
|
|
8075
|
+
...faithfulnessEnforceStatus ? { status: faithfulnessEnforceStatus } : {},
|
|
8076
|
+
// Claim-level provenance spans (issue #1575 PR 2). Carry verified
|
|
8077
|
+
// sources + the coarse strength tag from the extraction validator
|
|
8078
|
+
// through to frontmatter so they survive end-to-end.
|
|
8079
|
+
...fact.sources && fact.sources.length > 0 ? { sources: fact.sources } : {},
|
|
8080
|
+
...fact.provenance ? { provenance: fact.provenance } : {},
|
|
8081
|
+
// PR #2016: never defer inside the commit window (chunked-path
|
|
8082
|
+
// rule): a peer loading an authoritative index after the release
|
|
8083
|
+
// must see this hash, or its recheck misses and duplicates it.
|
|
8084
|
+
deferHashIndexSave: false,
|
|
8085
|
+
...factToolScoped ? { toolScoped: true } : {}
|
|
8086
|
+
});
|
|
8087
|
+
if (!factWrite2.tombstoneBlocked) {
|
|
8088
|
+
try {
|
|
8089
|
+
await this.deps.addContentHashDedup(targetStorage, contentHashDedupKey);
|
|
8090
|
+
} catch (err) {
|
|
8091
|
+
log.warn(`content-hash dedup registration failed for memory ${factWrite2.id}: ${err}`);
|
|
8092
|
+
}
|
|
8093
|
+
}
|
|
8094
|
+
return factWrite2;
|
|
8095
|
+
}
|
|
8096
|
+
).catch(finalizeOnWindowFailure);
|
|
8097
|
+
if (factWriteOutcome.suppressed) {
|
|
8098
|
+
await backfillDuplicateTemporalBounds();
|
|
8099
|
+
log.info(`dedup: raced duplicate suppressed in fact-dedup window for storage ${targetStorage.dir}`);
|
|
8100
|
+
dedupedCount++;
|
|
8101
|
+
continue;
|
|
8102
|
+
}
|
|
8103
|
+
const factWrite = factWriteOutcome.result;
|
|
7940
8104
|
const memoryId = factWrite.id;
|
|
7941
8105
|
const tombstoneBlocked = factWrite.tombstoneBlocked;
|
|
7942
8106
|
const postWriteGuard = faithfulnessEnforceStatus === "pending_review" || tombstoneBlocked;
|
|
@@ -8085,17 +8249,6 @@ var ExtractionPersistCoordinator = class {
|
|
|
8085
8249
|
...factToolScoped ? { toolScoped: true } : {}
|
|
8086
8250
|
});
|
|
8087
8251
|
}
|
|
8088
|
-
try {
|
|
8089
|
-
const canonicalFactContent = citationEnabled && hasCitationForTemplate(fact.content, citationTemplate) ? stripCitationForTemplate(fact.content, citationTemplate) : fact.content;
|
|
8090
|
-
const hashRegisterKey = writeCategory === "procedure" ? buildProcedurePersistBody(fact.content, fact.procedureSteps) : canonicalFactContent;
|
|
8091
|
-
if (!tombstoneBlocked) {
|
|
8092
|
-
await this.deps.addContentHashDedup(targetStorage, hashRegisterKey);
|
|
8093
|
-
}
|
|
8094
|
-
} catch (err) {
|
|
8095
|
-
log.warn(
|
|
8096
|
-
`content-hash dedup registration failed for memory ${memoryId}: ${err}`
|
|
8097
|
-
);
|
|
8098
|
-
}
|
|
8099
8252
|
} catch (err) {
|
|
8100
8253
|
await finalizeCommittedWrites(true).catch(
|
|
8101
8254
|
(finalizeErr) => log.warn(`committed-write finalization after post-write failure failed: ${finalizeErr}`)
|
|
@@ -8251,7 +8404,7 @@ async function drainExtractionAndShutdownDependencyPropagation(extractionQueue,
|
|
|
8251
8404
|
// src/orchestration/dependency-propagation-delivery.ts
|
|
8252
8405
|
import { randomUUID } from "crypto";
|
|
8253
8406
|
import { readFile as readFile4, unlink } from "fs/promises";
|
|
8254
|
-
import
|
|
8407
|
+
import path8 from "path";
|
|
8255
8408
|
|
|
8256
8409
|
// src/orchestration/dependency-propagation-recovery-replay.ts
|
|
8257
8410
|
import { createHash as createHash4 } from "crypto";
|
|
@@ -8934,13 +9087,13 @@ var DependencyPropagationDelivery = class {
|
|
|
8934
9087
|
try {
|
|
8935
9088
|
const job = validateJob(JSON.parse(await this.readQueueFile(filePath)), status);
|
|
8936
9089
|
if (!job) {
|
|
8937
|
-
log.warn(`dependency propagation ignored invalid job file ${
|
|
9090
|
+
log.warn(`dependency propagation ignored invalid job file ${path8.basename(filePath)}`);
|
|
8938
9091
|
continue;
|
|
8939
9092
|
}
|
|
8940
9093
|
entries.push({ job, filePath });
|
|
8941
9094
|
} catch (error) {
|
|
8942
9095
|
if (error instanceof SyntaxError || isNotFound(error)) {
|
|
8943
|
-
log.warn(`dependency propagation ignored unreadable job file ${
|
|
9096
|
+
log.warn(`dependency propagation ignored unreadable job file ${path8.basename(filePath)}: ${error}`);
|
|
8944
9097
|
continue;
|
|
8945
9098
|
}
|
|
8946
9099
|
throw error;
|
|
@@ -9011,7 +9164,7 @@ var DependencyPropagationDelivery = class {
|
|
|
9011
9164
|
await this.writeQueueJob(targetPath, next);
|
|
9012
9165
|
const terminal = status === "completed" || status === "dead_letter" || status === "canceled";
|
|
9013
9166
|
for (const entry of entries) {
|
|
9014
|
-
if (
|
|
9167
|
+
if (path8.resolve(entry.filePath) === path8.resolve(targetPath)) continue;
|
|
9015
9168
|
await unlink(entry.filePath).catch((error) => {
|
|
9016
9169
|
if (isNotFound(error)) return;
|
|
9017
9170
|
if (terminal) {
|
|
@@ -9075,7 +9228,7 @@ var DependencyPropagationDelivery = class {
|
|
|
9075
9228
|
allowMissingDirectory: true
|
|
9076
9229
|
});
|
|
9077
9230
|
for (const filePath of files) {
|
|
9078
|
-
if (
|
|
9231
|
+
if (path8.basename(filePath, ".json") !== jobId) continue;
|
|
9079
9232
|
try {
|
|
9080
9233
|
await unlink(filePath);
|
|
9081
9234
|
} catch (error) {
|
|
@@ -9276,11 +9429,11 @@ function createDependencyPropagationReplayReconciliation(host) {
|
|
|
9276
9429
|
// src/orchestration/recall-internal.ts
|
|
9277
9430
|
import { createHash as createHash6 } from "crypto";
|
|
9278
9431
|
import { readFile as readFile5, stat, unlink as unlink2 } from "fs/promises";
|
|
9279
|
-
import
|
|
9432
|
+
import path13 from "path";
|
|
9280
9433
|
|
|
9281
9434
|
// src/orchestration/graph-path-state-loader.ts
|
|
9282
9435
|
import { lstat, opendir, realpath } from "fs/promises";
|
|
9283
|
-
import
|
|
9436
|
+
import path9 from "path";
|
|
9284
9437
|
function isArchivePathIndexUnavailable(index) {
|
|
9285
9438
|
return "unavailable" in index;
|
|
9286
9439
|
}
|
|
@@ -9299,11 +9452,11 @@ var GraphPathStateLoader = class {
|
|
|
9299
9452
|
openArchiveDirectory = opendir;
|
|
9300
9453
|
async readNode(storage, nodeId, deadlineAtMs, allowArchiveLookup) {
|
|
9301
9454
|
if (typeof deadlineAtMs === "number" && Date.now() >= deadlineAtMs) return null;
|
|
9302
|
-
const configuredStorageRoot =
|
|
9455
|
+
const configuredStorageRoot = path9.resolve(storage.dir);
|
|
9303
9456
|
const storageRoot = await realpath(configuredStorageRoot).catch(() => null);
|
|
9304
9457
|
if (!storageRoot || storageRoot !== configuredStorageRoot) return null;
|
|
9305
|
-
const logicalId =
|
|
9306
|
-
const directRelativePaths = [nodeId,
|
|
9458
|
+
const logicalId = path9.basename(nodeId, path9.extname(nodeId));
|
|
9459
|
+
const directRelativePaths = [nodeId, path9.join("cold", nodeId)];
|
|
9307
9460
|
let inactiveDirectMemory = null;
|
|
9308
9461
|
for (const relativePath of directRelativePaths) {
|
|
9309
9462
|
const safePath = await this.resolveContainedPath(storageRoot, relativePath);
|
|
@@ -9326,7 +9479,7 @@ var GraphPathStateLoader = class {
|
|
|
9326
9479
|
if (!archiveIndex || isArchivePathIndexUnavailable(archiveIndex) || typeof deadlineAtMs === "number" && Date.now() >= deadlineAtMs) {
|
|
9327
9480
|
return null;
|
|
9328
9481
|
}
|
|
9329
|
-
const archivePaths = archiveIndex.pathsByBasename.get(
|
|
9482
|
+
const archivePaths = archiveIndex.pathsByBasename.get(path9.basename(nodeId)) ?? [];
|
|
9330
9483
|
for (const archivePath of archivePaths) {
|
|
9331
9484
|
if (typeof deadlineAtMs === "number" && Date.now() >= deadlineAtMs) return null;
|
|
9332
9485
|
const memory = await storage.readMemoryByPath(archivePath);
|
|
@@ -9336,17 +9489,17 @@ var GraphPathStateLoader = class {
|
|
|
9336
9489
|
return null;
|
|
9337
9490
|
}
|
|
9338
9491
|
async resolveContainedPath(storageRoot, relativePath) {
|
|
9339
|
-
if (
|
|
9492
|
+
if (path9.isAbsolute(relativePath)) return null;
|
|
9340
9493
|
const rawSegments = relativePath.replace(/\\/g, "/").split("/");
|
|
9341
9494
|
if (rawSegments.includes("..")) return null;
|
|
9342
|
-
const candidate =
|
|
9343
|
-
const lexicalRelative =
|
|
9344
|
-
if (lexicalRelative.length > 0 && (lexicalRelative.startsWith("..") ||
|
|
9495
|
+
const candidate = path9.resolve(storageRoot, relativePath);
|
|
9496
|
+
const lexicalRelative = path9.relative(storageRoot, candidate);
|
|
9497
|
+
if (lexicalRelative.length > 0 && (lexicalRelative.startsWith("..") || path9.isAbsolute(lexicalRelative))) {
|
|
9345
9498
|
return null;
|
|
9346
9499
|
}
|
|
9347
9500
|
const canonical = await realpath(candidate).catch(() => candidate);
|
|
9348
|
-
const canonicalRelative =
|
|
9349
|
-
if (canonicalRelative.length > 0 && (canonicalRelative.startsWith("..") ||
|
|
9501
|
+
const canonicalRelative = path9.relative(storageRoot, canonical);
|
|
9502
|
+
if (canonicalRelative.length > 0 && (canonicalRelative.startsWith("..") || path9.isAbsolute(canonicalRelative))) {
|
|
9350
9503
|
return null;
|
|
9351
9504
|
}
|
|
9352
9505
|
return canonical;
|
|
@@ -9419,7 +9572,7 @@ var GraphPathStateLoader = class {
|
|
|
9419
9572
|
}
|
|
9420
9573
|
async buildArchivePathIndex(storageRoot, version) {
|
|
9421
9574
|
const pathsByBasename = /* @__PURE__ */ new Map();
|
|
9422
|
-
const archiveRoot =
|
|
9575
|
+
const archiveRoot = path9.join(storageRoot, "archive");
|
|
9423
9576
|
let archiveRootStatus;
|
|
9424
9577
|
try {
|
|
9425
9578
|
archiveRootStatus = await this.archiveLstat(archiveRoot);
|
|
@@ -9437,8 +9590,8 @@ var GraphPathStateLoader = class {
|
|
|
9437
9590
|
if (isArchiveScanAbsenceError(error)) return { version, pathsByBasename };
|
|
9438
9591
|
return null;
|
|
9439
9592
|
}
|
|
9440
|
-
const archiveRelative =
|
|
9441
|
-
if (archiveRelative.length > 0 && (archiveRelative.startsWith("..") ||
|
|
9593
|
+
const archiveRelative = path9.relative(storageRoot, canonicalArchiveRoot);
|
|
9594
|
+
if (archiveRelative.length > 0 && (archiveRelative.startsWith("..") || path9.isAbsolute(archiveRelative))) {
|
|
9442
9595
|
return { version, pathsByBasename };
|
|
9443
9596
|
}
|
|
9444
9597
|
const pending = [canonicalArchiveRoot];
|
|
@@ -9464,8 +9617,8 @@ var GraphPathStateLoader = class {
|
|
|
9464
9617
|
if (isArchiveScanAbsenceError(error)) continue;
|
|
9465
9618
|
return null;
|
|
9466
9619
|
}
|
|
9467
|
-
const currentRelative =
|
|
9468
|
-
if (currentRelative.length > 0 && (currentRelative.startsWith("..") ||
|
|
9620
|
+
const currentRelative = path9.relative(storageRoot, canonicalCurrent);
|
|
9621
|
+
if (currentRelative.length > 0 && (currentRelative.startsWith("..") || path9.isAbsolute(currentRelative))) {
|
|
9469
9622
|
continue;
|
|
9470
9623
|
}
|
|
9471
9624
|
let directory;
|
|
@@ -9482,7 +9635,7 @@ var GraphPathStateLoader = class {
|
|
|
9482
9635
|
return { version, unavailable: "oversized" };
|
|
9483
9636
|
}
|
|
9484
9637
|
if (entry.isSymbolicLink()) continue;
|
|
9485
|
-
const entryPath =
|
|
9638
|
+
const entryPath = path9.join(canonicalCurrent, entry.name);
|
|
9486
9639
|
if (entry.isDirectory()) {
|
|
9487
9640
|
pending.push(entryPath);
|
|
9488
9641
|
continue;
|
|
@@ -9498,8 +9651,8 @@ var GraphPathStateLoader = class {
|
|
|
9498
9651
|
if (isArchiveScanAbsenceError(error)) continue;
|
|
9499
9652
|
return null;
|
|
9500
9653
|
}
|
|
9501
|
-
const relative =
|
|
9502
|
-
if (relative.length > 0 && (relative.startsWith("..") ||
|
|
9654
|
+
const relative = path9.relative(storageRoot, canonical);
|
|
9655
|
+
if (relative.length > 0 && (relative.startsWith("..") || path9.isAbsolute(relative))) {
|
|
9503
9656
|
continue;
|
|
9504
9657
|
}
|
|
9505
9658
|
const paths = pathsByBasename.get(entry.name);
|
|
@@ -9525,7 +9678,7 @@ var GraphPathStateLoader = class {
|
|
|
9525
9678
|
// src/orchestration/graph-recall-coordinator.ts
|
|
9526
9679
|
import { createHash as createHash5 } from "crypto";
|
|
9527
9680
|
import { mkdir as mkdir3, writeFile as writeFile3 } from "fs/promises";
|
|
9528
|
-
import
|
|
9681
|
+
import path10 from "path";
|
|
9529
9682
|
function mergeGraphExpandedResults(primary, expanded) {
|
|
9530
9683
|
const mergedByNamespaceAndPath = /* @__PURE__ */ new Map();
|
|
9531
9684
|
for (const item of [...primary, ...expanded]) {
|
|
@@ -9542,11 +9695,11 @@ function mergeGraphExpandedResults(primary, expanded) {
|
|
|
9542
9695
|
return Array.from(mergedByNamespaceAndPath.values());
|
|
9543
9696
|
}
|
|
9544
9697
|
function graphPathRelativeToStorage(storageDir, candidatePath) {
|
|
9545
|
-
const absolutePath =
|
|
9546
|
-
const rel =
|
|
9698
|
+
const absolutePath = path10.isAbsolute(candidatePath) ? candidatePath : path10.resolve(storageDir, candidatePath);
|
|
9699
|
+
const rel = path10.relative(storageDir, absolutePath);
|
|
9547
9700
|
if (!rel || rel === ".") return null;
|
|
9548
9701
|
if (rel.startsWith("..")) return null;
|
|
9549
|
-
return rel.split(
|
|
9702
|
+
return rel.split(path10.sep).join("/");
|
|
9550
9703
|
}
|
|
9551
9704
|
function normalizeGraphActivationScore(score) {
|
|
9552
9705
|
const bounded = Number.isFinite(score) && score > 0 ? score : 0;
|
|
@@ -9646,7 +9799,7 @@ var GraphRecallCoordinator = class {
|
|
|
9646
9799
|
resolvedPath = resolvedCold.result.path;
|
|
9647
9800
|
resolvedResult = resolvedCold.result;
|
|
9648
9801
|
}
|
|
9649
|
-
if (!
|
|
9802
|
+
if (!path10.isAbsolute(resolvedPath)) {
|
|
9650
9803
|
resolvedAmbiguousSeeds.set(result.path, null);
|
|
9651
9804
|
return null;
|
|
9652
9805
|
}
|
|
@@ -9671,7 +9824,7 @@ var GraphRecallCoordinator = class {
|
|
|
9671
9824
|
}
|
|
9672
9825
|
continue;
|
|
9673
9826
|
}
|
|
9674
|
-
if (
|
|
9827
|
+
if (path10.isAbsolute(result.path)) {
|
|
9675
9828
|
const resolved = await resolveAmbiguousSeedOwner(result, null);
|
|
9676
9829
|
if (resolved) {
|
|
9677
9830
|
addResultForNamespace(resolved.namespace, resolved.result);
|
|
@@ -9717,7 +9870,7 @@ var GraphRecallCoordinator = class {
|
|
|
9717
9870
|
0
|
|
9718
9871
|
);
|
|
9719
9872
|
seedPaths.push(
|
|
9720
|
-
...seedRelativePaths.map((rel) =>
|
|
9873
|
+
...seedRelativePaths.map((rel) => path10.join(storage.dir, rel))
|
|
9721
9874
|
);
|
|
9722
9875
|
const seedSet = new Set(seedRelativePaths);
|
|
9723
9876
|
const nodeMemoryCache = /* @__PURE__ */ new Map();
|
|
@@ -9772,7 +9925,7 @@ var GraphRecallCoordinator = class {
|
|
|
9772
9925
|
path: memory.path,
|
|
9773
9926
|
score,
|
|
9774
9927
|
namespace,
|
|
9775
|
-
seed:
|
|
9928
|
+
seed: path10.resolve(storage.dir, candidate.seed),
|
|
9776
9929
|
hopDepth: candidate.hopDepth,
|
|
9777
9930
|
decayedWeight: candidate.decayedWeight,
|
|
9778
9931
|
graphType: candidate.graphType,
|
|
@@ -9804,7 +9957,7 @@ var GraphRecallCoordinator = class {
|
|
|
9804
9957
|
add(memory.frontmatter.id);
|
|
9805
9958
|
if (relativePath) {
|
|
9806
9959
|
add(relativePath);
|
|
9807
|
-
if (relativePath.endsWith(".md")) add(
|
|
9960
|
+
if (relativePath.endsWith(".md")) add(path10.basename(relativePath, ".md"));
|
|
9808
9961
|
}
|
|
9809
9962
|
return state;
|
|
9810
9963
|
};
|
|
@@ -9851,7 +10004,7 @@ var GraphRecallCoordinator = class {
|
|
|
9851
10004
|
path: memory.path,
|
|
9852
10005
|
score,
|
|
9853
10006
|
namespace,
|
|
9854
|
-
seed:
|
|
10007
|
+
seed: path10.resolve(storage.dir, candidate.seed),
|
|
9855
10008
|
hopDepth: candidate.hopDepth,
|
|
9856
10009
|
decayedWeight: candidate.decayedWeight,
|
|
9857
10010
|
graphType: candidate.graphType,
|
|
@@ -9894,12 +10047,12 @@ var GraphRecallCoordinator = class {
|
|
|
9894
10047
|
}
|
|
9895
10048
|
async recordLastGraphRecallSnapshot(options) {
|
|
9896
10049
|
try {
|
|
9897
|
-
const snapshotPath =
|
|
10050
|
+
const snapshotPath = path10.join(
|
|
9898
10051
|
options.storage.dir,
|
|
9899
10052
|
"state",
|
|
9900
10053
|
"last_graph_recall.json"
|
|
9901
10054
|
);
|
|
9902
|
-
await mkdir3(
|
|
10055
|
+
await mkdir3(path10.dirname(snapshotPath), { recursive: true });
|
|
9903
10056
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
9904
10057
|
const totalSeedCount = options.seedPaths.length;
|
|
9905
10058
|
const totalExpandedCount = options.expandedPaths.length;
|
|
@@ -10199,11 +10352,11 @@ async function appendEpisodicContextSection(deps, options) {
|
|
|
10199
10352
|
}
|
|
10200
10353
|
|
|
10201
10354
|
// src/orchestration/recall-profile-storage.ts
|
|
10202
|
-
import
|
|
10355
|
+
import path11 from "path";
|
|
10203
10356
|
function resolveCompositeProfileStorage(options) {
|
|
10204
10357
|
const { profileStorages, memoryDir } = options;
|
|
10205
10358
|
const emptyProfileStorage = new Proxy(
|
|
10206
|
-
{ dir:
|
|
10359
|
+
{ dir: path11.join(memoryDir, ".empty-scope-profile") },
|
|
10207
10360
|
{
|
|
10208
10361
|
get(target, prop) {
|
|
10209
10362
|
if (prop in target) return Reflect.get(target, prop);
|
|
@@ -10351,7 +10504,7 @@ function resolveCompositeProfileStorage(options) {
|
|
|
10351
10504
|
}
|
|
10352
10505
|
|
|
10353
10506
|
// src/orchestration/recall-recognition-search.ts
|
|
10354
|
-
import
|
|
10507
|
+
import path12 from "path";
|
|
10355
10508
|
async function fetchQmdMemoryResultsWithRecognitionSwap(deps, prompt, qmdFetchLimit, qmdHybridFetchLimit, options) {
|
|
10356
10509
|
if (deps.config.recallRecognitionTier !== true || options.collection || options.namespacesEnabled !== true) {
|
|
10357
10510
|
return deps.fetchQmdMemoryResultsWithArtifactTopUp(
|
|
@@ -10438,7 +10591,7 @@ async function hitsFromIds(namespace, storage, index, ids) {
|
|
|
10438
10591
|
for (const [offset, id] of ids.entries()) {
|
|
10439
10592
|
const absPath = pathsById.get(id)?.[0];
|
|
10440
10593
|
if (!absPath) continue;
|
|
10441
|
-
const rel =
|
|
10594
|
+
const rel = path12.relative(storage.dir, absPath).split(path12.sep).join("/");
|
|
10442
10595
|
if (!rel || rel.startsWith("..")) continue;
|
|
10443
10596
|
hits.push({
|
|
10444
10597
|
docid: `${namespace}:${rel}`,
|
|
@@ -10686,7 +10839,7 @@ var RecallInternalCoordinator = class {
|
|
|
10686
10839
|
const graphExpandedResultPaths = /* @__PURE__ */ new Set();
|
|
10687
10840
|
const graphSourceLabelsForPath = (resultPath) => {
|
|
10688
10841
|
const labels = [];
|
|
10689
|
-
const normalizedPath = resultPath.split(
|
|
10842
|
+
const normalizedPath = resultPath.split(path13.sep).join("/");
|
|
10690
10843
|
const isEntityPath = normalizedPath.startsWith("entities/") || normalizedPath.includes("/entities/");
|
|
10691
10844
|
if (graphBaselinePaths.has(resultPath)) labels.push("baseline");
|
|
10692
10845
|
if (graphExpandedResultPaths.has(resultPath))
|
|
@@ -12223,11 +12376,11 @@ ${formatted}`;
|
|
|
12223
12376
|
if (!resolveRecallAuxiliaryCapabilities(this.deps.config).compactionReset) return null;
|
|
12224
12377
|
const workspaceDir = compactionWorkspaceDir || this.deps.config.workspaceDir || defaultWorkspaceDir();
|
|
12225
12378
|
const safeSessionKey = sanitizeSessionKeyForFilename(effectiveSessionKey);
|
|
12226
|
-
const signalPath =
|
|
12379
|
+
const signalPath = path13.join(
|
|
12227
12380
|
workspaceDir,
|
|
12228
12381
|
`.compaction-reset-signal-${safeSessionKey}`
|
|
12229
12382
|
);
|
|
12230
|
-
const bootPath =
|
|
12383
|
+
const bootPath = path13.join(workspaceDir, "BOOT.md");
|
|
12231
12384
|
try {
|
|
12232
12385
|
const signalStat = await stat(signalPath).catch(() => null);
|
|
12233
12386
|
if (!signalStat) return null;
|
|
@@ -14507,10 +14660,10 @@ ${tmtNode.summary}`
|
|
|
14507
14660
|
|
|
14508
14661
|
// src/orchestration/recall-search-pipeline.ts
|
|
14509
14662
|
import { createHash as createHash7 } from "crypto";
|
|
14510
|
-
import
|
|
14663
|
+
import path15 from "path";
|
|
14511
14664
|
|
|
14512
14665
|
// src/orchestration/recall-search-prefilter.ts
|
|
14513
|
-
import
|
|
14666
|
+
import path14 from "path";
|
|
14514
14667
|
async function fetchActiveArtifactsForNamespace(deps, namespace, prompt, targetCount, options = {}) {
|
|
14515
14668
|
const storage = await deps.storageRouter.storageFor(namespace);
|
|
14516
14669
|
let fetchLimit = computeArtifactCandidateFetchLimit(targetCount);
|
|
@@ -14639,7 +14792,7 @@ async function searchEmbeddingFallback(deps, query, limit) {
|
|
|
14639
14792
|
if (hits.length === 0) return [];
|
|
14640
14793
|
const results = [];
|
|
14641
14794
|
for (const hit of hits) {
|
|
14642
|
-
const fullPath =
|
|
14795
|
+
const fullPath = path14.isAbsolute(hit.path) ? hit.path : path14.join(deps.config.memoryDir, hit.path);
|
|
14643
14796
|
const memory = await deps.storage.readMemoryByPath(fullPath);
|
|
14644
14797
|
if (!memory) continue;
|
|
14645
14798
|
results.push({
|
|
@@ -15017,7 +15170,7 @@ var RecallSearchPipelineCoordinator = class {
|
|
|
15017
15170
|
const storage = await this.deps.storageRouter.storageFor(namespace);
|
|
15018
15171
|
const storageDir = typeof storage.dir === "string" && storage.dir ? storage.dir : null;
|
|
15019
15172
|
if (!storageDir) continue;
|
|
15020
|
-
const recallRoot =
|
|
15173
|
+
const recallRoot = path15.resolve(storageDir);
|
|
15021
15174
|
if (seenRecallRoots.has(recallRoot)) continue;
|
|
15022
15175
|
seenRecallRoots.add(recallRoot);
|
|
15023
15176
|
recallRoots.push(recallRoot);
|
|
@@ -15041,8 +15194,8 @@ var RecallSearchPipelineCoordinator = class {
|
|
|
15041
15194
|
if (resolvedCold) scopedResults.push(resolvedCold.result);
|
|
15042
15195
|
continue;
|
|
15043
15196
|
}
|
|
15044
|
-
if (
|
|
15045
|
-
if (recallRoots.some((recallRoot) => isPathInsideStorageRoot(recallRoot,
|
|
15197
|
+
if (path15.isAbsolute(result.path)) {
|
|
15198
|
+
if (recallRoots.some((recallRoot) => isPathInsideStorageRoot(recallRoot, path15.resolve(result.path)))) {
|
|
15046
15199
|
scopedResults.push(result);
|
|
15047
15200
|
}
|
|
15048
15201
|
continue;
|
|
@@ -15763,8 +15916,10 @@ var ExtractionDrain = class {
|
|
|
15763
15916
|
* persist step ends the host's preemption registration, so the drain registers
|
|
15764
15917
|
* it again before every later chunk; a fail-closed flush can then abort the
|
|
15765
15918
|
* next chunk's model request instead of waiting behind the whole window.
|
|
15919
|
+
* `preemptHandle`: the queue task's own preemption slot (per task, so two
|
|
15920
|
+
* concurrent automatic extractions cannot clobber each other's registration).
|
|
15766
15921
|
*/
|
|
15767
|
-
async run(turns, runOptions, preemptable = false) {
|
|
15922
|
+
async run(turns, runOptions, preemptable = false, preemptHandle) {
|
|
15768
15923
|
const budgetChars = this.deps.extractionWindowBudgetChars?.() ?? Number.POSITIVE_INFINITY;
|
|
15769
15924
|
const chunkable = runOptions.clearBufferAfterExtraction && !runOptions.forceExtractionAttempt && !runOptions.failOnExtractionFailure && !turns.some((turn) => turn.acceptedCapture === true) && Number.isFinite(budgetChars) && budgetChars > 0;
|
|
15770
15925
|
const chunks = chunkable ? chunkExtractionWindow(turns, budgetChars) : [];
|
|
@@ -15789,7 +15944,7 @@ var ExtractionDrain = class {
|
|
|
15789
15944
|
if (preemptable && position > 0) {
|
|
15790
15945
|
const local = new AbortController();
|
|
15791
15946
|
preempt = local;
|
|
15792
|
-
|
|
15947
|
+
preemptHandle?.arm(() => local.abort(preemptedExtractionError()));
|
|
15793
15948
|
chunkOptions = {
|
|
15794
15949
|
...chunkOptions,
|
|
15795
15950
|
abortSignal: runOptions.abortSignal ? AbortSignal.any([runOptions.abortSignal, local.signal]) : local.signal
|
|
@@ -15851,8 +16006,8 @@ var ExtractionDrain = class {
|
|
|
15851
16006
|
const reason = `dropped after ${dropAfter} repeated extraction failures (last result: status=${result.status} reason=${result.reason ?? "n/a"})`;
|
|
15852
16007
|
try {
|
|
15853
16008
|
const storage = await this.deps.getStorage();
|
|
15854
|
-
const
|
|
15855
|
-
log.warn(`buffer[${bufferKey}]: dropping ${chunk.length} turns \u2014 ${reason}; copy saved to ${
|
|
16009
|
+
const path42 = await storage.saveDroppedExtractionChunk(bufferKey, reason, chunk);
|
|
16010
|
+
log.warn(`buffer[${bufferKey}]: dropping ${chunk.length} turns \u2014 ${reason}; copy saved to ${path42}`);
|
|
15856
16011
|
} catch (err) {
|
|
15857
16012
|
log.warn(
|
|
15858
16013
|
`buffer[${bufferKey}]: could not save the dropped-chunk recovery copy; keeping the chunk in the buffer: ${describeError(err)}`
|
|
@@ -16420,8 +16575,8 @@ var TurnIngestionCoordinator = class {
|
|
|
16420
16575
|
}
|
|
16421
16576
|
if (settled) return;
|
|
16422
16577
|
const preemptable = options.preemptable === true && options.preemptRunning !== true;
|
|
16423
|
-
const accepted = this.deps.extractionQueueCoordinator.enqueue(async () => {
|
|
16424
|
-
await this.deps.extractionQueueCoordinator.runPreemptable(preemptable, options.abortSignal, async (abortSignal) => {
|
|
16578
|
+
const accepted = this.deps.extractionQueueCoordinator.enqueue(async (preemptHandle) => {
|
|
16579
|
+
await this.deps.extractionQueueCoordinator.runPreemptable(preemptHandle, preemptable, options.abortSignal, async (abortSignal) => {
|
|
16425
16580
|
if (settled) return;
|
|
16426
16581
|
if (typeof extractionDeadlineMs === "number" && extractionDeadlineMs <= Date.now()) {
|
|
16427
16582
|
settleTask(new ExtractionDeadlineError("queue_wait"));
|
|
@@ -16527,14 +16682,14 @@ var TurnIngestionCoordinator = class {
|
|
|
16527
16682
|
deadlineMs: extractionDeadlineMs,
|
|
16528
16683
|
bufferKey,
|
|
16529
16684
|
onDurableCommit: options.onDurableCommit,
|
|
16530
|
-
onBeforePersist: () =>
|
|
16685
|
+
onBeforePersist: () => preemptHandle?.disarm(),
|
|
16531
16686
|
abortSignal,
|
|
16532
16687
|
failOnExtractionFailure: options.failOnExtractionFailure === true,
|
|
16533
16688
|
writeNamespaceOverride: options.writeNamespaceOverride,
|
|
16534
16689
|
principalOverride: options.principalOverride,
|
|
16535
16690
|
scopeProfileWritePlan: effectiveScopePlan,
|
|
16536
16691
|
forceExtractionAttempt: options.forceExtractionAttempt === true
|
|
16537
|
-
}, preemptable);
|
|
16692
|
+
}, preemptable, preemptHandle);
|
|
16538
16693
|
settleTask(void 0, result);
|
|
16539
16694
|
} catch (err) {
|
|
16540
16695
|
const reason2 = abortSignal.reason;
|
|
@@ -16544,7 +16699,7 @@ var TurnIngestionCoordinator = class {
|
|
|
16544
16699
|
}
|
|
16545
16700
|
}
|
|
16546
16701
|
});
|
|
16547
|
-
}, { front: options.preemptRunning === true });
|
|
16702
|
+
}, { front: options.preemptRunning === true, key: bufferKey });
|
|
16548
16703
|
if (!accepted) {
|
|
16549
16704
|
settleTask(new Error("extraction queue is stopped"));
|
|
16550
16705
|
return;
|
|
@@ -16623,7 +16778,7 @@ var TurnIngestionCoordinator = class {
|
|
|
16623
16778
|
|
|
16624
16779
|
// src/orchestration/recall-introspection.ts
|
|
16625
16780
|
import { mkdir as mkdir5, readFile as readFile7, writeFile as writeFile5 } from "fs/promises";
|
|
16626
|
-
import
|
|
16781
|
+
import path17 from "path";
|
|
16627
16782
|
|
|
16628
16783
|
// src/taxonomy/default-taxonomy.ts
|
|
16629
16784
|
var DEFAULT_TAXONOMY = {
|
|
@@ -16746,7 +16901,7 @@ function generateResolverDocument(taxonomy) {
|
|
|
16746
16901
|
|
|
16747
16902
|
// src/taxonomy/taxonomy-loader.ts
|
|
16748
16903
|
import { readFile as readFile6, mkdir as mkdir4, writeFile as writeFile4 } from "fs/promises";
|
|
16749
|
-
import
|
|
16904
|
+
import path16 from "path";
|
|
16750
16905
|
var TAXONOMY_DIR = ".taxonomy";
|
|
16751
16906
|
var TAXONOMY_FILE = "taxonomy.json";
|
|
16752
16907
|
var MAX_SLUG_LENGTH = 32;
|
|
@@ -16844,7 +16999,7 @@ function validateTaxonomy(taxonomy) {
|
|
|
16844
16999
|
}
|
|
16845
17000
|
}
|
|
16846
17001
|
async function loadTaxonomy(memoryDir) {
|
|
16847
|
-
const taxonomyPath =
|
|
17002
|
+
const taxonomyPath = path16.join(memoryDir, TAXONOMY_DIR, TAXONOMY_FILE);
|
|
16848
17003
|
let raw;
|
|
16849
17004
|
try {
|
|
16850
17005
|
raw = await readFile6(taxonomyPath, "utf-8");
|
|
@@ -16894,16 +17049,16 @@ async function loadTaxonomy(memoryDir) {
|
|
|
16894
17049
|
}
|
|
16895
17050
|
async function saveTaxonomy(memoryDir, taxonomy) {
|
|
16896
17051
|
validateTaxonomy(taxonomy);
|
|
16897
|
-
const dir =
|
|
17052
|
+
const dir = path16.join(memoryDir, TAXONOMY_DIR);
|
|
16898
17053
|
await mkdir4(dir, { recursive: true });
|
|
16899
|
-
const filePath =
|
|
17054
|
+
const filePath = path16.join(dir, TAXONOMY_FILE);
|
|
16900
17055
|
await writeFile4(filePath, JSON.stringify(taxonomy, null, 2) + "\n", "utf-8");
|
|
16901
17056
|
}
|
|
16902
17057
|
function getTaxonomyDir(memoryDir) {
|
|
16903
|
-
return
|
|
17058
|
+
return path16.join(memoryDir, TAXONOMY_DIR);
|
|
16904
17059
|
}
|
|
16905
17060
|
function getTaxonomyFilePath(memoryDir) {
|
|
16906
|
-
return
|
|
17061
|
+
return path16.join(memoryDir, TAXONOMY_DIR, TAXONOMY_FILE);
|
|
16907
17062
|
}
|
|
16908
17063
|
|
|
16909
17064
|
// src/orchestration/recall-introspection.ts
|
|
@@ -16927,7 +17082,7 @@ var RecallIntrospectionCoordinator = class {
|
|
|
16927
17082
|
}
|
|
16928
17083
|
async getLastGraphRecallSnapshot(namespace) {
|
|
16929
17084
|
const storage = await this.deps.getStorage(namespace);
|
|
16930
|
-
const snapshotPath =
|
|
17085
|
+
const snapshotPath = path17.join(
|
|
16931
17086
|
storage.dir,
|
|
16932
17087
|
"state",
|
|
16933
17088
|
"last_graph_recall.json"
|
|
@@ -16966,7 +17121,7 @@ var RecallIntrospectionCoordinator = class {
|
|
|
16966
17121
|
}
|
|
16967
17122
|
async getLastIntentSnapshot(namespace) {
|
|
16968
17123
|
const storage = await this.deps.getStorage(namespace);
|
|
16969
|
-
const snapshotPath =
|
|
17124
|
+
const snapshotPath = path17.join(storage.dir, "state", "last_intent.json");
|
|
16970
17125
|
try {
|
|
16971
17126
|
const raw = await readFile7(snapshotPath, "utf-8");
|
|
16972
17127
|
const parsed = JSON.parse(raw);
|
|
@@ -16999,7 +17154,7 @@ var RecallIntrospectionCoordinator = class {
|
|
|
16999
17154
|
}
|
|
17000
17155
|
async getLastQmdRecallSnapshot(namespace) {
|
|
17001
17156
|
const storage = await this.deps.getStorage(namespace);
|
|
17002
|
-
const snapshotPath =
|
|
17157
|
+
const snapshotPath = path17.join(
|
|
17003
17158
|
storage.dir,
|
|
17004
17159
|
"state",
|
|
17005
17160
|
"last_qmd_recall.json"
|
|
@@ -17291,12 +17446,12 @@ var RecallIntrospectionCoordinator = class {
|
|
|
17291
17446
|
}
|
|
17292
17447
|
async recordLastIntentSnapshot(options) {
|
|
17293
17448
|
try {
|
|
17294
|
-
const snapshotPath =
|
|
17449
|
+
const snapshotPath = path17.join(
|
|
17295
17450
|
options.storage.dir,
|
|
17296
17451
|
"state",
|
|
17297
17452
|
"last_intent.json"
|
|
17298
17453
|
);
|
|
17299
|
-
await mkdir5(
|
|
17454
|
+
await mkdir5(path17.dirname(snapshotPath), { recursive: true });
|
|
17300
17455
|
await writeFile5(
|
|
17301
17456
|
snapshotPath,
|
|
17302
17457
|
JSON.stringify(options.snapshot, null, 2),
|
|
@@ -17308,12 +17463,12 @@ var RecallIntrospectionCoordinator = class {
|
|
|
17308
17463
|
}
|
|
17309
17464
|
async recordLastQmdRecallSnapshot(options) {
|
|
17310
17465
|
try {
|
|
17311
|
-
const snapshotPath =
|
|
17466
|
+
const snapshotPath = path17.join(
|
|
17312
17467
|
options.storage.dir,
|
|
17313
17468
|
"state",
|
|
17314
17469
|
"last_qmd_recall.json"
|
|
17315
17470
|
);
|
|
17316
|
-
await mkdir5(
|
|
17471
|
+
await mkdir5(path17.dirname(snapshotPath), { recursive: true });
|
|
17317
17472
|
await writeFile5(
|
|
17318
17473
|
snapshotPath,
|
|
17319
17474
|
JSON.stringify(options.snapshot, null, 2),
|
|
@@ -17328,8 +17483,8 @@ var RecallIntrospectionCoordinator = class {
|
|
|
17328
17483
|
const stateDir = await this.deps.resolveStateDirForNamespace(
|
|
17329
17484
|
options.namespace
|
|
17330
17485
|
);
|
|
17331
|
-
const snapshotPath =
|
|
17332
|
-
await mkdir5(
|
|
17486
|
+
const snapshotPath = path17.join(stateDir, "last_intent.json");
|
|
17487
|
+
await mkdir5(path17.dirname(snapshotPath), { recursive: true });
|
|
17333
17488
|
await writeFile5(
|
|
17334
17489
|
snapshotPath,
|
|
17335
17490
|
JSON.stringify(options.snapshot, null, 2),
|
|
@@ -17343,7 +17498,7 @@ var RecallIntrospectionCoordinator = class {
|
|
|
17343
17498
|
|
|
17344
17499
|
// src/orchestration/orchestrator-init.ts
|
|
17345
17500
|
import { readdir as readdir2, stat as stat2, unlink as unlink3 } from "fs/promises";
|
|
17346
|
-
import
|
|
17501
|
+
import path18 from "path";
|
|
17347
17502
|
|
|
17348
17503
|
// src/orchestration/startup-collection-checks.ts
|
|
17349
17504
|
async function startupDiscoveryWithTimeout(discover, configuredFallback, timeoutMs = qmdStartupCollectionCheckTimeoutMs()) {
|
|
@@ -17679,7 +17834,7 @@ var OrchestratorInitCoordinator = class {
|
|
|
17679
17834
|
const files = await readdir2(wsDir).catch(() => []);
|
|
17680
17835
|
for (const f of files) {
|
|
17681
17836
|
if (!f.startsWith(".compaction-reset-signal-")) continue;
|
|
17682
|
-
const fp =
|
|
17837
|
+
const fp = path18.join(wsDir, f);
|
|
17683
17838
|
const s = await stat2(fp).catch(() => null);
|
|
17684
17839
|
if (s && Date.now() - s.mtimeMs >= COMPACTION_SIGNAL_MAX_AGE_MS) {
|
|
17685
17840
|
await unlink3(fp).catch(() => {
|
|
@@ -18099,11 +18254,11 @@ var OrchestratorInitCoordinator = class {
|
|
|
18099
18254
|
};
|
|
18100
18255
|
|
|
18101
18256
|
// src/orchestration/persistence-index.ts
|
|
18102
|
-
import
|
|
18257
|
+
import path20 from "path";
|
|
18103
18258
|
|
|
18104
18259
|
// src/orchestration/recall-recognition-index.ts
|
|
18105
18260
|
import { promises as fsp } from "fs";
|
|
18106
|
-
import
|
|
18261
|
+
import path19 from "path";
|
|
18107
18262
|
import { setTimeout as delay } from "timers/promises";
|
|
18108
18263
|
var writeChains = /* @__PURE__ */ new Map();
|
|
18109
18264
|
var LOCK_POLL_MS = 10;
|
|
@@ -18154,7 +18309,7 @@ async function withRecognitionIndexLock(memoryDir, op) {
|
|
|
18154
18309
|
} catch (error) {
|
|
18155
18310
|
const code = error?.code;
|
|
18156
18311
|
if (code === "ENOENT") {
|
|
18157
|
-
await fsp.mkdir(
|
|
18312
|
+
await fsp.mkdir(path19.dirname(lockDir), { recursive: true }).catch(() => void 0);
|
|
18158
18313
|
continue;
|
|
18159
18314
|
}
|
|
18160
18315
|
if (code !== "EEXIST") throw error;
|
|
@@ -18405,7 +18560,7 @@ var PersistenceIndexCoordinator = class {
|
|
|
18405
18560
|
const allMems = allMemsForGraph ?? [];
|
|
18406
18561
|
for (const m of allMems) {
|
|
18407
18562
|
if (m.frontmatter.entityRef === entityRef) {
|
|
18408
|
-
const rel =
|
|
18563
|
+
const rel = path20.relative(storage.dir, m.path);
|
|
18409
18564
|
if (rel !== memoryRelPath) entitySiblings.push(rel);
|
|
18410
18565
|
}
|
|
18411
18566
|
}
|
|
@@ -18601,7 +18756,7 @@ var PersistenceIndexCoordinator = class {
|
|
|
18601
18756
|
|
|
18602
18757
|
// src/orchestration/workspace-ops.ts
|
|
18603
18758
|
import { lstat as lstat2, mkdir as mkdir6, readFile as readFile8, readdir as readdir3, realpath as realpath2, writeFile as writeFile6 } from "fs/promises";
|
|
18604
|
-
import
|
|
18759
|
+
import path21 from "path";
|
|
18605
18760
|
|
|
18606
18761
|
// src/maintenance/pattern-reinforcement.ts
|
|
18607
18762
|
function patternReinforcementKey(content) {
|
|
@@ -20505,8 +20660,8 @@ var MeetingsService = class {
|
|
|
20505
20660
|
// src/orchestration/workspace-ops.ts
|
|
20506
20661
|
var MEETINGS_BUILD_DEBOUNCE_MS = 5e3;
|
|
20507
20662
|
function matchesMemoryPath(candidatePath, requestedPath, memoryDir) {
|
|
20508
|
-
const normalizedCandidate =
|
|
20509
|
-
return normalizedCandidate ===
|
|
20663
|
+
const normalizedCandidate = path21.resolve(candidatePath);
|
|
20664
|
+
return normalizedCandidate === path21.resolve(requestedPath) || normalizedCandidate === path21.resolve(memoryDir, requestedPath);
|
|
20510
20665
|
}
|
|
20511
20666
|
function accessTrackingPathCandidates(storageDir, memoryPath) {
|
|
20512
20667
|
const candidates = qmdResultPathCandidates(storageDir, memoryPath);
|
|
@@ -20514,12 +20669,12 @@ function accessTrackingPathCandidates(storageDir, memoryPath) {
|
|
|
20514
20669
|
if (!parts) return candidates;
|
|
20515
20670
|
candidates.push(
|
|
20516
20671
|
...qmdResultPathCandidates(storageDir, parts.relativePath),
|
|
20517
|
-
...qmdResultPathCandidates(
|
|
20672
|
+
...qmdResultPathCandidates(path21.join(storageDir, "cold"), parts.relativePath)
|
|
20518
20673
|
);
|
|
20519
20674
|
return [...new Set(candidates)];
|
|
20520
20675
|
}
|
|
20521
20676
|
function canonicalMemoryPath(memoryPath, memoryDir) {
|
|
20522
|
-
return
|
|
20677
|
+
return path21.resolve(path21.isAbsolute(memoryPath) ? memoryPath : path21.resolve(memoryDir, memoryPath));
|
|
20523
20678
|
}
|
|
20524
20679
|
var WorkspaceOpsCoordinator = class {
|
|
20525
20680
|
constructor(deps) {
|
|
@@ -20601,15 +20756,15 @@ var WorkspaceOpsCoordinator = class {
|
|
|
20601
20756
|
this.deps.lastFileHygieneRunAtMs = now;
|
|
20602
20757
|
if (hygiene.rotateEnabled) {
|
|
20603
20758
|
for (const rel of hygiene.rotatePaths) {
|
|
20604
|
-
const abs =
|
|
20759
|
+
const abs = path21.isAbsolute(rel) ? rel : path21.join(this.deps.config.workspaceDir, rel);
|
|
20605
20760
|
try {
|
|
20606
20761
|
const raw = await readFile8(abs, "utf-8");
|
|
20607
20762
|
if (raw.length > hygiene.rotateMaxBytes) {
|
|
20608
|
-
const archiveDir =
|
|
20763
|
+
const archiveDir = path21.join(
|
|
20609
20764
|
this.deps.config.workspaceDir,
|
|
20610
20765
|
hygiene.archiveDir
|
|
20611
20766
|
);
|
|
20612
|
-
const base =
|
|
20767
|
+
const base = path21.basename(abs);
|
|
20613
20768
|
const prefix = base.toUpperCase().replace(/\.MD$/i, "").replace(/[^A-Z0-9]+/g, "-") || "FILE";
|
|
20614
20769
|
const { newContent } = await rotateMarkdownFileToArchive({
|
|
20615
20770
|
filePath: abs,
|
|
@@ -20634,8 +20789,8 @@ var WorkspaceOpsCoordinator = class {
|
|
|
20634
20789
|
log.warn(w.message);
|
|
20635
20790
|
}
|
|
20636
20791
|
if (hygiene.warningsLogEnabled && warnings.length > 0) {
|
|
20637
|
-
const fp =
|
|
20638
|
-
await mkdir6(
|
|
20792
|
+
const fp = path21.join(this.deps.config.memoryDir, hygiene.warningsLogPath);
|
|
20793
|
+
await mkdir6(path21.dirname(fp), { recursive: true });
|
|
20639
20794
|
const stamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
20640
20795
|
const block = `
|
|
20641
20796
|
|
|
@@ -20675,7 +20830,7 @@ var WorkspaceOpsCoordinator = class {
|
|
|
20675
20830
|
for (const categoryDir of RECALL_FALLBACK_DIRS) {
|
|
20676
20831
|
if (memoryRootReal === null) break;
|
|
20677
20832
|
for (const date of datesToScan) {
|
|
20678
|
-
const dateDir =
|
|
20833
|
+
const dateDir = path21.join(storage.dir, categoryDir, date);
|
|
20679
20834
|
try {
|
|
20680
20835
|
const dirStat = await lstat2(dateDir);
|
|
20681
20836
|
if (dirStat.isSymbolicLink() || !dirStat.isDirectory()) continue;
|
|
@@ -20684,7 +20839,7 @@ var WorkspaceOpsCoordinator = class {
|
|
|
20684
20839
|
for (const entry of entries) {
|
|
20685
20840
|
if (entry.isSymbolicLink()) continue;
|
|
20686
20841
|
if (!entry.name.endsWith(".md")) continue;
|
|
20687
|
-
const fullPath =
|
|
20842
|
+
const fullPath = path21.join(dateDir, entry.name);
|
|
20688
20843
|
try {
|
|
20689
20844
|
assertPathInsideRoot(memoryRootReal, await realpath2(fullPath), fullPath);
|
|
20690
20845
|
const memory = await storage.readMemoryByPath(fullPath);
|
|
@@ -20706,13 +20861,13 @@ var WorkspaceOpsCoordinator = class {
|
|
|
20706
20861
|
return a.frontmatter.created < b.frontmatter.created ? -1 : 1;
|
|
20707
20862
|
});
|
|
20708
20863
|
const hourlySummaries = [];
|
|
20709
|
-
const hourlyBaseDir =
|
|
20864
|
+
const hourlyBaseDir = path21.join(storage.dir, "summaries", "hourly");
|
|
20710
20865
|
try {
|
|
20711
20866
|
const sessionKeys = await readdir3(hourlyBaseDir, { withFileTypes: true });
|
|
20712
20867
|
for (const sk of sessionKeys) {
|
|
20713
20868
|
if (!sk.isDirectory()) continue;
|
|
20714
20869
|
for (const date of datesToScan) {
|
|
20715
|
-
const summaryFile =
|
|
20870
|
+
const summaryFile = path21.join(hourlyBaseDir, sk.name, `${date}.md`);
|
|
20716
20871
|
try {
|
|
20717
20872
|
const raw = await readFile8(summaryFile, "utf-8");
|
|
20718
20873
|
const filtered = filterHourlySummaryMarkdownForLocalDay(
|
|
@@ -21189,18 +21344,18 @@ ${reflectionsContent.trim()}
|
|
|
21189
21344
|
// src/orchestration/namespace-read-fanout.ts
|
|
21190
21345
|
import { existsSync, readFileSync } from "fs";
|
|
21191
21346
|
import { stat as stat3 } from "fs/promises";
|
|
21192
|
-
import
|
|
21347
|
+
import path23 from "path";
|
|
21193
21348
|
|
|
21194
21349
|
// src/orchestration/orchestrator-namespace-scope.ts
|
|
21195
|
-
import
|
|
21350
|
+
import path22 from "path";
|
|
21196
21351
|
function computeSemanticDedupScope(targetStorage, config) {
|
|
21197
21352
|
if (!resolveNamespaceCapabilities(config).namespaces) return {};
|
|
21198
|
-
const memoryDir =
|
|
21199
|
-
const storageDir =
|
|
21353
|
+
const memoryDir = path22.resolve(config.memoryDir);
|
|
21354
|
+
const storageDir = path22.resolve(targetStorage.dir);
|
|
21200
21355
|
if (storageDir === memoryDir) {
|
|
21201
21356
|
return { pathExcludePrefixes: ["namespaces/"] };
|
|
21202
21357
|
}
|
|
21203
|
-
let rel =
|
|
21358
|
+
let rel = path22.relative(memoryDir, storageDir);
|
|
21204
21359
|
if (!rel || rel.startsWith("..")) {
|
|
21205
21360
|
log.debug(
|
|
21206
21361
|
`semantic dedup: target storage dir ${storageDir} is outside memoryDir ${memoryDir}; scoping lookup to absolute path prefix`
|
|
@@ -21253,7 +21408,7 @@ var NamespaceReadFanoutCoordinator = class {
|
|
|
21253
21408
|
loadNamespaceStorageDirHintsFromCatalog() {
|
|
21254
21409
|
if (this.deps.namespaceStorageDirHintsLoaded || !this.deps.namespaceCatalog.enabled) return;
|
|
21255
21410
|
this.deps.namespaceStorageDirHintsLoaded = true;
|
|
21256
|
-
const catalogPath =
|
|
21411
|
+
const catalogPath = path23.join(this.deps.config.memoryDir, "state", "namespaces.jsonl");
|
|
21257
21412
|
if (!existsSync(catalogPath)) return;
|
|
21258
21413
|
let body;
|
|
21259
21414
|
try {
|
|
@@ -21290,7 +21445,7 @@ var NamespaceReadFanoutCoordinator = class {
|
|
|
21290
21445
|
if (!this.deps.storageDirMatchesNamespaceHint(record.namespace, record.storageDir)) {
|
|
21291
21446
|
continue;
|
|
21292
21447
|
}
|
|
21293
|
-
const resolvedStorageDir =
|
|
21448
|
+
const resolvedStorageDir = path23.resolve(record.storageDir);
|
|
21294
21449
|
const current = preferredByStorageDir.get(resolvedStorageDir);
|
|
21295
21450
|
preferredByStorageDir.set(
|
|
21296
21451
|
resolvedStorageDir,
|
|
@@ -21475,12 +21630,12 @@ var NamespaceReadFanoutCoordinator = class {
|
|
|
21475
21630
|
}
|
|
21476
21631
|
async resolveStateDirForNamespace(namespace) {
|
|
21477
21632
|
if (!resolveNamespaceCapabilities(this.deps.config).namespaces) {
|
|
21478
|
-
return
|
|
21633
|
+
return path23.join(this.deps.config.memoryDir, "state");
|
|
21479
21634
|
}
|
|
21480
21635
|
if (namespace !== this.deps.config.defaultNamespace) {
|
|
21481
|
-
return
|
|
21636
|
+
return path23.join(this.deps.config.memoryDir, "namespaces", namespace, "state");
|
|
21482
21637
|
}
|
|
21483
|
-
const candidate =
|
|
21638
|
+
const candidate = path23.join(
|
|
21484
21639
|
this.deps.config.memoryDir,
|
|
21485
21640
|
"namespaces",
|
|
21486
21641
|
this.deps.config.defaultNamespace
|
|
@@ -21488,11 +21643,11 @@ var NamespaceReadFanoutCoordinator = class {
|
|
|
21488
21643
|
try {
|
|
21489
21644
|
const candidateStat = await stat3(candidate);
|
|
21490
21645
|
if (candidateStat.isDirectory()) {
|
|
21491
|
-
return
|
|
21646
|
+
return path23.join(candidate, "state");
|
|
21492
21647
|
}
|
|
21493
21648
|
} catch {
|
|
21494
21649
|
}
|
|
21495
|
-
return
|
|
21650
|
+
return path23.join(this.deps.config.memoryDir, "state");
|
|
21496
21651
|
}
|
|
21497
21652
|
namespaceFromPath(p) {
|
|
21498
21653
|
if (!resolveNamespaceCapabilities(this.deps.config).namespaces) return this.deps.config.defaultNamespace;
|
|
@@ -21972,7 +22127,7 @@ var Orchestrator = class {
|
|
|
21972
22127
|
if (this.destroyed) throw new Error("orchestrator has been destroyed");
|
|
21973
22128
|
if (!this._dependencyPropagationDelivery) {
|
|
21974
22129
|
this._dependencyPropagationDelivery = new DependencyPropagationDelivery({
|
|
21975
|
-
queueRoot:
|
|
22130
|
+
queueRoot: path24.join(this.config.memoryDir, "state", "dependency-propagation"),
|
|
21976
22131
|
config: this.config,
|
|
21977
22132
|
extraction: this.extraction,
|
|
21978
22133
|
getStorage: (namespace) => this.getStorage(namespace),
|
|
@@ -22323,7 +22478,7 @@ var Orchestrator = class {
|
|
|
22323
22478
|
const defaultNs = normalizeNamespaceIdentity(this.config.defaultNamespace);
|
|
22324
22479
|
if (ns !== defaultNs && !isSafeRouteNamespace(ns)) return;
|
|
22325
22480
|
if (!this.storageDirMatchesNamespaceHint(ns, storageDir)) return;
|
|
22326
|
-
const resolvedStorageDir =
|
|
22481
|
+
const resolvedStorageDir = path24.resolve(storageDir);
|
|
22327
22482
|
let hints = this.namespaceStorageDirHints.get(resolvedStorageDir);
|
|
22328
22483
|
if (!hints) {
|
|
22329
22484
|
hints = /* @__PURE__ */ new Set();
|
|
@@ -22334,21 +22489,21 @@ var Orchestrator = class {
|
|
|
22334
22489
|
storageDirMatchesNamespaceHint(namespace, storageDir) {
|
|
22335
22490
|
const ns = normalizeNamespaceIdentity(namespace);
|
|
22336
22491
|
if (!ns) return false;
|
|
22337
|
-
const resolvedStorageDir =
|
|
22338
|
-
const resolvedMemoryDir =
|
|
22492
|
+
const resolvedStorageDir = path24.resolve(storageDir);
|
|
22493
|
+
const resolvedMemoryDir = path24.resolve(this.config.memoryDir);
|
|
22339
22494
|
const defaultNs = normalizeNamespaceIdentity(this.config.defaultNamespace);
|
|
22340
22495
|
if (resolvedStorageDir === resolvedMemoryDir) return ns === defaultNs;
|
|
22341
|
-
const resolvedNamespacesDir =
|
|
22496
|
+
const resolvedNamespacesDir = path24.join(resolvedMemoryDir, "namespaces");
|
|
22342
22497
|
if (!isPathInsideStorageRoot(resolvedNamespacesDir, resolvedStorageDir)) return false;
|
|
22343
|
-
const rawRoot =
|
|
22344
|
-
const tokenRoot =
|
|
22498
|
+
const rawRoot = path24.resolve(resolvedNamespacesDir, ns);
|
|
22499
|
+
const tokenRoot = path24.resolve(resolvedNamespacesDir, namespaceIdentityToken(ns));
|
|
22345
22500
|
return resolvedStorageDir === rawRoot || resolvedStorageDir === tokenRoot;
|
|
22346
22501
|
}
|
|
22347
22502
|
namespaceStorageDirHintOwnershipRank(record, resolvedStorageDir, configured) {
|
|
22348
|
-
if (resolvedStorageDir ===
|
|
22503
|
+
if (resolvedStorageDir === path24.resolve(this.config.memoryDir)) {
|
|
22349
22504
|
return record.namespace === normalizeNamespaceIdentity(this.config.defaultNamespace) ? 0 : 3;
|
|
22350
22505
|
}
|
|
22351
|
-
const leaf =
|
|
22506
|
+
const leaf = path24.basename(resolvedStorageDir);
|
|
22352
22507
|
const tokenOwnsRoot = namespaceIdentityToken(record.namespace) === leaf;
|
|
22353
22508
|
if (tokenOwnsRoot && configured.has(record.namespace)) return 0;
|
|
22354
22509
|
if (record.namespace === leaf) return 1;
|
|
@@ -22489,7 +22644,7 @@ var Orchestrator = class {
|
|
|
22489
22644
|
StorageManager.setOkfConformanceDefault(config.memoryDir, config.okf?.conformanceEnabled);
|
|
22490
22645
|
this.profiler = new ProfilingCollector({
|
|
22491
22646
|
enabled: resolvePipelineProcessingCapabilities(this.config).profiling,
|
|
22492
|
-
storageDir: config.profilingStorageDir ||
|
|
22647
|
+
storageDir: config.profilingStorageDir || path24.join(config.memoryDir, "profiling"),
|
|
22493
22648
|
maxTraces: config.profilingMaxTraces
|
|
22494
22649
|
});
|
|
22495
22650
|
this.namespaceCatalog = new NamespaceCatalog(config);
|
|
@@ -22567,7 +22722,7 @@ var Orchestrator = class {
|
|
|
22567
22722
|
bindStorage(this.storage, this.config.defaultNamespace);
|
|
22568
22723
|
this.storageRouter.onStorageCreated = bindStorage;
|
|
22569
22724
|
this.storageRouter.forEachCachedStorage(bindStorage);
|
|
22570
|
-
this.extractionQueueCoordinator = new ExtractionQueueCoordinator();
|
|
22725
|
+
this.extractionQueueCoordinator = new ExtractionQueueCoordinator(config.extractionQueueConcurrency);
|
|
22571
22726
|
this.recallResultFormatter = new RecallResultFormatter(this.config);
|
|
22572
22727
|
const conversationIndexRuntime = createConversationIndexRuntime(config, {
|
|
22573
22728
|
getQmd: () => this.conversationQmd,
|
|
@@ -22580,7 +22735,7 @@ var Orchestrator = class {
|
|
|
22580
22735
|
this.compounding = resolveConsolidationCapabilities(config).compounding ? new CompoundingEngine(config, this.storage) : void 0;
|
|
22581
22736
|
this.buffer = new SmartBuffer(config, this.storage);
|
|
22582
22737
|
this.transcript = new TranscriptManager(config);
|
|
22583
|
-
this.conversationIndexDir =
|
|
22738
|
+
this.conversationIndexDir = path24.join(
|
|
22584
22739
|
config.memoryDir,
|
|
22585
22740
|
"conversation-index",
|
|
22586
22741
|
"chunks"
|
|
@@ -22731,7 +22886,7 @@ var Orchestrator = class {
|
|
|
22731
22886
|
getHandleHistory: () => this.handleHistory
|
|
22732
22887
|
});
|
|
22733
22888
|
this.threading = new ThreadingManager(
|
|
22734
|
-
|
|
22889
|
+
path24.join(config.memoryDir, "threads"),
|
|
22735
22890
|
config.threadingGapMinutes
|
|
22736
22891
|
);
|
|
22737
22892
|
const lifecycleCaps = resolveMemoryLifecycleCapabilities(config);
|
|
@@ -24845,9 +25000,9 @@ function readStructuralSymbol(entry) {
|
|
|
24845
25000
|
const rec = entry;
|
|
24846
25001
|
const symbol = typeof rec.symbol === "string" ? rec.symbol.trim() : "";
|
|
24847
25002
|
if (!symbol) return null;
|
|
24848
|
-
const
|
|
25003
|
+
const path42 = typeof rec.path === "string" && rec.path.length > 0 ? rec.path : void 0;
|
|
24849
25004
|
const kind = typeof rec.kind === "string" && rec.kind.length > 0 ? rec.kind : void 0;
|
|
24850
|
-
const item =
|
|
25005
|
+
const item = path42 !== void 0 && kind !== void 0 ? { symbol, path: path42, kind } : path42 !== void 0 ? { symbol, path: path42 } : kind !== void 0 ? { symbol, kind } : { symbol };
|
|
24851
25006
|
return item;
|
|
24852
25007
|
}
|
|
24853
25008
|
function classifySpawnError(err) {
|
|
@@ -24921,7 +25076,7 @@ var DEFAULT_GRACE_PERIOD_DAYS = 7;
|
|
|
24921
25076
|
|
|
24922
25077
|
// src/binary-lifecycle/backend.ts
|
|
24923
25078
|
import fsp2 from "fs/promises";
|
|
24924
|
-
import
|
|
25079
|
+
import path25 from "path";
|
|
24925
25080
|
var FilesystemBackend = class {
|
|
24926
25081
|
type = "filesystem";
|
|
24927
25082
|
basePath;
|
|
@@ -24929,19 +25084,19 @@ var FilesystemBackend = class {
|
|
|
24929
25084
|
if (!basePath || basePath.trim().length === 0) {
|
|
24930
25085
|
throw new Error("FilesystemBackend requires a non-empty basePath");
|
|
24931
25086
|
}
|
|
24932
|
-
this.basePath =
|
|
25087
|
+
this.basePath = path25.resolve(basePath);
|
|
24933
25088
|
}
|
|
24934
25089
|
resolveRemotePath(remotePath) {
|
|
24935
|
-
const resolved =
|
|
24936
|
-
const relative =
|
|
24937
|
-
if (relative === ".." || relative.startsWith(`..${
|
|
25090
|
+
const resolved = path25.isAbsolute(remotePath) ? path25.resolve(remotePath) : path25.resolve(this.basePath, remotePath);
|
|
25091
|
+
const relative = path25.relative(this.basePath, resolved);
|
|
25092
|
+
if (relative === ".." || relative.startsWith(`..${path25.sep}`) || path25.isAbsolute(relative)) {
|
|
24938
25093
|
throw new Error(`FilesystemBackend remotePath escapes basePath: ${JSON.stringify(remotePath)}`);
|
|
24939
25094
|
}
|
|
24940
25095
|
return resolved;
|
|
24941
25096
|
}
|
|
24942
25097
|
isInsideBase(candidate, realBase) {
|
|
24943
|
-
const relative =
|
|
24944
|
-
return relative === "" || relative !== ".." && !relative.startsWith(`..${
|
|
25098
|
+
const relative = path25.relative(realBase, candidate);
|
|
25099
|
+
return relative === "" || relative !== ".." && !relative.startsWith(`..${path25.sep}`) && !path25.isAbsolute(relative);
|
|
24945
25100
|
}
|
|
24946
25101
|
async realBasePathIfExists() {
|
|
24947
25102
|
try {
|
|
@@ -24970,13 +25125,13 @@ var FilesystemBackend = class {
|
|
|
24970
25125
|
}
|
|
24971
25126
|
async ensureSafeParentDirectory(dest) {
|
|
24972
25127
|
const realBase = await this.ensureBaseDirectory();
|
|
24973
|
-
const destDir =
|
|
24974
|
-
const relativeDir =
|
|
24975
|
-
const segments = relativeDir === "" ? [] : relativeDir.split(
|
|
25128
|
+
const destDir = path25.dirname(dest);
|
|
25129
|
+
const relativeDir = path25.relative(this.basePath, destDir);
|
|
25130
|
+
const segments = relativeDir === "" ? [] : relativeDir.split(path25.sep);
|
|
24976
25131
|
let current = this.basePath;
|
|
24977
25132
|
for (const segment of segments) {
|
|
24978
25133
|
if (segment === "." || segment === "") continue;
|
|
24979
|
-
current =
|
|
25134
|
+
current = path25.join(current, segment);
|
|
24980
25135
|
try {
|
|
24981
25136
|
const stat5 = await fsp2.lstat(current);
|
|
24982
25137
|
if (stat5.isSymbolicLink()) {
|
|
@@ -25004,13 +25159,13 @@ var FilesystemBackend = class {
|
|
|
25004
25159
|
if (realBase === null) {
|
|
25005
25160
|
return null;
|
|
25006
25161
|
}
|
|
25007
|
-
const destDir =
|
|
25008
|
-
const relativeDir =
|
|
25009
|
-
const segments = relativeDir === "" ? [] : relativeDir.split(
|
|
25162
|
+
const destDir = path25.dirname(dest);
|
|
25163
|
+
const relativeDir = path25.relative(this.basePath, destDir);
|
|
25164
|
+
const segments = relativeDir === "" ? [] : relativeDir.split(path25.sep);
|
|
25010
25165
|
let current = this.basePath;
|
|
25011
25166
|
for (const segment of segments) {
|
|
25012
25167
|
if (segment === "." || segment === "") continue;
|
|
25013
|
-
current =
|
|
25168
|
+
current = path25.join(current, segment);
|
|
25014
25169
|
let stat5;
|
|
25015
25170
|
try {
|
|
25016
25171
|
stat5 = await fsp2.lstat(current);
|
|
@@ -25058,7 +25213,7 @@ var FilesystemBackend = class {
|
|
|
25058
25213
|
return dest;
|
|
25059
25214
|
}
|
|
25060
25215
|
async upload(localPath, remotePath) {
|
|
25061
|
-
if (
|
|
25216
|
+
if (path25.isAbsolute(remotePath)) {
|
|
25062
25217
|
throw new Error(`FilesystemBackend upload remotePath must be relative: ${JSON.stringify(remotePath)}`);
|
|
25063
25218
|
}
|
|
25064
25219
|
const dest = this.resolveRemotePath(remotePath);
|
|
@@ -25131,7 +25286,7 @@ function createBackend(cfg) {
|
|
|
25131
25286
|
|
|
25132
25287
|
// src/binary-lifecycle/scanner.ts
|
|
25133
25288
|
import fsp3 from "fs/promises";
|
|
25134
|
-
import
|
|
25289
|
+
import path26 from "path";
|
|
25135
25290
|
import crypto from "crypto";
|
|
25136
25291
|
function matchesPatterns(filename, patterns) {
|
|
25137
25292
|
const lower = filename.toLowerCase();
|
|
@@ -25156,8 +25311,8 @@ async function scanForBinaries(memoryDir, config, manifest) {
|
|
|
25156
25311
|
return;
|
|
25157
25312
|
}
|
|
25158
25313
|
for (const entry of entries) {
|
|
25159
|
-
const fullPath =
|
|
25160
|
-
const relativePath =
|
|
25314
|
+
const fullPath = path26.join(dir, entry.name);
|
|
25315
|
+
const relativePath = path26.relative(memoryDir, fullPath).split(path26.sep).join("/");
|
|
25161
25316
|
if (entry.isDirectory()) {
|
|
25162
25317
|
if (entry.name === ".binary-lifecycle") continue;
|
|
25163
25318
|
await walk(fullPath);
|
|
@@ -25197,15 +25352,15 @@ async function hashFile(filePath) {
|
|
|
25197
25352
|
|
|
25198
25353
|
// src/binary-lifecycle/manifest.ts
|
|
25199
25354
|
import fsp4 from "fs/promises";
|
|
25200
|
-
import
|
|
25355
|
+
import path27 from "path";
|
|
25201
25356
|
import crypto2 from "crypto";
|
|
25202
25357
|
var MANIFEST_DIR = ".binary-lifecycle";
|
|
25203
25358
|
var MANIFEST_FILE = "manifest.json";
|
|
25204
25359
|
function manifestDir(memoryDir) {
|
|
25205
|
-
return
|
|
25360
|
+
return path27.join(memoryDir, MANIFEST_DIR);
|
|
25206
25361
|
}
|
|
25207
25362
|
function manifestPath(memoryDir) {
|
|
25208
|
-
return
|
|
25363
|
+
return path27.join(memoryDir, MANIFEST_DIR, MANIFEST_FILE);
|
|
25209
25364
|
}
|
|
25210
25365
|
async function readManifest(memoryDir) {
|
|
25211
25366
|
const filePath = manifestPath(memoryDir);
|
|
@@ -25257,13 +25412,13 @@ function emptyManifest() {
|
|
|
25257
25412
|
|
|
25258
25413
|
// src/binary-lifecycle/pipeline.ts
|
|
25259
25414
|
import fsp5 from "fs/promises";
|
|
25260
|
-
import
|
|
25415
|
+
import path28 from "path";
|
|
25261
25416
|
import crypto3 from "crypto";
|
|
25262
25417
|
var historicalIdCache = new HistoricalEntityCanonicalIdCache();
|
|
25263
25418
|
function isRecallCorpusMarkdown(mdPath, memoryDir) {
|
|
25264
|
-
const rel =
|
|
25265
|
-
if (rel.startsWith("..") ||
|
|
25266
|
-
const top = rel.split(
|
|
25419
|
+
const rel = path28.relative(memoryDir, mdPath);
|
|
25420
|
+
if (rel.startsWith("..") || path28.isAbsolute(rel)) return false;
|
|
25421
|
+
const top = rel.split(path28.sep)[0];
|
|
25267
25422
|
return RECALL_FALLBACK_DIRS.includes(top);
|
|
25268
25423
|
}
|
|
25269
25424
|
async function hashFile2(filePath) {
|
|
@@ -25287,13 +25442,13 @@ function escapeRegex(s) {
|
|
|
25287
25442
|
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
25288
25443
|
}
|
|
25289
25444
|
function resolveManifestAssetPath(memoryDir, originalPath) {
|
|
25290
|
-
if (originalPath.length === 0 || originalPath.includes("\0") || originalPath.includes("\\") ||
|
|
25445
|
+
if (originalPath.length === 0 || originalPath.includes("\0") || originalPath.includes("\\") || path28.isAbsolute(originalPath) || path28.win32.isAbsolute(originalPath)) {
|
|
25291
25446
|
return null;
|
|
25292
25447
|
}
|
|
25293
|
-
const memoryRoot =
|
|
25294
|
-
const fullPath =
|
|
25295
|
-
const relative =
|
|
25296
|
-
if (relative === "" || relative === ".." || relative.startsWith(`..${
|
|
25448
|
+
const memoryRoot = path28.resolve(memoryDir);
|
|
25449
|
+
const fullPath = path28.resolve(memoryRoot, originalPath);
|
|
25450
|
+
const relative = path28.relative(memoryRoot, fullPath);
|
|
25451
|
+
if (relative === "" || relative === ".." || relative.startsWith(`..${path28.sep}`) || path28.isAbsolute(relative)) {
|
|
25297
25452
|
return null;
|
|
25298
25453
|
}
|
|
25299
25454
|
return fullPath;
|
|
@@ -25304,7 +25459,7 @@ function validateBinaryLifecycleConfig(config) {
|
|
|
25304
25459
|
}
|
|
25305
25460
|
}
|
|
25306
25461
|
function remotePathForAsset(backend, relPath) {
|
|
25307
|
-
const normalized = relPath.split(
|
|
25462
|
+
const normalized = relPath.split(path28.sep).join("/");
|
|
25308
25463
|
if (backend.type === "filesystem") {
|
|
25309
25464
|
return `.binary-lifecycle/mirrors/${normalized}`;
|
|
25310
25465
|
}
|
|
@@ -25317,11 +25472,11 @@ async function stageMirror(memoryDir, newPaths, backend, assets, log2, dryRun) {
|
|
|
25317
25472
|
let mirrored = 0;
|
|
25318
25473
|
const errors = [];
|
|
25319
25474
|
for (const relPath of newPaths) {
|
|
25320
|
-
const fullPath =
|
|
25475
|
+
const fullPath = path28.join(memoryDir, relPath);
|
|
25321
25476
|
try {
|
|
25322
25477
|
const stat5 = await fsp5.stat(fullPath);
|
|
25323
25478
|
const contentHash = await hashFile2(fullPath);
|
|
25324
|
-
const ext =
|
|
25479
|
+
const ext = path28.extname(relPath);
|
|
25325
25480
|
const mimeType = guessMimeType(ext);
|
|
25326
25481
|
const remotePath = remotePathForAsset(backend, relPath);
|
|
25327
25482
|
let backendLocation = remotePath;
|
|
@@ -25472,7 +25627,7 @@ async function stageRedirect(memoryDir, assets, log2, dryRun, readMarkdownFile,
|
|
|
25472
25627
|
for (const update of updates) {
|
|
25473
25628
|
try {
|
|
25474
25629
|
await withRawEntityPageMutation(memoryDir, update.mdPath, async () => {
|
|
25475
|
-
const stateDir =
|
|
25630
|
+
const stateDir = path28.join(memoryDir, "state");
|
|
25476
25631
|
const kind = classifyEntityRefWritePath(memoryDir, update.mdPath);
|
|
25477
25632
|
if (kind === "memory") {
|
|
25478
25633
|
const idsAtWrite = historicalIdCache.get(stateDir);
|
|
@@ -25565,10 +25720,10 @@ async function countRemainingLocalReferences(memoryDir, asset, assetAbsolute, md
|
|
|
25565
25720
|
return { remaining, errors };
|
|
25566
25721
|
}
|
|
25567
25722
|
function markdownReferencePattern(asset, assetAbsolute, mdPath) {
|
|
25568
|
-
const mdDir =
|
|
25723
|
+
const mdDir = path28.dirname(mdPath);
|
|
25569
25724
|
const candidates = /* @__PURE__ */ new Set();
|
|
25570
25725
|
const addCandidate = (candidate) => {
|
|
25571
|
-
const normalized = candidate.split(
|
|
25726
|
+
const normalized = candidate.split(path28.sep).join("/");
|
|
25572
25727
|
if (normalized.length === 0) return;
|
|
25573
25728
|
candidates.add(normalized);
|
|
25574
25729
|
const isParentTraversal = normalized === ".." || normalized.startsWith("../");
|
|
@@ -25576,10 +25731,10 @@ function markdownReferencePattern(asset, assetAbsolute, mdPath) {
|
|
|
25576
25731
|
candidates.add(`./${normalized}`);
|
|
25577
25732
|
}
|
|
25578
25733
|
};
|
|
25579
|
-
addCandidate(
|
|
25580
|
-
const originalPath = asset.originalPath.split(
|
|
25581
|
-
const originalAsFileRelative =
|
|
25582
|
-
if (
|
|
25734
|
+
addCandidate(path28.relative(mdDir, assetAbsolute));
|
|
25735
|
+
const originalPath = asset.originalPath.split(path28.sep).join("/");
|
|
25736
|
+
const originalAsFileRelative = path28.resolve(mdDir, ...originalPath.split("/"));
|
|
25737
|
+
if (path28.resolve(originalAsFileRelative) === path28.resolve(assetAbsolute)) {
|
|
25583
25738
|
addCandidate(originalPath);
|
|
25584
25739
|
}
|
|
25585
25740
|
addCandidate(`/${originalPath}`);
|
|
@@ -25675,7 +25830,7 @@ async function findMarkdownFiles(dir) {
|
|
|
25675
25830
|
return;
|
|
25676
25831
|
}
|
|
25677
25832
|
for (const entry of entries) {
|
|
25678
|
-
const full =
|
|
25833
|
+
const full = path28.join(current, entry.name);
|
|
25679
25834
|
if (entry.isDirectory()) {
|
|
25680
25835
|
if (entry.name === ".binary-lifecycle") continue;
|
|
25681
25836
|
await walk(full);
|
|
@@ -25750,7 +25905,7 @@ async function runBinaryLifecyclePipeline(memoryDir, config, backend, log2, opts
|
|
|
25750
25905
|
|
|
25751
25906
|
// src/projection/index.ts
|
|
25752
25907
|
import fs from "fs";
|
|
25753
|
-
import
|
|
25908
|
+
import path29 from "path";
|
|
25754
25909
|
var VALID_PROJECTION_CATEGORIES = new Set(ALL_CATEGORY_KEYS);
|
|
25755
25910
|
async function generateContextTree(options) {
|
|
25756
25911
|
const startTime = Date.now();
|
|
@@ -25765,8 +25920,8 @@ async function generateContextTree(options) {
|
|
|
25765
25920
|
let nodesGenerated = 0;
|
|
25766
25921
|
let nodesSkipped = 0;
|
|
25767
25922
|
const categoryCounts = {};
|
|
25768
|
-
const resolvedMemoryDir =
|
|
25769
|
-
const resolvedOutputDir =
|
|
25923
|
+
const resolvedMemoryDir = path29.resolve(memoryDir);
|
|
25924
|
+
const resolvedOutputDir = path29.resolve(outputDir);
|
|
25770
25925
|
const requestedCategories = validateProjectionCategories(filterCategories);
|
|
25771
25926
|
const realMemoryDir = assertSafeMemoryRoot(resolvedMemoryDir);
|
|
25772
25927
|
assertNotSymlink(resolvedOutputDir, "context tree outputDir");
|
|
@@ -25804,7 +25959,7 @@ async function generateContextTree(options) {
|
|
|
25804
25959
|
}
|
|
25805
25960
|
}
|
|
25806
25961
|
if (includeEntities) {
|
|
25807
|
-
const entitiesDir =
|
|
25962
|
+
const entitiesDir = path29.join(memoryDir, "entities");
|
|
25808
25963
|
if (fs.existsSync(entitiesDir)) {
|
|
25809
25964
|
assertSafeInputRoot(realMemoryDir, entitiesDir, "entities root");
|
|
25810
25965
|
categoryCounts["entity"] = 0;
|
|
@@ -25816,7 +25971,7 @@ async function generateContextTree(options) {
|
|
|
25816
25971
|
continue;
|
|
25817
25972
|
}
|
|
25818
25973
|
const content = fs.readFileSync(filePath, "utf8");
|
|
25819
|
-
const fileName =
|
|
25974
|
+
const fileName = path29.basename(filePath, ".md");
|
|
25820
25975
|
const node = projectEntityNode(fileName, content);
|
|
25821
25976
|
const outputPath = resolveContainedOutputPath(realOutputDir, "entities", `${fileName}.md`);
|
|
25822
25977
|
writeProjectedContent(realOutputDir, outputPath, node.content);
|
|
@@ -25828,7 +25983,7 @@ async function generateContextTree(options) {
|
|
|
25828
25983
|
}
|
|
25829
25984
|
const shouldIncludeQuestions = includeQuestions && (requestedCategories === void 0 || requestedCategories.includes("question"));
|
|
25830
25985
|
if (shouldIncludeQuestions) {
|
|
25831
|
-
const questionsDir =
|
|
25986
|
+
const questionsDir = path29.join(memoryDir, "questions");
|
|
25832
25987
|
if (fs.existsSync(questionsDir)) {
|
|
25833
25988
|
assertSafeInputRoot(realMemoryDir, questionsDir, "questions root");
|
|
25834
25989
|
categoryCounts["question"] = 0;
|
|
@@ -25869,8 +26024,8 @@ async function generateContextTree(options) {
|
|
|
25869
26024
|
};
|
|
25870
26025
|
}
|
|
25871
26026
|
function isPathInside(root, candidate) {
|
|
25872
|
-
const relative =
|
|
25873
|
-
return relative === "" || !relative.startsWith("..") && !
|
|
26027
|
+
const relative = path29.relative(root, candidate);
|
|
26028
|
+
return relative === "" || !relative.startsWith("..") && !path29.isAbsolute(relative);
|
|
25874
26029
|
}
|
|
25875
26030
|
function assertNotSymlink(targetPath, label) {
|
|
25876
26031
|
try {
|
|
@@ -25907,12 +26062,12 @@ function assertSafeInputRoot(realMemoryDir, targetPath, label) {
|
|
|
25907
26062
|
}
|
|
25908
26063
|
function assertSafeOutputTarget(realOutputDir, outputPath) {
|
|
25909
26064
|
let current = realOutputDir;
|
|
25910
|
-
const relative =
|
|
25911
|
-
if (relative.startsWith("..") ||
|
|
26065
|
+
const relative = path29.relative(realOutputDir, outputPath);
|
|
26066
|
+
if (relative.startsWith("..") || path29.isAbsolute(relative)) {
|
|
25912
26067
|
throw new Error(`context tree output path escapes outputDir: ${outputPath}`);
|
|
25913
26068
|
}
|
|
25914
|
-
for (const segment of relative.split(
|
|
25915
|
-
current =
|
|
26069
|
+
for (const segment of relative.split(path29.sep).filter(Boolean)) {
|
|
26070
|
+
current = path29.join(current, segment);
|
|
25916
26071
|
try {
|
|
25917
26072
|
const stat5 = fs.lstatSync(current);
|
|
25918
26073
|
if (stat5.isSymbolicLink()) {
|
|
@@ -25942,17 +26097,17 @@ function validateProjectionCategories(categories) {
|
|
|
25942
26097
|
return validated;
|
|
25943
26098
|
}
|
|
25944
26099
|
function resolveContainedOutputPath(outputRoot, ...segments) {
|
|
25945
|
-
const resolved =
|
|
25946
|
-
const relative =
|
|
25947
|
-
if (relative === "" || !relative.startsWith("..") && !
|
|
26100
|
+
const resolved = path29.resolve(outputRoot, ...segments);
|
|
26101
|
+
const relative = path29.relative(outputRoot, resolved);
|
|
26102
|
+
if (relative === "" || !relative.startsWith("..") && !path29.isAbsolute(relative)) {
|
|
25948
26103
|
return resolved;
|
|
25949
26104
|
}
|
|
25950
26105
|
throw new Error(`context tree output path escapes outputDir: ${segments.join("/")}`);
|
|
25951
26106
|
}
|
|
25952
26107
|
function writeProjectedContent(realOutputDir, outputPath, generatedContent) {
|
|
25953
26108
|
assertSafeOutputTarget(realOutputDir, outputPath);
|
|
25954
|
-
fs.mkdirSync(
|
|
25955
|
-
const realParent = fs.realpathSync(
|
|
26109
|
+
fs.mkdirSync(path29.dirname(outputPath), { recursive: true });
|
|
26110
|
+
const realParent = fs.realpathSync(path29.dirname(outputPath));
|
|
25956
26111
|
if (!isPathInside(realOutputDir, realParent)) {
|
|
25957
26112
|
throw new Error(`context tree output path escapes outputDir: ${outputPath}`);
|
|
25958
26113
|
}
|
|
@@ -25991,7 +26146,7 @@ function walkR(dir, realMemoryDir) {
|
|
|
25991
26146
|
const results = [];
|
|
25992
26147
|
function walk(directory) {
|
|
25993
26148
|
for (const entry of fs.readdirSync(directory, { withFileTypes: true })) {
|
|
25994
|
-
const fullPath =
|
|
26149
|
+
const fullPath = path29.join(directory, entry.name);
|
|
25995
26150
|
if (entry.isSymbolicLink()) {
|
|
25996
26151
|
throw new Error(`context tree input path contains symlink: ${fullPath}`);
|
|
25997
26152
|
}
|
|
@@ -26044,13 +26199,13 @@ function extractBody(content) {
|
|
|
26044
26199
|
}
|
|
26045
26200
|
function projectNode(filePath, category, fm, rawContent) {
|
|
26046
26201
|
const body = extractBody(rawContent);
|
|
26047
|
-
const fileName =
|
|
26048
|
-
const dateDir =
|
|
26202
|
+
const fileName = path29.basename(filePath, ".md");
|
|
26203
|
+
const dateDir = path29.basename(path29.dirname(filePath));
|
|
26049
26204
|
let relPath;
|
|
26050
26205
|
if (/^\d{4}-\d{2}-\d{2}$/.test(dateDir)) {
|
|
26051
|
-
relPath =
|
|
26206
|
+
relPath = path29.join(category, dateDir, `${fileName}.md`);
|
|
26052
26207
|
} else {
|
|
26053
|
-
relPath =
|
|
26208
|
+
relPath = path29.join(category, `${fileName}.md`);
|
|
26054
26209
|
}
|
|
26055
26210
|
const generatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
26056
26211
|
const md = `# ${fm.id}
|
|
@@ -26096,7 +26251,7 @@ function projectEntityNode(fileName, content) {
|
|
|
26096
26251
|
${content}
|
|
26097
26252
|
`;
|
|
26098
26253
|
return {
|
|
26099
|
-
path:
|
|
26254
|
+
path: path29.join("entities", `${fileName}.md`),
|
|
26100
26255
|
category: "entity",
|
|
26101
26256
|
title: fileName,
|
|
26102
26257
|
content: md,
|
|
@@ -26149,7 +26304,7 @@ function generateIndex(categoryCounts, outputDir) {
|
|
|
26149
26304
|
|
|
26150
26305
|
// src/onboarding/index.ts
|
|
26151
26306
|
import fs2 from "fs";
|
|
26152
|
-
import
|
|
26307
|
+
import path30 from "path";
|
|
26153
26308
|
var LANGUAGE_RULES = [
|
|
26154
26309
|
{
|
|
26155
26310
|
language: "TypeScript",
|
|
@@ -26251,7 +26406,7 @@ function onboard(options) {
|
|
|
26251
26406
|
maxDepth = 6,
|
|
26252
26407
|
excludeDirs = []
|
|
26253
26408
|
} = options;
|
|
26254
|
-
const directory =
|
|
26409
|
+
const directory = path30.resolve(options.directory ?? process.cwd());
|
|
26255
26410
|
let rootStat;
|
|
26256
26411
|
try {
|
|
26257
26412
|
rootStat = fs2.statSync(directory);
|
|
@@ -26293,7 +26448,7 @@ function walkDir(root, exclude, maxDepth) {
|
|
|
26293
26448
|
}
|
|
26294
26449
|
for (const entry of entries) {
|
|
26295
26450
|
if (exclude.has(entry.name)) continue;
|
|
26296
|
-
const fullPath =
|
|
26451
|
+
const fullPath = path30.join(dir, entry.name);
|
|
26297
26452
|
if (entry.isDirectory()) {
|
|
26298
26453
|
walk(fullPath, depth + 1);
|
|
26299
26454
|
} else if (entry.isFile()) {
|
|
@@ -26308,11 +26463,11 @@ function detectLanguages(files, root) {
|
|
|
26308
26463
|
const results = [];
|
|
26309
26464
|
const extCounts = /* @__PURE__ */ new Map();
|
|
26310
26465
|
for (const f of files) {
|
|
26311
|
-
const ext =
|
|
26466
|
+
const ext = path30.extname(f).toLowerCase();
|
|
26312
26467
|
if (ext) extCounts.set(ext, (extCounts.get(ext) ?? 0) + 1);
|
|
26313
26468
|
}
|
|
26314
26469
|
const rootFiles = new Set(
|
|
26315
|
-
files.filter((f) =>
|
|
26470
|
+
files.filter((f) => path30.dirname(f) === root).map((f) => path30.basename(f))
|
|
26316
26471
|
);
|
|
26317
26472
|
for (const rule of LANGUAGE_RULES) {
|
|
26318
26473
|
const evidence = [];
|
|
@@ -26356,7 +26511,7 @@ function detectLanguages(files, root) {
|
|
|
26356
26511
|
}
|
|
26357
26512
|
function detectShape(files, root) {
|
|
26358
26513
|
const rootFiles = new Set(
|
|
26359
|
-
files.filter((f) =>
|
|
26514
|
+
files.filter((f) => path30.dirname(f) === root).map((f) => path30.basename(f))
|
|
26360
26515
|
);
|
|
26361
26516
|
const rootDirs = /* @__PURE__ */ new Set();
|
|
26362
26517
|
try {
|
|
@@ -26367,7 +26522,7 @@ function detectShape(files, root) {
|
|
|
26367
26522
|
}
|
|
26368
26523
|
const evidence = [];
|
|
26369
26524
|
if (rootFiles.has("package.json")) {
|
|
26370
|
-
const pkg = readJsonSafe(
|
|
26525
|
+
const pkg = readJsonSafe(path30.join(root, "package.json"));
|
|
26371
26526
|
if (pkg?.workspaces) {
|
|
26372
26527
|
evidence.push("package.json has workspaces");
|
|
26373
26528
|
return { shape: "monorepo", evidence };
|
|
@@ -26381,13 +26536,13 @@ function detectShape(files, root) {
|
|
|
26381
26536
|
evidence.push("workspace manifest found");
|
|
26382
26537
|
return { shape: "workspace", evidence };
|
|
26383
26538
|
}
|
|
26384
|
-
const cargoToml = readTomlWorkspace(
|
|
26539
|
+
const cargoToml = readTomlWorkspace(path30.join(root, "Cargo.toml"));
|
|
26385
26540
|
if (cargoToml) {
|
|
26386
26541
|
evidence.push("Cargo.toml has workspace");
|
|
26387
26542
|
return { shape: "workspace", evidence };
|
|
26388
26543
|
}
|
|
26389
26544
|
if (rootFiles.has("package.json")) {
|
|
26390
|
-
const pkg = readJsonSafe(
|
|
26545
|
+
const pkg = readJsonSafe(path30.join(root, "package.json"));
|
|
26391
26546
|
if (pkg?.exports || pkg?.main) {
|
|
26392
26547
|
if (pkg?.bin) {
|
|
26393
26548
|
evidence.push("package.json has bin");
|
|
@@ -26421,8 +26576,8 @@ function discoverDocs(files, root) {
|
|
|
26421
26576
|
{ pattern: /^\.editorconfig$/i, kind: "config" }
|
|
26422
26577
|
];
|
|
26423
26578
|
for (const filePath of files) {
|
|
26424
|
-
const basename =
|
|
26425
|
-
const relPath =
|
|
26579
|
+
const basename = path30.basename(filePath).toLowerCase();
|
|
26580
|
+
const relPath = path30.relative(root, filePath);
|
|
26426
26581
|
let kind;
|
|
26427
26582
|
for (const { pattern, kind: k } of docPatterns) {
|
|
26428
26583
|
if (pattern.test(basename)) {
|
|
@@ -26434,7 +26589,7 @@ function discoverDocs(files, root) {
|
|
|
26434
26589
|
kind = "docs";
|
|
26435
26590
|
}
|
|
26436
26591
|
if (!kind && (basename.endsWith(".md") || basename.endsWith(".mdx"))) {
|
|
26437
|
-
if (
|
|
26592
|
+
if (path30.dirname(relPath) === "." || isUnderDocsDir(relPath)) {
|
|
26438
26593
|
kind = "docs";
|
|
26439
26594
|
}
|
|
26440
26595
|
}
|
|
@@ -26455,7 +26610,7 @@ function discoverDocs(files, root) {
|
|
|
26455
26610
|
return docs;
|
|
26456
26611
|
}
|
|
26457
26612
|
function isUnderDocsDir(relPath) {
|
|
26458
|
-
const parts = relPath.split(
|
|
26613
|
+
const parts = relPath.split(path30.sep);
|
|
26459
26614
|
return parts[0] === "docs" || parts[0] === "doc" || parts[0] === "documentation";
|
|
26460
26615
|
}
|
|
26461
26616
|
function buildPlan(languages, shape, docs, _root) {
|
|
@@ -26499,7 +26654,7 @@ function readTomlWorkspace(filePath) {
|
|
|
26499
26654
|
|
|
26500
26655
|
// src/curation/index.ts
|
|
26501
26656
|
import fs3 from "fs";
|
|
26502
|
-
import
|
|
26657
|
+
import path31 from "path";
|
|
26503
26658
|
import crypto4 from "crypto";
|
|
26504
26659
|
async function curate(options) {
|
|
26505
26660
|
const startTime = Date.now();
|
|
@@ -26590,12 +26745,12 @@ function resolveTargets(targetPath) {
|
|
|
26590
26745
|
const extensions = /* @__PURE__ */ new Set([".md", ".txt", ".mdx", ".rst"]);
|
|
26591
26746
|
function walk(dir) {
|
|
26592
26747
|
for (const entry of fs3.readdirSync(dir, { withFileTypes: true })) {
|
|
26593
|
-
const fullPath =
|
|
26748
|
+
const fullPath = path31.join(dir, entry.name);
|
|
26594
26749
|
if (entry.isDirectory()) {
|
|
26595
26750
|
if (entry.name !== "node_modules" && entry.name !== ".git") {
|
|
26596
26751
|
walk(fullPath);
|
|
26597
26752
|
}
|
|
26598
|
-
} else if (extensions.has(
|
|
26753
|
+
} else if (extensions.has(path31.extname(entry.name).toLowerCase())) {
|
|
26599
26754
|
results.push(fullPath);
|
|
26600
26755
|
}
|
|
26601
26756
|
}
|
|
@@ -26604,12 +26759,12 @@ function resolveTargets(targetPath) {
|
|
|
26604
26759
|
return results;
|
|
26605
26760
|
}
|
|
26606
26761
|
function resolveProvenanceRoot(targetPath) {
|
|
26607
|
-
const resolvedTarget =
|
|
26762
|
+
const resolvedTarget = path31.resolve(targetPath);
|
|
26608
26763
|
const stat5 = fs3.statSync(resolvedTarget);
|
|
26609
|
-
return stat5.isFile() ?
|
|
26764
|
+
return stat5.isFile() ? path31.dirname(resolvedTarget) : resolvedTarget;
|
|
26610
26765
|
}
|
|
26611
26766
|
function extractStatements(content, filePath, projectRoot, source, sourceFileHash, categoryOverride, confidence, entityRef, tags) {
|
|
26612
|
-
const relativePath =
|
|
26767
|
+
const relativePath = path31.relative(projectRoot, path31.resolve(filePath)) || path31.basename(filePath);
|
|
26613
26768
|
const statements = [];
|
|
26614
26769
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
26615
26770
|
const paragraphs = content.split(/\n{2,}/).map((p) => p.trim()).filter((p) => p.length > 20 && p.length < 2e3);
|
|
@@ -26703,7 +26858,7 @@ function loadExistingMemories(memoryDir) {
|
|
|
26703
26858
|
if (!fs3.existsSync(memoryDir)) return result;
|
|
26704
26859
|
const dirs = ALL_CATEGORY_DIRS;
|
|
26705
26860
|
for (const dir of dirs) {
|
|
26706
|
-
const fullDir =
|
|
26861
|
+
const fullDir = path31.join(memoryDir, dir);
|
|
26707
26862
|
if (!fs3.existsSync(fullDir)) continue;
|
|
26708
26863
|
walkFiles(fullDir, (filePath) => {
|
|
26709
26864
|
const content = readFileSafe(filePath);
|
|
@@ -26726,11 +26881,11 @@ function writeStatement(stmt, memoryDir) {
|
|
|
26726
26881
|
const now = /* @__PURE__ */ new Date();
|
|
26727
26882
|
const dateDir = now.toISOString().split("T")[0];
|
|
26728
26883
|
const categoryDir = getCategoryDir(memoryDir, stmt.category);
|
|
26729
|
-
const dir =
|
|
26884
|
+
const dir = path31.join(categoryDir, dateDir);
|
|
26730
26885
|
fs3.mkdirSync(dir, { recursive: true });
|
|
26731
26886
|
const fileName = `${stmt.category}-${Date.now()}-${stmt.id.slice(0, 8)}.md`;
|
|
26732
|
-
const filePath =
|
|
26733
|
-
const historicalIds = historicalIdCache2.get(
|
|
26887
|
+
const filePath = path31.join(dir, fileName);
|
|
26888
|
+
const historicalIds = historicalIdCache2.get(path31.join(memoryDir, "state"));
|
|
26734
26889
|
const rawBody = `${[
|
|
26735
26890
|
"---",
|
|
26736
26891
|
`id: ${stmt.id}`,
|
|
@@ -26753,7 +26908,7 @@ ${stmt.content}
|
|
|
26753
26908
|
fs3.writeFileSync(filePath, body);
|
|
26754
26909
|
try {
|
|
26755
26910
|
repairContentAfterJournalMoveSync({
|
|
26756
|
-
stateDir:
|
|
26911
|
+
stateDir: path31.join(memoryDir, "state"),
|
|
26757
26912
|
cache: historicalIdCache2,
|
|
26758
26913
|
idsAtWrite: historicalIds,
|
|
26759
26914
|
rawContent: rawBody,
|
|
@@ -26814,7 +26969,7 @@ function extractBody2(content) {
|
|
|
26814
26969
|
}
|
|
26815
26970
|
function walkFiles(dir, callback) {
|
|
26816
26971
|
for (const entry of fs3.readdirSync(dir, { withFileTypes: true })) {
|
|
26817
|
-
const fullPath =
|
|
26972
|
+
const fullPath = path31.join(dir, entry.name);
|
|
26818
26973
|
if (entry.isDirectory()) {
|
|
26819
26974
|
walkFiles(fullPath, callback);
|
|
26820
26975
|
} else if (entry.name.endsWith(".md")) {
|
|
@@ -26825,7 +26980,7 @@ function walkFiles(dir, callback) {
|
|
|
26825
26980
|
|
|
26826
26981
|
// src/sync/index.ts
|
|
26827
26982
|
import fs4 from "fs";
|
|
26828
|
-
import
|
|
26983
|
+
import path32 from "path";
|
|
26829
26984
|
import crypto5 from "crypto";
|
|
26830
26985
|
var DEFAULT_EXTENSIONS = /* @__PURE__ */ new Set([".md", ".txt", ".mdx", ".rst"]);
|
|
26831
26986
|
var DEFAULT_EXCLUDE2 = /* @__PURE__ */ new Set([
|
|
@@ -26847,7 +27002,7 @@ function syncChanges(options) {
|
|
|
26847
27002
|
} = options;
|
|
26848
27003
|
const extSet = new Set(extensions);
|
|
26849
27004
|
const excludeSet = /* @__PURE__ */ new Set([...DEFAULT_EXCLUDE2, ...excludeDirs]);
|
|
26850
|
-
const stateFilePath = options.stateFile ??
|
|
27005
|
+
const stateFilePath = options.stateFile ?? path32.join(memoryDir, ".sync-state.json");
|
|
26851
27006
|
const prevState = loadState(stateFilePath);
|
|
26852
27007
|
const currentFiles = scanFiles(sourceDir, extSet, excludeSet);
|
|
26853
27008
|
const changes = computeDiff(currentFiles, prevState.fileHashes, sourceDir);
|
|
@@ -26863,7 +27018,7 @@ function syncChanges(options) {
|
|
|
26863
27018
|
for (const [relPath, hash] of Object.entries(currentFiles)) {
|
|
26864
27019
|
newState.fileHashes[relPath] = hash;
|
|
26865
27020
|
}
|
|
26866
|
-
fs4.mkdirSync(
|
|
27021
|
+
fs4.mkdirSync(path32.dirname(stateFilePath), { recursive: true });
|
|
26867
27022
|
fs4.writeFileSync(stateFilePath, JSON.stringify(newState, null, 2));
|
|
26868
27023
|
}
|
|
26869
27024
|
return {
|
|
@@ -26929,13 +27084,13 @@ function scanFiles(root, extensions, exclude) {
|
|
|
26929
27084
|
}
|
|
26930
27085
|
for (const entry of entries) {
|
|
26931
27086
|
if (exclude.has(entry.name)) continue;
|
|
26932
|
-
const fullPath =
|
|
27087
|
+
const fullPath = path32.join(dir, entry.name);
|
|
26933
27088
|
if (entry.isDirectory()) {
|
|
26934
27089
|
walk(fullPath);
|
|
26935
27090
|
} else if (entry.isFile()) {
|
|
26936
|
-
const ext =
|
|
27091
|
+
const ext = path32.extname(entry.name).toLowerCase();
|
|
26937
27092
|
if (!extensions.has(ext)) continue;
|
|
26938
|
-
const relPath =
|
|
27093
|
+
const relPath = path32.relative(root, fullPath);
|
|
26939
27094
|
try {
|
|
26940
27095
|
const content = fs4.readFileSync(fullPath, "utf8");
|
|
26941
27096
|
result[relPath] = hashContent2(content);
|
|
@@ -26950,7 +27105,7 @@ function scanFiles(root, extensions, exclude) {
|
|
|
26950
27105
|
function computeDiff(current, previous, sourceDir) {
|
|
26951
27106
|
const changes = [];
|
|
26952
27107
|
for (const [relPath, hash] of Object.entries(current)) {
|
|
26953
|
-
const fullPath =
|
|
27108
|
+
const fullPath = path32.join(sourceDir, relPath);
|
|
26954
27109
|
if (!(relPath in previous)) {
|
|
26955
27110
|
let size = 0;
|
|
26956
27111
|
try {
|
|
@@ -26983,7 +27138,7 @@ function computeDiff(current, previous, sourceDir) {
|
|
|
26983
27138
|
for (const relPath of Object.keys(previous)) {
|
|
26984
27139
|
if (!(relPath in current)) {
|
|
26985
27140
|
changes.push({
|
|
26986
|
-
filePath:
|
|
27141
|
+
filePath: path32.join(sourceDir, relPath),
|
|
26987
27142
|
relativePath: relPath,
|
|
26988
27143
|
type: "deleted",
|
|
26989
27144
|
currentHash: "",
|
|
@@ -27013,21 +27168,21 @@ function hashContent2(content) {
|
|
|
27013
27168
|
import { spawnSync } from "child_process";
|
|
27014
27169
|
import crypto6 from "crypto";
|
|
27015
27170
|
import fs5 from "fs";
|
|
27016
|
-
import
|
|
27171
|
+
import path33 from "path";
|
|
27017
27172
|
var historicalIdCache3 = new HistoricalEntityCanonicalIdCache();
|
|
27018
27173
|
var MANIFEST_VERSION = 1;
|
|
27019
27174
|
var MANIFEST_LOCK_STALE_MS = 3e4;
|
|
27020
27175
|
var MANIFEST_LOCK_TIMEOUT_MS = MANIFEST_LOCK_STALE_MS + 1e4;
|
|
27021
27176
|
var MANIFEST_LOCK_SLEEP_MS = 20;
|
|
27022
27177
|
function normalizeSpaceMemoryDir(memoryDir) {
|
|
27023
|
-
return
|
|
27178
|
+
return path33.resolve(memoryDir);
|
|
27024
27179
|
}
|
|
27025
27180
|
function getSpacesDir(baseDir) {
|
|
27026
27181
|
const homeDir = baseDir ?? resolveHomeDir();
|
|
27027
|
-
return
|
|
27182
|
+
return path33.join(homeDir, ".config", "engram", "spaces");
|
|
27028
27183
|
}
|
|
27029
27184
|
function getManifestPath(baseDir) {
|
|
27030
|
-
return
|
|
27185
|
+
return path33.join(getSpacesDir(baseDir), "manifest.json");
|
|
27031
27186
|
}
|
|
27032
27187
|
function loadManifest(baseDir, memoryDirOverride) {
|
|
27033
27188
|
if (fs5.existsSync(getManifestPath(baseDir))) {
|
|
@@ -27074,9 +27229,9 @@ function readManifestUnlocked(baseDir, memoryDirOverride, options = {}) {
|
|
|
27074
27229
|
}
|
|
27075
27230
|
function saveManifestUnlocked(manifest, baseDir) {
|
|
27076
27231
|
const manifestPath2 = getManifestPath(baseDir);
|
|
27077
|
-
const manifestDir2 =
|
|
27232
|
+
const manifestDir2 = path33.dirname(manifestPath2);
|
|
27078
27233
|
fs5.mkdirSync(manifestDir2, { recursive: true });
|
|
27079
|
-
const tempPath =
|
|
27234
|
+
const tempPath = path33.join(manifestDir2, `.manifest.${process.pid}.${Date.now()}.${crypto6.randomUUID()}.tmp`);
|
|
27080
27235
|
try {
|
|
27081
27236
|
fs5.writeFileSync(tempPath, `${JSON.stringify(manifest, null, 2)}
|
|
27082
27237
|
`, { flag: "wx" });
|
|
@@ -27091,7 +27246,7 @@ function saveManifestUnlocked(manifest, baseDir) {
|
|
|
27091
27246
|
}
|
|
27092
27247
|
function withManifestLock(baseDir, operation) {
|
|
27093
27248
|
const lockDir = `${getManifestPath(baseDir)}.lock`;
|
|
27094
|
-
fs5.mkdirSync(
|
|
27249
|
+
fs5.mkdirSync(path33.dirname(lockDir), { recursive: true });
|
|
27095
27250
|
const lockOwner = acquireManifestLock(lockDir);
|
|
27096
27251
|
try {
|
|
27097
27252
|
return operation();
|
|
@@ -27117,7 +27272,7 @@ function acquireManifestLock(lockDir) {
|
|
|
27117
27272
|
try {
|
|
27118
27273
|
fs5.mkdirSync(lockDir, { recursive: false });
|
|
27119
27274
|
try {
|
|
27120
|
-
fs5.writeFileSync(
|
|
27275
|
+
fs5.writeFileSync(path33.join(lockDir, "owner"), `${owner}
|
|
27121
27276
|
`, { flag: "wx" });
|
|
27122
27277
|
} catch (error) {
|
|
27123
27278
|
fs5.rmSync(lockDir, { recursive: true, force: true });
|
|
@@ -27147,7 +27302,7 @@ function acquireManifestLock(lockDir) {
|
|
|
27147
27302
|
}
|
|
27148
27303
|
function releaseManifestLock(lockDir, owner) {
|
|
27149
27304
|
try {
|
|
27150
|
-
const ownerPath =
|
|
27305
|
+
const ownerPath = path33.join(lockDir, "owner");
|
|
27151
27306
|
if (fs5.readFileSync(ownerPath, "utf8").trim() === owner) {
|
|
27152
27307
|
fs5.rmSync(lockDir, { recursive: true, force: true });
|
|
27153
27308
|
}
|
|
@@ -27163,7 +27318,7 @@ function removeStaleManifestLock(lockDir) {
|
|
|
27163
27318
|
try {
|
|
27164
27319
|
fs5.mkdirSync(reclaimDir, { recursive: false });
|
|
27165
27320
|
try {
|
|
27166
|
-
fs5.writeFileSync(
|
|
27321
|
+
fs5.writeFileSync(path33.join(reclaimDir, "owner"), `${reclaimOwner}
|
|
27167
27322
|
`, { flag: "wx" });
|
|
27168
27323
|
} catch (error) {
|
|
27169
27324
|
fs5.rmSync(reclaimDir, { recursive: true, force: true });
|
|
@@ -27238,7 +27393,7 @@ function readManifestLockSnapshot(lockDir) {
|
|
|
27238
27393
|
throw error;
|
|
27239
27394
|
}
|
|
27240
27395
|
try {
|
|
27241
|
-
const owner = fs5.readFileSync(
|
|
27396
|
+
const owner = fs5.readFileSync(path33.join(lockDir, "owner"), "utf8").trim();
|
|
27242
27397
|
return { mtimeMs: stat5.mtimeMs, owner };
|
|
27243
27398
|
} catch (error) {
|
|
27244
27399
|
if (error.code === "ENOENT") {
|
|
@@ -27310,8 +27465,8 @@ function sleepSync(ms) {
|
|
|
27310
27465
|
}
|
|
27311
27466
|
function createPersonalSpace(baseDir, memoryDirOverride) {
|
|
27312
27467
|
const homeDir = baseDir ?? resolveHomeDir();
|
|
27313
|
-
const standalonePath =
|
|
27314
|
-
const openclawPath =
|
|
27468
|
+
const standalonePath = path33.join(homeDir, ".engram", "memory");
|
|
27469
|
+
const openclawPath = path33.join(homeDir, ".openclaw", "workspace", "memory", "local");
|
|
27315
27470
|
const memoryDir = memoryDirOverride ?? readEnvVar("REMNIC_MEMORY_DIR") ?? readEnvVar("ENGRAM_MEMORY_DIR") ?? (fs5.existsSync(standalonePath) ? standalonePath : fs5.existsSync(openclawPath) ? openclawPath : standalonePath);
|
|
27316
27471
|
const normalizedMemoryDir = normalizeSpaceMemoryDir(memoryDir);
|
|
27317
27472
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -27340,7 +27495,7 @@ function createSpace(options) {
|
|
|
27340
27495
|
const id = options.name.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-");
|
|
27341
27496
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
27342
27497
|
const memoryDir = normalizeSpaceMemoryDir(
|
|
27343
|
-
options.memoryDir ??
|
|
27498
|
+
options.memoryDir ?? path33.join(getSpacesDir(options.baseDir), id, "memory")
|
|
27344
27499
|
);
|
|
27345
27500
|
const space = updateManifest(options.baseDir, (manifest) => {
|
|
27346
27501
|
if (manifest.spaces.some((s) => s.id === id)) {
|
|
@@ -27586,14 +27741,14 @@ async function mergeSpaces(sourceSpaceId, targetSpaceId, options) {
|
|
|
27586
27741
|
};
|
|
27587
27742
|
}
|
|
27588
27743
|
function getAuditLog(baseDir) {
|
|
27589
|
-
const auditPath =
|
|
27744
|
+
const auditPath = path33.join(getSpacesDir(baseDir), "audit.jsonl");
|
|
27590
27745
|
if (!fs5.existsSync(auditPath)) return [];
|
|
27591
27746
|
const lines = fs5.readFileSync(auditPath, "utf8").trim().split("\n");
|
|
27592
27747
|
return lines.filter((l) => l.trim()).map((l) => JSON.parse(l));
|
|
27593
27748
|
}
|
|
27594
27749
|
function appendAudit(entry, baseDir) {
|
|
27595
|
-
const auditPath =
|
|
27596
|
-
fs5.mkdirSync(
|
|
27750
|
+
const auditPath = path33.join(getSpacesDir(baseDir), "audit.jsonl");
|
|
27751
|
+
fs5.mkdirSync(path33.dirname(auditPath), { recursive: true });
|
|
27597
27752
|
const full = {
|
|
27598
27753
|
id: crypto6.randomUUID(),
|
|
27599
27754
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -27614,11 +27769,11 @@ async function copyMemories(sourceDir, targetDir, options) {
|
|
|
27614
27769
|
sourceFiles.filter((p) => {
|
|
27615
27770
|
const rp = safeRealpath(p);
|
|
27616
27771
|
if (!rp || !isPathInsideRoot(rp, sourceRoot)) return false;
|
|
27617
|
-
const rel =
|
|
27618
|
-
const mapped =
|
|
27772
|
+
const rel = path33.relative(sourceRoot, rp);
|
|
27773
|
+
const mapped = path33.resolve(targetRoot, rel);
|
|
27619
27774
|
if (!isPathInsideRoot(mapped, targetRoot)) return false;
|
|
27620
27775
|
return classifyEntityRefWritePath(targetRoot, mapped) === "entity";
|
|
27621
|
-
}).map((p) =>
|
|
27776
|
+
}).map((p) => path33.basename(p, ".md"))
|
|
27622
27777
|
);
|
|
27623
27778
|
const firstEntityId = sourceEntityIds.values().next().value;
|
|
27624
27779
|
if (firstEntityId === void 0) {
|
|
@@ -27626,7 +27781,7 @@ async function copyMemories(sourceDir, targetDir, options) {
|
|
|
27626
27781
|
}
|
|
27627
27782
|
return withRawEntityPageMutation(
|
|
27628
27783
|
targetRoot,
|
|
27629
|
-
|
|
27784
|
+
path33.join(targetRoot, "entities", `${firstEntityId}.md`),
|
|
27630
27785
|
async () => copyPreparedMemories(
|
|
27631
27786
|
sourceFiles,
|
|
27632
27787
|
sourceRoot,
|
|
@@ -27653,14 +27808,14 @@ function copyPreparedMemories(sourceFiles, sourceRoot, targetRoot, sourceEntityI
|
|
|
27653
27808
|
continue;
|
|
27654
27809
|
}
|
|
27655
27810
|
const content = fs5.readFileSync(sourcePath, "utf8");
|
|
27656
|
-
const relativePath =
|
|
27657
|
-
const targetPath =
|
|
27811
|
+
const relativePath = path33.relative(sourceRoot, sourceRealPath);
|
|
27812
|
+
const targetPath = path33.resolve(targetRoot, relativePath);
|
|
27658
27813
|
if (!isPathInsideRoot(targetPath, targetRoot)) {
|
|
27659
27814
|
skipped++;
|
|
27660
27815
|
continue;
|
|
27661
27816
|
}
|
|
27662
27817
|
const targetKind = classifyEntityRefWritePath(targetRoot, targetPath);
|
|
27663
|
-
const idsAtCompare = historicalIdCache3.get(
|
|
27818
|
+
const idsAtCompare = historicalIdCache3.get(path33.join(targetRoot, "state"));
|
|
27664
27819
|
const sourceRef = targetKind === "memory" ? readEntityRefFromFrontmatter(content) : null;
|
|
27665
27820
|
const refHasSourceClaimant = sourceRef !== null && sourceEntityIds.has(sourceRef);
|
|
27666
27821
|
const canonicalContent = targetKind === "memory" && !refHasSourceClaimant ? canonicalizeEntityRefFrontmatter(content, idsAtCompare) : content;
|
|
@@ -27687,7 +27842,7 @@ function copyPreparedMemories(sourceFiles, sourceRoot, targetRoot, sourceEntityI
|
|
|
27687
27842
|
if (fs5.existsSync(targetPath) && !options?.force) {
|
|
27688
27843
|
const targetContent = fs5.readFileSync(targetPath, "utf8");
|
|
27689
27844
|
const targetHash = hashContent3(targetContent);
|
|
27690
|
-
if (hashContent3(canonicalContent) === targetHash && historicalIdCache3.get(
|
|
27845
|
+
if (hashContent3(canonicalContent) === targetHash && historicalIdCache3.get(path33.join(targetRoot, "state")) === idsAtCompare) {
|
|
27691
27846
|
skipped++;
|
|
27692
27847
|
continue;
|
|
27693
27848
|
}
|
|
@@ -27703,13 +27858,13 @@ function copyPreparedMemories(sourceFiles, sourceRoot, targetRoot, sourceEntityI
|
|
|
27703
27858
|
continue;
|
|
27704
27859
|
}
|
|
27705
27860
|
}
|
|
27706
|
-
fs5.mkdirSync(
|
|
27707
|
-
const targetParentRealPath = safeRealpath(
|
|
27861
|
+
fs5.mkdirSync(path33.dirname(targetPath), { recursive: true });
|
|
27862
|
+
const targetParentRealPath = safeRealpath(path33.dirname(targetPath));
|
|
27708
27863
|
if (!targetParentRealPath || !isPathInsideRoot(targetParentRealPath, targetRoot)) {
|
|
27709
27864
|
skipped++;
|
|
27710
27865
|
continue;
|
|
27711
27866
|
}
|
|
27712
|
-
const stateDir =
|
|
27867
|
+
const stateDir = path33.join(targetRoot, "state");
|
|
27713
27868
|
if (targetKind === "memory" && !refHasSourceClaimant) {
|
|
27714
27869
|
const idsAtWrite = historicalIdCache3.get(stateDir);
|
|
27715
27870
|
const written = canonicalizeEntityRefFrontmatter(content, idsAtWrite);
|
|
@@ -27753,7 +27908,7 @@ function copyPreparedMemories(sourceFiles, sourceRoot, targetRoot, sourceEntityI
|
|
|
27753
27908
|
bumpMemoryCorpusVersionForDir(targetRoot);
|
|
27754
27909
|
}
|
|
27755
27910
|
if (reconcileNeeded) {
|
|
27756
|
-
requestEntityCanonicalIdReconcileSync(
|
|
27911
|
+
requestEntityCanonicalIdReconcileSync(path33.join(targetRoot, "state"));
|
|
27757
27912
|
}
|
|
27758
27913
|
return { merged, conflicts, skipped };
|
|
27759
27914
|
}
|
|
@@ -27764,7 +27919,7 @@ function walkMd(dir) {
|
|
|
27764
27919
|
const results = [];
|
|
27765
27920
|
function walk(d) {
|
|
27766
27921
|
for (const entry of fs5.readdirSync(d, { withFileTypes: true })) {
|
|
27767
|
-
const fullPath =
|
|
27922
|
+
const fullPath = path33.join(d, entry.name);
|
|
27768
27923
|
if (entry.isSymbolicLink()) {
|
|
27769
27924
|
continue;
|
|
27770
27925
|
}
|
|
@@ -27793,8 +27948,8 @@ function safeRealpath(filePath) {
|
|
|
27793
27948
|
}
|
|
27794
27949
|
}
|
|
27795
27950
|
function isPathInsideRoot(candidatePath, rootPath) {
|
|
27796
|
-
const relative =
|
|
27797
|
-
return relative === "" || !relative.startsWith("..") && !
|
|
27951
|
+
const relative = path33.relative(rootPath, candidatePath);
|
|
27952
|
+
return relative === "" || !relative.startsWith("..") && !path33.isAbsolute(relative);
|
|
27798
27953
|
}
|
|
27799
27954
|
function parseSimpleFrontmatter(content) {
|
|
27800
27955
|
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
@@ -27915,7 +28070,7 @@ var REMNIC_RECALL_DECISION_RULES = `## When to Use Recall vs Direct Read
|
|
|
27915
28070
|
// src/memory-extension/codex-publisher.ts
|
|
27916
28071
|
import fs6 from "fs";
|
|
27917
28072
|
import os from "os";
|
|
27918
|
-
import
|
|
28073
|
+
import path34 from "path";
|
|
27919
28074
|
var REMNIC_EXTENSION_DIR_NAME = "remnic";
|
|
27920
28075
|
function resolveEnvHome(env) {
|
|
27921
28076
|
if (env === void 0) return resolveHomeDir();
|
|
@@ -27924,12 +28079,12 @@ function resolveEnvHome(env) {
|
|
|
27924
28079
|
function expandTildeWithHome(input, homeDir) {
|
|
27925
28080
|
if (input === "~") return homeDir;
|
|
27926
28081
|
if (input.startsWith("~/") || input.startsWith("~\\")) {
|
|
27927
|
-
return
|
|
28082
|
+
return path34.join(homeDir, input.slice(2));
|
|
27928
28083
|
}
|
|
27929
28084
|
return input;
|
|
27930
28085
|
}
|
|
27931
28086
|
function normalizeHostRoot(input, homeDir) {
|
|
27932
|
-
return
|
|
28087
|
+
return path34.resolve(expandTildeWithHome(input.trim(), homeDir));
|
|
27933
28088
|
}
|
|
27934
28089
|
var CodexMemoryExtensionPublisher = class {
|
|
27935
28090
|
hostId = "codex";
|
|
@@ -27943,12 +28098,12 @@ var CodexMemoryExtensionPublisher = class {
|
|
|
27943
28098
|
async resolveExtensionRoot(env) {
|
|
27944
28099
|
const homeDir = resolveEnvHome(env);
|
|
27945
28100
|
const codexHomeInput = env === void 0 ? readEnvVar("CODEX_HOME")?.trim() : env.CODEX_HOME?.trim();
|
|
27946
|
-
const codexHome = codexHomeInput ? normalizeHostRoot(codexHomeInput, homeDir) :
|
|
27947
|
-
return
|
|
28101
|
+
const codexHome = codexHomeInput ? normalizeHostRoot(codexHomeInput, homeDir) : path34.resolve(homeDir, ".codex");
|
|
28102
|
+
return path34.join(codexHome, "memories_extensions", REMNIC_EXTENSION_DIR_NAME);
|
|
27948
28103
|
}
|
|
27949
28104
|
async isHostAvailable() {
|
|
27950
28105
|
try {
|
|
27951
|
-
const home = readEnvVar("CODEX_HOME")?.trim() ||
|
|
28106
|
+
const home = readEnvVar("CODEX_HOME")?.trim() || path34.join(resolveHomeDir(), ".codex");
|
|
27952
28107
|
return fs6.existsSync(home);
|
|
27953
28108
|
} catch {
|
|
27954
28109
|
return false;
|
|
@@ -27999,7 +28154,7 @@ When running inside the Codex phase-2 consolidation sandbox:
|
|
|
27999
28154
|
}
|
|
28000
28155
|
async publish(ctx) {
|
|
28001
28156
|
const extensionRoot = await this.resolveExtensionRoot();
|
|
28002
|
-
const instructionsPath =
|
|
28157
|
+
const instructionsPath = path34.join(extensionRoot, "instructions.md");
|
|
28003
28158
|
const filesWritten = [];
|
|
28004
28159
|
const skipped = [];
|
|
28005
28160
|
ctx.log.info(`Publishing Codex memory extension to ${extensionRoot}`);
|
|
@@ -28631,9 +28786,9 @@ function buildWeeklyActivitySummary(cards, options) {
|
|
|
28631
28786
|
// src/activity/timeline/weekly-persist.ts
|
|
28632
28787
|
import { randomBytes as randomBytes3 } from "crypto";
|
|
28633
28788
|
import { mkdirSync, readFileSync as readFileSync2, renameSync, unlinkSync, writeFileSync } from "fs";
|
|
28634
|
-
import
|
|
28789
|
+
import path35 from "path";
|
|
28635
28790
|
var WEEKLY_SNAPSHOT_FORMAT_VERSION = 1;
|
|
28636
|
-
var WEEKLY_SNAPSHOT_DIR =
|
|
28791
|
+
var WEEKLY_SNAPSHOT_DIR = path35.join("activity", "weekly");
|
|
28637
28792
|
function requireToken(value, name) {
|
|
28638
28793
|
if (typeof value !== "string" || value.trim().length === 0) {
|
|
28639
28794
|
throw new TypeError(`${name} must be a non-empty string`);
|
|
@@ -28656,8 +28811,8 @@ function weeklySnapshotPath(input) {
|
|
|
28656
28811
|
const identity = hashActivityBody(
|
|
28657
28812
|
`${input.summary.weekStartUtc}\0${input.summary.weekEndUtc}\0${sourceRevision}\0${configHash}`
|
|
28658
28813
|
);
|
|
28659
|
-
return
|
|
28660
|
-
|
|
28814
|
+
return path35.join(
|
|
28815
|
+
path35.resolve(memoryDir),
|
|
28661
28816
|
WEEKLY_SNAPSHOT_DIR,
|
|
28662
28817
|
namespaceIdentityToken(namespace),
|
|
28663
28818
|
`${weekDate}--${identity}.json`
|
|
@@ -28687,7 +28842,7 @@ function persistWeeklySnapshot(input) {
|
|
|
28687
28842
|
throw error;
|
|
28688
28843
|
}
|
|
28689
28844
|
}
|
|
28690
|
-
mkdirSync(
|
|
28845
|
+
mkdirSync(path35.dirname(filePath), { recursive: true, mode: 448 });
|
|
28691
28846
|
const tmpPath = `${filePath}.${process.pid}.${randomBytes3(8).toString("hex")}.tmp`;
|
|
28692
28847
|
writeFileSync(tmpPath, text, { encoding: "utf8", mode: 384 });
|
|
28693
28848
|
try {
|
|
@@ -29339,7 +29494,7 @@ function selectRecapForDay(input) {
|
|
|
29339
29494
|
|
|
29340
29495
|
// src/activity/journal-read.ts
|
|
29341
29496
|
import { closeSync, constants as fsConstants, fstatSync, lstatSync, openSync, readFileSync as readFileSync3, realpathSync, statSync as statSync2 } from "fs";
|
|
29342
|
-
import
|
|
29497
|
+
import path36 from "path";
|
|
29343
29498
|
|
|
29344
29499
|
// src/activity/journal-section.ts
|
|
29345
29500
|
function parseAtxHeading(line) {
|
|
@@ -29530,8 +29685,8 @@ function readJournalForDate(input) {
|
|
|
29530
29685
|
const relative = resolveVaultNotePath(input.vault.dailyNotePath, input.date, {
|
|
29531
29686
|
timezone: input.timezone
|
|
29532
29687
|
});
|
|
29533
|
-
const root =
|
|
29534
|
-
const filePath =
|
|
29688
|
+
const root = path36.resolve(expandTildePath(input.vault.vaultPath));
|
|
29689
|
+
const filePath = path36.join(root, relative);
|
|
29535
29690
|
try {
|
|
29536
29691
|
const rootStat = lstatSync(root);
|
|
29537
29692
|
if (rootStat.isSymbolicLink() || !rootStat.isDirectory()) {
|
|
@@ -29540,8 +29695,8 @@ function readJournalForDate(input) {
|
|
|
29540
29695
|
} catch {
|
|
29541
29696
|
return { ok: true, exists: false, reason: "missing_file", filePath };
|
|
29542
29697
|
}
|
|
29543
|
-
const lexical =
|
|
29544
|
-
if (lexical.length === 0 || lexical === ".." || lexical.startsWith(`..${
|
|
29698
|
+
const lexical = path36.relative(root, filePath);
|
|
29699
|
+
if (lexical.length === 0 || lexical === ".." || lexical.startsWith(`..${path36.sep}`) || path36.isAbsolute(lexical)) {
|
|
29545
29700
|
return { ok: false, reason: "path_escape", filePath };
|
|
29546
29701
|
}
|
|
29547
29702
|
if (!containedBySymlinks(root, filePath)) {
|
|
@@ -29574,11 +29729,11 @@ function containedBySymlinks(root, dest) {
|
|
|
29574
29729
|
try {
|
|
29575
29730
|
if (statSync2(probe).isFile() || statSync2(probe).isDirectory()) {
|
|
29576
29731
|
const real = realpathSync(probe);
|
|
29577
|
-
return real === realRoot || real.startsWith(`${realRoot}${
|
|
29732
|
+
return real === realRoot || real.startsWith(`${realRoot}${path36.sep}`);
|
|
29578
29733
|
}
|
|
29579
29734
|
} catch {
|
|
29580
29735
|
}
|
|
29581
|
-
const parent =
|
|
29736
|
+
const parent = path36.dirname(probe);
|
|
29582
29737
|
if (parent === probe) return false;
|
|
29583
29738
|
probe = parent;
|
|
29584
29739
|
}
|
|
@@ -29589,15 +29744,15 @@ function symlinkRejected() {
|
|
|
29589
29744
|
return err;
|
|
29590
29745
|
}
|
|
29591
29746
|
function readVerifiedDailyNote(root, filePath) {
|
|
29592
|
-
const relative =
|
|
29593
|
-
const parts = relative.split(
|
|
29747
|
+
const relative = path36.relative(root, filePath);
|
|
29748
|
+
const parts = relative.split(path36.sep).filter((part) => part.length > 0 && part !== ".");
|
|
29594
29749
|
let cursor = root;
|
|
29595
29750
|
for (const part of parts) {
|
|
29596
|
-
cursor =
|
|
29751
|
+
cursor = path36.join(cursor, part);
|
|
29597
29752
|
const st = lstatSync(cursor);
|
|
29598
29753
|
if (st.isSymbolicLink()) throw symlinkRejected();
|
|
29599
29754
|
}
|
|
29600
|
-
const parent =
|
|
29755
|
+
const parent = path36.dirname(filePath);
|
|
29601
29756
|
const parentLstat = lstatSync(parent);
|
|
29602
29757
|
if (parentLstat.isSymbolicLink() || !parentLstat.isDirectory()) throw symlinkRejected();
|
|
29603
29758
|
const nofollow = fsConstants.O_NOFOLLOW ?? 0;
|
|
@@ -29621,7 +29776,7 @@ function readVerifiedDailyNote(root, filePath) {
|
|
|
29621
29776
|
try {
|
|
29622
29777
|
const fdPath = realpathSync(`/proc/self/fd/${fd}`);
|
|
29623
29778
|
const realRoot = realpathSync(root);
|
|
29624
|
-
if (fdPath !== realRoot && !fdPath.startsWith(`${realRoot}${
|
|
29779
|
+
if (fdPath !== realRoot && !fdPath.startsWith(`${realRoot}${path36.sep}`)) {
|
|
29625
29780
|
throw symlinkRejected();
|
|
29626
29781
|
}
|
|
29627
29782
|
} catch (err) {
|
|
@@ -29636,11 +29791,11 @@ function readVerifiedDailyNote(root, filePath) {
|
|
|
29636
29791
|
// src/activity/journal-state.ts
|
|
29637
29792
|
import { createHash as createHash11, randomBytes as randomBytes4 } from "crypto";
|
|
29638
29793
|
import { mkdirSync as mkdirSync2, readFileSync as readFileSync4, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
29639
|
-
import
|
|
29794
|
+
import path37 from "path";
|
|
29640
29795
|
var STATE_DIR_NAME = "state";
|
|
29641
29796
|
var STATE_FILE_NAME = "timeline.json";
|
|
29642
29797
|
function timelineStatePath(memoryDir) {
|
|
29643
|
-
return
|
|
29798
|
+
return path37.join(memoryDir, STATE_DIR_NAME, STATE_FILE_NAME);
|
|
29644
29799
|
}
|
|
29645
29800
|
function hashJournalText(text) {
|
|
29646
29801
|
return createHash11("sha256").update(text, "utf8").digest("hex");
|
|
@@ -29666,14 +29821,14 @@ function readTimelineState(memoryDir) {
|
|
|
29666
29821
|
}
|
|
29667
29822
|
function writeTimelineState(memoryDir, state) {
|
|
29668
29823
|
const filePath = timelineStatePath(memoryDir);
|
|
29669
|
-
mkdirSync2(
|
|
29824
|
+
mkdirSync2(path37.dirname(filePath), { recursive: true });
|
|
29670
29825
|
const tempPath = `${filePath}.${process.pid}.${randomBytes4(8).toString("hex")}.tmp`;
|
|
29671
29826
|
writeFileSync2(tempPath, `${JSON.stringify(state, null, 2)}
|
|
29672
29827
|
`);
|
|
29673
29828
|
renameSync2(tempPath, filePath);
|
|
29674
29829
|
}
|
|
29675
29830
|
function journalDateLockPath(memoryDir, date) {
|
|
29676
|
-
return
|
|
29831
|
+
return path37.join(memoryDir, STATE_DIR_NAME, `journal-extract-${date}.lock`);
|
|
29677
29832
|
}
|
|
29678
29833
|
function timelineStateLockPath(memoryDir) {
|
|
29679
29834
|
return `${timelineStatePath(memoryDir)}.lock`;
|
|
@@ -30381,7 +30536,7 @@ function normalizeDropKeys(keys) {
|
|
|
30381
30536
|
}
|
|
30382
30537
|
|
|
30383
30538
|
// src/activity/vault-wikilink.ts
|
|
30384
|
-
import
|
|
30539
|
+
import path38 from "path";
|
|
30385
30540
|
function formatVaultWikilink(notePath) {
|
|
30386
30541
|
if (typeof notePath !== "string" || notePath.trim().length === 0) {
|
|
30387
30542
|
throw new RangeError("Vault wikilink path must be a non-empty relative path.");
|
|
@@ -30389,7 +30544,7 @@ function formatVaultWikilink(notePath) {
|
|
|
30389
30544
|
if (notePath.includes("\n") || notePath.includes("\r")) {
|
|
30390
30545
|
throw new RangeError("Vault wikilink path must not contain newlines.");
|
|
30391
30546
|
}
|
|
30392
|
-
if (
|
|
30547
|
+
if (path38.posix.isAbsolute(notePath) || path38.win32.isAbsolute(notePath)) {
|
|
30393
30548
|
throw new RangeError("Vault wikilink path must be relative; absolute paths are rejected.");
|
|
30394
30549
|
}
|
|
30395
30550
|
if (notePath.split(/[\\/]/).some((segment) => segment === "..")) {
|
|
@@ -30411,7 +30566,7 @@ function stripVaultMdSuffix(notePath) {
|
|
|
30411
30566
|
}
|
|
30412
30567
|
|
|
30413
30568
|
// src/activity/vault-join.ts
|
|
30414
|
-
import
|
|
30569
|
+
import path39 from "path";
|
|
30415
30570
|
function joinVaultSegments(parts) {
|
|
30416
30571
|
if (parts.length === 0) {
|
|
30417
30572
|
throw new RangeError("Vault path parts must be a non-empty list.");
|
|
@@ -30426,7 +30581,7 @@ function joinVaultSegments(parts) {
|
|
|
30426
30581
|
if (part.includes("\n") || part.includes("\r")) {
|
|
30427
30582
|
throw new RangeError("Vault path part must not contain a newline.");
|
|
30428
30583
|
}
|
|
30429
|
-
if (
|
|
30584
|
+
if (path39.posix.isAbsolute(part) || path39.win32.isAbsolute(part)) {
|
|
30430
30585
|
throw new RangeError("Vault path part must be relative.");
|
|
30431
30586
|
}
|
|
30432
30587
|
if (part.split("/").includes("..")) {
|
|
@@ -30481,7 +30636,7 @@ function planVaultDryRun(inputs) {
|
|
|
30481
30636
|
// src/session-summaries/index.ts
|
|
30482
30637
|
import { createHash as createHash12 } from "crypto";
|
|
30483
30638
|
import { lstat as lstat3, mkdir as mkdir7, readFile as readFile9, readdir as readdir4, rename, rm, stat as stat4, writeFile as writeFile7 } from "fs/promises";
|
|
30484
|
-
import
|
|
30639
|
+
import path40 from "path";
|
|
30485
30640
|
|
|
30486
30641
|
// src/session-summaries/adapters.ts
|
|
30487
30642
|
var VALID_ROLES = /* @__PURE__ */ new Set(["user", "assistant", "tool", "system", "other"]);
|
|
@@ -30986,7 +31141,7 @@ function shortHash(value, length = 16) {
|
|
|
30986
31141
|
async function listTranscriptFiles(root, maxFiles) {
|
|
30987
31142
|
const out = [];
|
|
30988
31143
|
let truncated = false;
|
|
30989
|
-
const entrySortKey = (entryName, isDirectory) => isDirectory ? `${entryName}${
|
|
31144
|
+
const entrySortKey = (entryName, isDirectory) => isDirectory ? `${entryName}${path40.sep}` : entryName;
|
|
30990
31145
|
async function visit(dir) {
|
|
30991
31146
|
if (truncated) return;
|
|
30992
31147
|
const entries = (await readdir4(dir, { withFileTypes: true })).sort(
|
|
@@ -30996,13 +31151,13 @@ async function listTranscriptFiles(root, maxFiles) {
|
|
|
30996
31151
|
if (truncated) return;
|
|
30997
31152
|
if (entry.name.startsWith(".")) continue;
|
|
30998
31153
|
if (entry.isSymbolicLink()) continue;
|
|
30999
|
-
const fullPath =
|
|
31154
|
+
const fullPath = path40.join(dir, entry.name);
|
|
31000
31155
|
if (entry.isDirectory()) {
|
|
31001
31156
|
await visit(fullPath);
|
|
31002
31157
|
continue;
|
|
31003
31158
|
}
|
|
31004
31159
|
if (!entry.isFile()) continue;
|
|
31005
|
-
const ext =
|
|
31160
|
+
const ext = path40.extname(entry.name).toLowerCase();
|
|
31006
31161
|
if (!SUPPORTED_EXTENSIONS.has(ext)) continue;
|
|
31007
31162
|
out.push(fullPath);
|
|
31008
31163
|
if (out.length > maxFiles) {
|
|
@@ -31029,7 +31184,7 @@ function normalizeInputDir(inputDir) {
|
|
|
31029
31184
|
if (typeof inputDir !== "string" || inputDir.trim().length === 0) {
|
|
31030
31185
|
throw new Error("inputDir must be a non-empty string");
|
|
31031
31186
|
}
|
|
31032
|
-
return
|
|
31187
|
+
return path40.resolve(expandTildePath(inputDir.trim()));
|
|
31033
31188
|
}
|
|
31034
31189
|
function initRoleCounts() {
|
|
31035
31190
|
return {
|
|
@@ -31186,11 +31341,11 @@ async function collectLocalSessionSummaries(options) {
|
|
|
31186
31341
|
continue;
|
|
31187
31342
|
}
|
|
31188
31343
|
seenFileHashes.add(fileHash);
|
|
31189
|
-
const fileExtension =
|
|
31344
|
+
const fileExtension = path40.extname(filePath).toLowerCase();
|
|
31190
31345
|
const parsed = await adapter.parseFile(
|
|
31191
31346
|
{
|
|
31192
31347
|
content,
|
|
31193
|
-
fileName:
|
|
31348
|
+
fileName: path40.basename(filePath),
|
|
31194
31349
|
fileExtension,
|
|
31195
31350
|
fileRef: fileHash
|
|
31196
31351
|
},
|
|
@@ -31246,7 +31401,7 @@ async function collectLocalSessionSummaries(options) {
|
|
|
31246
31401
|
}
|
|
31247
31402
|
async function readRedactionConfig(pathLike) {
|
|
31248
31403
|
if (!pathLike) return void 0;
|
|
31249
|
-
const raw = await readFile9(
|
|
31404
|
+
const raw = await readFile9(path40.resolve(expandTildePath(pathLike)), "utf-8");
|
|
31250
31405
|
const parsed = JSON.parse(raw);
|
|
31251
31406
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
31252
31407
|
throw new Error("redaction config must be a JSON object");
|
|
@@ -31259,15 +31414,15 @@ function toJsonl(drafts) {
|
|
|
31259
31414
|
}
|
|
31260
31415
|
function defaultDraftOutputPath(memoryDir, generatedAt) {
|
|
31261
31416
|
const stamp = generatedAt.replace(/[:.]/g, "-");
|
|
31262
|
-
return
|
|
31263
|
-
|
|
31417
|
+
return path40.join(
|
|
31418
|
+
path40.resolve(expandTildePath(memoryDir)),
|
|
31264
31419
|
"state",
|
|
31265
31420
|
"session-summary-drafts",
|
|
31266
31421
|
`session-summaries-${stamp}.jsonl`
|
|
31267
31422
|
);
|
|
31268
31423
|
}
|
|
31269
31424
|
async function writeDrafts(filePath, drafts) {
|
|
31270
|
-
await mkdir7(
|
|
31425
|
+
await mkdir7(path40.dirname(filePath), { recursive: true });
|
|
31271
31426
|
const tempPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
|
|
31272
31427
|
try {
|
|
31273
31428
|
await writeFile7(tempPath, toJsonl(drafts), "utf-8");
|
|
@@ -31285,7 +31440,7 @@ async function runLocalSessionSummaryCliCommand(options) {
|
|
|
31285
31440
|
});
|
|
31286
31441
|
const wroteFiles = [];
|
|
31287
31442
|
if (options.output) {
|
|
31288
|
-
const outputPath =
|
|
31443
|
+
const outputPath = path40.resolve(expandTildePath(options.output));
|
|
31289
31444
|
await writeDrafts(outputPath, report.drafts);
|
|
31290
31445
|
wroteFiles.push(outputPath);
|
|
31291
31446
|
}
|
|
@@ -31320,19 +31475,19 @@ async function runLocalSessionSummaryCliCommand(options) {
|
|
|
31320
31475
|
|
|
31321
31476
|
// src/transfer/capsule-fork.ts
|
|
31322
31477
|
import { lstat as lstat4, mkdir as mkdir8, readFile as readFile10, realpath as realpath3, writeFile as writeFile8 } from "fs/promises";
|
|
31323
|
-
import
|
|
31478
|
+
import path41 from "path";
|
|
31324
31479
|
async function forkCapsule(opts) {
|
|
31325
31480
|
validateForkId(opts.forkId);
|
|
31326
|
-
const rootAbs =
|
|
31481
|
+
const rootAbs = path41.resolve(opts.targetRoot);
|
|
31327
31482
|
await assertIsDirectoryNotSymlink(rootAbs, "forkCapsule", "targetRoot");
|
|
31328
|
-
const forkDirAbs =
|
|
31483
|
+
const forkDirAbs = path41.join(rootAbs, "forks", opts.forkId);
|
|
31329
31484
|
const forkEntryExists = await pathEntryExists(forkDirAbs);
|
|
31330
31485
|
if (forkEntryExists) {
|
|
31331
31486
|
throw new Error(
|
|
31332
31487
|
`forkCapsule: fork path already exists \u2014 forkId "${opts.forkId}" is already in use at: ${forkDirAbs}`
|
|
31333
31488
|
);
|
|
31334
31489
|
}
|
|
31335
|
-
const archiveAbs =
|
|
31490
|
+
const archiveAbs = path41.resolve(opts.sourceArchive);
|
|
31336
31491
|
const importResult = await importCapsule({
|
|
31337
31492
|
archivePath: archiveAbs,
|
|
31338
31493
|
root: rootAbs,
|
|
@@ -31354,10 +31509,10 @@ async function forkCapsule(opts) {
|
|
|
31354
31509
|
importedRecords: importResult.imported.length,
|
|
31355
31510
|
skippedRecords: importResult.skipped.length
|
|
31356
31511
|
};
|
|
31357
|
-
const lineagePath =
|
|
31512
|
+
const lineagePath = path41.join(forkDirAbs, "lineage.json");
|
|
31358
31513
|
const rootReal = await realpath3(rootAbs);
|
|
31359
31514
|
await assertRealpathInsideRoot(rootReal, lineagePath, `forks/${opts.forkId}/lineage.json`, "forkCapsule");
|
|
31360
|
-
await mkdir8(
|
|
31515
|
+
await mkdir8(path41.dirname(lineagePath), { recursive: true });
|
|
31361
31516
|
await writeFile8(lineagePath, JSON.stringify(lineage, null, 2) + "\n", "utf-8");
|
|
31362
31517
|
return {
|
|
31363
31518
|
archivePath: archiveAbs,
|
|
@@ -31371,11 +31526,11 @@ async function readForkLineage(targetRoot, forkId) {
|
|
|
31371
31526
|
if (typeof forkId !== "string" || forkId.length === 0 || forkId.length > 64 || !CAPSULE_ID_PATTERN.test(forkId)) {
|
|
31372
31527
|
return null;
|
|
31373
31528
|
}
|
|
31374
|
-
const rootAbs =
|
|
31529
|
+
const rootAbs = path41.resolve(targetRoot);
|
|
31375
31530
|
const rootReal = await realpath3(rootAbs).catch(() => rootAbs);
|
|
31376
|
-
const lineagePath =
|
|
31377
|
-
const rel =
|
|
31378
|
-
if (rel.startsWith("..") ||
|
|
31531
|
+
const lineagePath = path41.join(rootReal, "forks", forkId, "lineage.json");
|
|
31532
|
+
const rel = path41.relative(rootReal, lineagePath);
|
|
31533
|
+
if (rel.startsWith("..") || path41.isAbsolute(rel)) {
|
|
31379
31534
|
return null;
|
|
31380
31535
|
}
|
|
31381
31536
|
if (!await isLineagePathContained(rootReal, lineagePath)) {
|
|
@@ -31416,19 +31571,19 @@ async function pathEntryExists(absPath) {
|
|
|
31416
31571
|
async function isLineagePathContained(rootReal, lineagePath) {
|
|
31417
31572
|
let existing = lineagePath;
|
|
31418
31573
|
const suffix = [];
|
|
31419
|
-
while (existing !==
|
|
31574
|
+
while (existing !== path41.dirname(existing)) {
|
|
31420
31575
|
const st = await lstat4(existing).catch(() => null);
|
|
31421
31576
|
if (st !== null) break;
|
|
31422
|
-
suffix.unshift(
|
|
31423
|
-
existing =
|
|
31577
|
+
suffix.unshift(path41.basename(existing));
|
|
31578
|
+
existing = path41.dirname(existing);
|
|
31424
31579
|
}
|
|
31425
31580
|
const existingReal = await realpath3(existing).catch(() => existing);
|
|
31426
|
-
const targetReal = suffix.length > 0 ?
|
|
31427
|
-
const rel =
|
|
31581
|
+
const targetReal = suffix.length > 0 ? path41.join(existingReal, ...suffix) : existingReal;
|
|
31582
|
+
const rel = path41.relative(rootReal, targetReal);
|
|
31428
31583
|
if (rel === "") return true;
|
|
31429
31584
|
if (rel === "..") return false;
|
|
31430
|
-
if (rel.startsWith(`..${
|
|
31431
|
-
if (
|
|
31585
|
+
if (rel.startsWith(`..${path41.sep}`)) return false;
|
|
31586
|
+
if (path41.isAbsolute(rel)) return false;
|
|
31432
31587
|
return true;
|
|
31433
31588
|
}
|
|
31434
31589
|
|
|
@@ -31621,4 +31776,4 @@ export {
|
|
|
31621
31776
|
qmdStartupCollectionChecksWithTimeout,
|
|
31622
31777
|
Orchestrator
|
|
31623
31778
|
};
|
|
31624
|
-
//# sourceMappingURL=chunk-
|
|
31779
|
+
//# sourceMappingURL=chunk-FAF4A76Q.js.map
|