@remnic/core 10.0.66 → 10.0.67
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-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-XMBDI725.js → chunk-LFYEQK45.js} +674 -518
- package/dist/chunk-LFYEQK45.js.map +1 -0
- 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/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 +141 -138
- 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 +89 -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,41 @@ 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 () => targetStorage.writeSealedMemory(factWriteEnvelope, {
|
|
8063
|
+
importance,
|
|
8064
|
+
supersedes,
|
|
8065
|
+
links: links.length > 0 ? links : void 0,
|
|
8066
|
+
intentGoal: inferredIntent?.goal,
|
|
8067
|
+
intentActionType: inferredIntent?.actionType,
|
|
8068
|
+
intentEntityTypes: inferredIntent?.entityTypes,
|
|
8069
|
+
memoryKind,
|
|
8070
|
+
...biTemporal ? { observedAt: biTemporal.observedAt, eventTimeSource: biTemporal.eventTimeSource, ...biTemporal.validUntil ? { invalidAt: biTemporal.validUntil } : {} } : {},
|
|
8071
|
+
contentHashSource: writeCategory === "fact" ? fact.content : void 0,
|
|
8072
|
+
// Faithfulness gate (issue #1576).
|
|
8073
|
+
...faithfulnessFm ? { faithfulness: faithfulnessFm } : {},
|
|
8074
|
+
...faithfulnessEnforceStatus ? { status: faithfulnessEnforceStatus } : {},
|
|
8075
|
+
// Claim-level provenance spans (issue #1575 PR 2). Carry verified
|
|
8076
|
+
// sources + the coarse strength tag from the extraction validator
|
|
8077
|
+
// through to frontmatter so they survive end-to-end.
|
|
8078
|
+
...fact.sources && fact.sources.length > 0 ? { sources: fact.sources } : {},
|
|
8079
|
+
...fact.provenance ? { provenance: fact.provenance } : {},
|
|
8080
|
+
// PR #2016: never defer inside the commit window (chunked-path
|
|
8081
|
+
// rule): a peer loading an authoritative index after the release
|
|
8082
|
+
// must see this hash, or its recheck misses and duplicates it.
|
|
8083
|
+
deferHashIndexSave: false,
|
|
8084
|
+
...factToolScoped ? { toolScoped: true } : {}
|
|
8085
|
+
})
|
|
8086
|
+
).catch(finalizeOnWindowFailure);
|
|
8087
|
+
if (factWriteOutcome.suppressed) {
|
|
8088
|
+
await backfillDuplicateTemporalBounds();
|
|
8089
|
+
log.info(`dedup: raced duplicate suppressed in fact-dedup window for storage ${targetStorage.dir}`);
|
|
8090
|
+
dedupedCount++;
|
|
8091
|
+
continue;
|
|
8092
|
+
}
|
|
8093
|
+
const factWrite = factWriteOutcome.result;
|
|
7940
8094
|
const memoryId = factWrite.id;
|
|
7941
8095
|
const tombstoneBlocked = factWrite.tombstoneBlocked;
|
|
7942
8096
|
const postWriteGuard = faithfulnessEnforceStatus === "pending_review" || tombstoneBlocked;
|
|
@@ -8251,7 +8405,7 @@ async function drainExtractionAndShutdownDependencyPropagation(extractionQueue,
|
|
|
8251
8405
|
// src/orchestration/dependency-propagation-delivery.ts
|
|
8252
8406
|
import { randomUUID } from "crypto";
|
|
8253
8407
|
import { readFile as readFile4, unlink } from "fs/promises";
|
|
8254
|
-
import
|
|
8408
|
+
import path8 from "path";
|
|
8255
8409
|
|
|
8256
8410
|
// src/orchestration/dependency-propagation-recovery-replay.ts
|
|
8257
8411
|
import { createHash as createHash4 } from "crypto";
|
|
@@ -8934,13 +9088,13 @@ var DependencyPropagationDelivery = class {
|
|
|
8934
9088
|
try {
|
|
8935
9089
|
const job = validateJob(JSON.parse(await this.readQueueFile(filePath)), status);
|
|
8936
9090
|
if (!job) {
|
|
8937
|
-
log.warn(`dependency propagation ignored invalid job file ${
|
|
9091
|
+
log.warn(`dependency propagation ignored invalid job file ${path8.basename(filePath)}`);
|
|
8938
9092
|
continue;
|
|
8939
9093
|
}
|
|
8940
9094
|
entries.push({ job, filePath });
|
|
8941
9095
|
} catch (error) {
|
|
8942
9096
|
if (error instanceof SyntaxError || isNotFound(error)) {
|
|
8943
|
-
log.warn(`dependency propagation ignored unreadable job file ${
|
|
9097
|
+
log.warn(`dependency propagation ignored unreadable job file ${path8.basename(filePath)}: ${error}`);
|
|
8944
9098
|
continue;
|
|
8945
9099
|
}
|
|
8946
9100
|
throw error;
|
|
@@ -9011,7 +9165,7 @@ var DependencyPropagationDelivery = class {
|
|
|
9011
9165
|
await this.writeQueueJob(targetPath, next);
|
|
9012
9166
|
const terminal = status === "completed" || status === "dead_letter" || status === "canceled";
|
|
9013
9167
|
for (const entry of entries) {
|
|
9014
|
-
if (
|
|
9168
|
+
if (path8.resolve(entry.filePath) === path8.resolve(targetPath)) continue;
|
|
9015
9169
|
await unlink(entry.filePath).catch((error) => {
|
|
9016
9170
|
if (isNotFound(error)) return;
|
|
9017
9171
|
if (terminal) {
|
|
@@ -9075,7 +9229,7 @@ var DependencyPropagationDelivery = class {
|
|
|
9075
9229
|
allowMissingDirectory: true
|
|
9076
9230
|
});
|
|
9077
9231
|
for (const filePath of files) {
|
|
9078
|
-
if (
|
|
9232
|
+
if (path8.basename(filePath, ".json") !== jobId) continue;
|
|
9079
9233
|
try {
|
|
9080
9234
|
await unlink(filePath);
|
|
9081
9235
|
} catch (error) {
|
|
@@ -9276,11 +9430,11 @@ function createDependencyPropagationReplayReconciliation(host) {
|
|
|
9276
9430
|
// src/orchestration/recall-internal.ts
|
|
9277
9431
|
import { createHash as createHash6 } from "crypto";
|
|
9278
9432
|
import { readFile as readFile5, stat, unlink as unlink2 } from "fs/promises";
|
|
9279
|
-
import
|
|
9433
|
+
import path13 from "path";
|
|
9280
9434
|
|
|
9281
9435
|
// src/orchestration/graph-path-state-loader.ts
|
|
9282
9436
|
import { lstat, opendir, realpath } from "fs/promises";
|
|
9283
|
-
import
|
|
9437
|
+
import path9 from "path";
|
|
9284
9438
|
function isArchivePathIndexUnavailable(index) {
|
|
9285
9439
|
return "unavailable" in index;
|
|
9286
9440
|
}
|
|
@@ -9299,11 +9453,11 @@ var GraphPathStateLoader = class {
|
|
|
9299
9453
|
openArchiveDirectory = opendir;
|
|
9300
9454
|
async readNode(storage, nodeId, deadlineAtMs, allowArchiveLookup) {
|
|
9301
9455
|
if (typeof deadlineAtMs === "number" && Date.now() >= deadlineAtMs) return null;
|
|
9302
|
-
const configuredStorageRoot =
|
|
9456
|
+
const configuredStorageRoot = path9.resolve(storage.dir);
|
|
9303
9457
|
const storageRoot = await realpath(configuredStorageRoot).catch(() => null);
|
|
9304
9458
|
if (!storageRoot || storageRoot !== configuredStorageRoot) return null;
|
|
9305
|
-
const logicalId =
|
|
9306
|
-
const directRelativePaths = [nodeId,
|
|
9459
|
+
const logicalId = path9.basename(nodeId, path9.extname(nodeId));
|
|
9460
|
+
const directRelativePaths = [nodeId, path9.join("cold", nodeId)];
|
|
9307
9461
|
let inactiveDirectMemory = null;
|
|
9308
9462
|
for (const relativePath of directRelativePaths) {
|
|
9309
9463
|
const safePath = await this.resolveContainedPath(storageRoot, relativePath);
|
|
@@ -9326,7 +9480,7 @@ var GraphPathStateLoader = class {
|
|
|
9326
9480
|
if (!archiveIndex || isArchivePathIndexUnavailable(archiveIndex) || typeof deadlineAtMs === "number" && Date.now() >= deadlineAtMs) {
|
|
9327
9481
|
return null;
|
|
9328
9482
|
}
|
|
9329
|
-
const archivePaths = archiveIndex.pathsByBasename.get(
|
|
9483
|
+
const archivePaths = archiveIndex.pathsByBasename.get(path9.basename(nodeId)) ?? [];
|
|
9330
9484
|
for (const archivePath of archivePaths) {
|
|
9331
9485
|
if (typeof deadlineAtMs === "number" && Date.now() >= deadlineAtMs) return null;
|
|
9332
9486
|
const memory = await storage.readMemoryByPath(archivePath);
|
|
@@ -9336,17 +9490,17 @@ var GraphPathStateLoader = class {
|
|
|
9336
9490
|
return null;
|
|
9337
9491
|
}
|
|
9338
9492
|
async resolveContainedPath(storageRoot, relativePath) {
|
|
9339
|
-
if (
|
|
9493
|
+
if (path9.isAbsolute(relativePath)) return null;
|
|
9340
9494
|
const rawSegments = relativePath.replace(/\\/g, "/").split("/");
|
|
9341
9495
|
if (rawSegments.includes("..")) return null;
|
|
9342
|
-
const candidate =
|
|
9343
|
-
const lexicalRelative =
|
|
9344
|
-
if (lexicalRelative.length > 0 && (lexicalRelative.startsWith("..") ||
|
|
9496
|
+
const candidate = path9.resolve(storageRoot, relativePath);
|
|
9497
|
+
const lexicalRelative = path9.relative(storageRoot, candidate);
|
|
9498
|
+
if (lexicalRelative.length > 0 && (lexicalRelative.startsWith("..") || path9.isAbsolute(lexicalRelative))) {
|
|
9345
9499
|
return null;
|
|
9346
9500
|
}
|
|
9347
9501
|
const canonical = await realpath(candidate).catch(() => candidate);
|
|
9348
|
-
const canonicalRelative =
|
|
9349
|
-
if (canonicalRelative.length > 0 && (canonicalRelative.startsWith("..") ||
|
|
9502
|
+
const canonicalRelative = path9.relative(storageRoot, canonical);
|
|
9503
|
+
if (canonicalRelative.length > 0 && (canonicalRelative.startsWith("..") || path9.isAbsolute(canonicalRelative))) {
|
|
9350
9504
|
return null;
|
|
9351
9505
|
}
|
|
9352
9506
|
return canonical;
|
|
@@ -9419,7 +9573,7 @@ var GraphPathStateLoader = class {
|
|
|
9419
9573
|
}
|
|
9420
9574
|
async buildArchivePathIndex(storageRoot, version) {
|
|
9421
9575
|
const pathsByBasename = /* @__PURE__ */ new Map();
|
|
9422
|
-
const archiveRoot =
|
|
9576
|
+
const archiveRoot = path9.join(storageRoot, "archive");
|
|
9423
9577
|
let archiveRootStatus;
|
|
9424
9578
|
try {
|
|
9425
9579
|
archiveRootStatus = await this.archiveLstat(archiveRoot);
|
|
@@ -9437,8 +9591,8 @@ var GraphPathStateLoader = class {
|
|
|
9437
9591
|
if (isArchiveScanAbsenceError(error)) return { version, pathsByBasename };
|
|
9438
9592
|
return null;
|
|
9439
9593
|
}
|
|
9440
|
-
const archiveRelative =
|
|
9441
|
-
if (archiveRelative.length > 0 && (archiveRelative.startsWith("..") ||
|
|
9594
|
+
const archiveRelative = path9.relative(storageRoot, canonicalArchiveRoot);
|
|
9595
|
+
if (archiveRelative.length > 0 && (archiveRelative.startsWith("..") || path9.isAbsolute(archiveRelative))) {
|
|
9442
9596
|
return { version, pathsByBasename };
|
|
9443
9597
|
}
|
|
9444
9598
|
const pending = [canonicalArchiveRoot];
|
|
@@ -9464,8 +9618,8 @@ var GraphPathStateLoader = class {
|
|
|
9464
9618
|
if (isArchiveScanAbsenceError(error)) continue;
|
|
9465
9619
|
return null;
|
|
9466
9620
|
}
|
|
9467
|
-
const currentRelative =
|
|
9468
|
-
if (currentRelative.length > 0 && (currentRelative.startsWith("..") ||
|
|
9621
|
+
const currentRelative = path9.relative(storageRoot, canonicalCurrent);
|
|
9622
|
+
if (currentRelative.length > 0 && (currentRelative.startsWith("..") || path9.isAbsolute(currentRelative))) {
|
|
9469
9623
|
continue;
|
|
9470
9624
|
}
|
|
9471
9625
|
let directory;
|
|
@@ -9482,7 +9636,7 @@ var GraphPathStateLoader = class {
|
|
|
9482
9636
|
return { version, unavailable: "oversized" };
|
|
9483
9637
|
}
|
|
9484
9638
|
if (entry.isSymbolicLink()) continue;
|
|
9485
|
-
const entryPath =
|
|
9639
|
+
const entryPath = path9.join(canonicalCurrent, entry.name);
|
|
9486
9640
|
if (entry.isDirectory()) {
|
|
9487
9641
|
pending.push(entryPath);
|
|
9488
9642
|
continue;
|
|
@@ -9498,8 +9652,8 @@ var GraphPathStateLoader = class {
|
|
|
9498
9652
|
if (isArchiveScanAbsenceError(error)) continue;
|
|
9499
9653
|
return null;
|
|
9500
9654
|
}
|
|
9501
|
-
const relative =
|
|
9502
|
-
if (relative.length > 0 && (relative.startsWith("..") ||
|
|
9655
|
+
const relative = path9.relative(storageRoot, canonical);
|
|
9656
|
+
if (relative.length > 0 && (relative.startsWith("..") || path9.isAbsolute(relative))) {
|
|
9503
9657
|
continue;
|
|
9504
9658
|
}
|
|
9505
9659
|
const paths = pathsByBasename.get(entry.name);
|
|
@@ -9525,7 +9679,7 @@ var GraphPathStateLoader = class {
|
|
|
9525
9679
|
// src/orchestration/graph-recall-coordinator.ts
|
|
9526
9680
|
import { createHash as createHash5 } from "crypto";
|
|
9527
9681
|
import { mkdir as mkdir3, writeFile as writeFile3 } from "fs/promises";
|
|
9528
|
-
import
|
|
9682
|
+
import path10 from "path";
|
|
9529
9683
|
function mergeGraphExpandedResults(primary, expanded) {
|
|
9530
9684
|
const mergedByNamespaceAndPath = /* @__PURE__ */ new Map();
|
|
9531
9685
|
for (const item of [...primary, ...expanded]) {
|
|
@@ -9542,11 +9696,11 @@ function mergeGraphExpandedResults(primary, expanded) {
|
|
|
9542
9696
|
return Array.from(mergedByNamespaceAndPath.values());
|
|
9543
9697
|
}
|
|
9544
9698
|
function graphPathRelativeToStorage(storageDir, candidatePath) {
|
|
9545
|
-
const absolutePath =
|
|
9546
|
-
const rel =
|
|
9699
|
+
const absolutePath = path10.isAbsolute(candidatePath) ? candidatePath : path10.resolve(storageDir, candidatePath);
|
|
9700
|
+
const rel = path10.relative(storageDir, absolutePath);
|
|
9547
9701
|
if (!rel || rel === ".") return null;
|
|
9548
9702
|
if (rel.startsWith("..")) return null;
|
|
9549
|
-
return rel.split(
|
|
9703
|
+
return rel.split(path10.sep).join("/");
|
|
9550
9704
|
}
|
|
9551
9705
|
function normalizeGraphActivationScore(score) {
|
|
9552
9706
|
const bounded = Number.isFinite(score) && score > 0 ? score : 0;
|
|
@@ -9646,7 +9800,7 @@ var GraphRecallCoordinator = class {
|
|
|
9646
9800
|
resolvedPath = resolvedCold.result.path;
|
|
9647
9801
|
resolvedResult = resolvedCold.result;
|
|
9648
9802
|
}
|
|
9649
|
-
if (!
|
|
9803
|
+
if (!path10.isAbsolute(resolvedPath)) {
|
|
9650
9804
|
resolvedAmbiguousSeeds.set(result.path, null);
|
|
9651
9805
|
return null;
|
|
9652
9806
|
}
|
|
@@ -9671,7 +9825,7 @@ var GraphRecallCoordinator = class {
|
|
|
9671
9825
|
}
|
|
9672
9826
|
continue;
|
|
9673
9827
|
}
|
|
9674
|
-
if (
|
|
9828
|
+
if (path10.isAbsolute(result.path)) {
|
|
9675
9829
|
const resolved = await resolveAmbiguousSeedOwner(result, null);
|
|
9676
9830
|
if (resolved) {
|
|
9677
9831
|
addResultForNamespace(resolved.namespace, resolved.result);
|
|
@@ -9717,7 +9871,7 @@ var GraphRecallCoordinator = class {
|
|
|
9717
9871
|
0
|
|
9718
9872
|
);
|
|
9719
9873
|
seedPaths.push(
|
|
9720
|
-
...seedRelativePaths.map((rel) =>
|
|
9874
|
+
...seedRelativePaths.map((rel) => path10.join(storage.dir, rel))
|
|
9721
9875
|
);
|
|
9722
9876
|
const seedSet = new Set(seedRelativePaths);
|
|
9723
9877
|
const nodeMemoryCache = /* @__PURE__ */ new Map();
|
|
@@ -9772,7 +9926,7 @@ var GraphRecallCoordinator = class {
|
|
|
9772
9926
|
path: memory.path,
|
|
9773
9927
|
score,
|
|
9774
9928
|
namespace,
|
|
9775
|
-
seed:
|
|
9929
|
+
seed: path10.resolve(storage.dir, candidate.seed),
|
|
9776
9930
|
hopDepth: candidate.hopDepth,
|
|
9777
9931
|
decayedWeight: candidate.decayedWeight,
|
|
9778
9932
|
graphType: candidate.graphType,
|
|
@@ -9804,7 +9958,7 @@ var GraphRecallCoordinator = class {
|
|
|
9804
9958
|
add(memory.frontmatter.id);
|
|
9805
9959
|
if (relativePath) {
|
|
9806
9960
|
add(relativePath);
|
|
9807
|
-
if (relativePath.endsWith(".md")) add(
|
|
9961
|
+
if (relativePath.endsWith(".md")) add(path10.basename(relativePath, ".md"));
|
|
9808
9962
|
}
|
|
9809
9963
|
return state;
|
|
9810
9964
|
};
|
|
@@ -9851,7 +10005,7 @@ var GraphRecallCoordinator = class {
|
|
|
9851
10005
|
path: memory.path,
|
|
9852
10006
|
score,
|
|
9853
10007
|
namespace,
|
|
9854
|
-
seed:
|
|
10008
|
+
seed: path10.resolve(storage.dir, candidate.seed),
|
|
9855
10009
|
hopDepth: candidate.hopDepth,
|
|
9856
10010
|
decayedWeight: candidate.decayedWeight,
|
|
9857
10011
|
graphType: candidate.graphType,
|
|
@@ -9894,12 +10048,12 @@ var GraphRecallCoordinator = class {
|
|
|
9894
10048
|
}
|
|
9895
10049
|
async recordLastGraphRecallSnapshot(options) {
|
|
9896
10050
|
try {
|
|
9897
|
-
const snapshotPath =
|
|
10051
|
+
const snapshotPath = path10.join(
|
|
9898
10052
|
options.storage.dir,
|
|
9899
10053
|
"state",
|
|
9900
10054
|
"last_graph_recall.json"
|
|
9901
10055
|
);
|
|
9902
|
-
await mkdir3(
|
|
10056
|
+
await mkdir3(path10.dirname(snapshotPath), { recursive: true });
|
|
9903
10057
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
9904
10058
|
const totalSeedCount = options.seedPaths.length;
|
|
9905
10059
|
const totalExpandedCount = options.expandedPaths.length;
|
|
@@ -10199,11 +10353,11 @@ async function appendEpisodicContextSection(deps, options) {
|
|
|
10199
10353
|
}
|
|
10200
10354
|
|
|
10201
10355
|
// src/orchestration/recall-profile-storage.ts
|
|
10202
|
-
import
|
|
10356
|
+
import path11 from "path";
|
|
10203
10357
|
function resolveCompositeProfileStorage(options) {
|
|
10204
10358
|
const { profileStorages, memoryDir } = options;
|
|
10205
10359
|
const emptyProfileStorage = new Proxy(
|
|
10206
|
-
{ dir:
|
|
10360
|
+
{ dir: path11.join(memoryDir, ".empty-scope-profile") },
|
|
10207
10361
|
{
|
|
10208
10362
|
get(target, prop) {
|
|
10209
10363
|
if (prop in target) return Reflect.get(target, prop);
|
|
@@ -10351,7 +10505,7 @@ function resolveCompositeProfileStorage(options) {
|
|
|
10351
10505
|
}
|
|
10352
10506
|
|
|
10353
10507
|
// src/orchestration/recall-recognition-search.ts
|
|
10354
|
-
import
|
|
10508
|
+
import path12 from "path";
|
|
10355
10509
|
async function fetchQmdMemoryResultsWithRecognitionSwap(deps, prompt, qmdFetchLimit, qmdHybridFetchLimit, options) {
|
|
10356
10510
|
if (deps.config.recallRecognitionTier !== true || options.collection || options.namespacesEnabled !== true) {
|
|
10357
10511
|
return deps.fetchQmdMemoryResultsWithArtifactTopUp(
|
|
@@ -10438,7 +10592,7 @@ async function hitsFromIds(namespace, storage, index, ids) {
|
|
|
10438
10592
|
for (const [offset, id] of ids.entries()) {
|
|
10439
10593
|
const absPath = pathsById.get(id)?.[0];
|
|
10440
10594
|
if (!absPath) continue;
|
|
10441
|
-
const rel =
|
|
10595
|
+
const rel = path12.relative(storage.dir, absPath).split(path12.sep).join("/");
|
|
10442
10596
|
if (!rel || rel.startsWith("..")) continue;
|
|
10443
10597
|
hits.push({
|
|
10444
10598
|
docid: `${namespace}:${rel}`,
|
|
@@ -10686,7 +10840,7 @@ var RecallInternalCoordinator = class {
|
|
|
10686
10840
|
const graphExpandedResultPaths = /* @__PURE__ */ new Set();
|
|
10687
10841
|
const graphSourceLabelsForPath = (resultPath) => {
|
|
10688
10842
|
const labels = [];
|
|
10689
|
-
const normalizedPath = resultPath.split(
|
|
10843
|
+
const normalizedPath = resultPath.split(path13.sep).join("/");
|
|
10690
10844
|
const isEntityPath = normalizedPath.startsWith("entities/") || normalizedPath.includes("/entities/");
|
|
10691
10845
|
if (graphBaselinePaths.has(resultPath)) labels.push("baseline");
|
|
10692
10846
|
if (graphExpandedResultPaths.has(resultPath))
|
|
@@ -12223,11 +12377,11 @@ ${formatted}`;
|
|
|
12223
12377
|
if (!resolveRecallAuxiliaryCapabilities(this.deps.config).compactionReset) return null;
|
|
12224
12378
|
const workspaceDir = compactionWorkspaceDir || this.deps.config.workspaceDir || defaultWorkspaceDir();
|
|
12225
12379
|
const safeSessionKey = sanitizeSessionKeyForFilename(effectiveSessionKey);
|
|
12226
|
-
const signalPath =
|
|
12380
|
+
const signalPath = path13.join(
|
|
12227
12381
|
workspaceDir,
|
|
12228
12382
|
`.compaction-reset-signal-${safeSessionKey}`
|
|
12229
12383
|
);
|
|
12230
|
-
const bootPath =
|
|
12384
|
+
const bootPath = path13.join(workspaceDir, "BOOT.md");
|
|
12231
12385
|
try {
|
|
12232
12386
|
const signalStat = await stat(signalPath).catch(() => null);
|
|
12233
12387
|
if (!signalStat) return null;
|
|
@@ -14507,10 +14661,10 @@ ${tmtNode.summary}`
|
|
|
14507
14661
|
|
|
14508
14662
|
// src/orchestration/recall-search-pipeline.ts
|
|
14509
14663
|
import { createHash as createHash7 } from "crypto";
|
|
14510
|
-
import
|
|
14664
|
+
import path15 from "path";
|
|
14511
14665
|
|
|
14512
14666
|
// src/orchestration/recall-search-prefilter.ts
|
|
14513
|
-
import
|
|
14667
|
+
import path14 from "path";
|
|
14514
14668
|
async function fetchActiveArtifactsForNamespace(deps, namespace, prompt, targetCount, options = {}) {
|
|
14515
14669
|
const storage = await deps.storageRouter.storageFor(namespace);
|
|
14516
14670
|
let fetchLimit = computeArtifactCandidateFetchLimit(targetCount);
|
|
@@ -14639,7 +14793,7 @@ async function searchEmbeddingFallback(deps, query, limit) {
|
|
|
14639
14793
|
if (hits.length === 0) return [];
|
|
14640
14794
|
const results = [];
|
|
14641
14795
|
for (const hit of hits) {
|
|
14642
|
-
const fullPath =
|
|
14796
|
+
const fullPath = path14.isAbsolute(hit.path) ? hit.path : path14.join(deps.config.memoryDir, hit.path);
|
|
14643
14797
|
const memory = await deps.storage.readMemoryByPath(fullPath);
|
|
14644
14798
|
if (!memory) continue;
|
|
14645
14799
|
results.push({
|
|
@@ -15017,7 +15171,7 @@ var RecallSearchPipelineCoordinator = class {
|
|
|
15017
15171
|
const storage = await this.deps.storageRouter.storageFor(namespace);
|
|
15018
15172
|
const storageDir = typeof storage.dir === "string" && storage.dir ? storage.dir : null;
|
|
15019
15173
|
if (!storageDir) continue;
|
|
15020
|
-
const recallRoot =
|
|
15174
|
+
const recallRoot = path15.resolve(storageDir);
|
|
15021
15175
|
if (seenRecallRoots.has(recallRoot)) continue;
|
|
15022
15176
|
seenRecallRoots.add(recallRoot);
|
|
15023
15177
|
recallRoots.push(recallRoot);
|
|
@@ -15041,8 +15195,8 @@ var RecallSearchPipelineCoordinator = class {
|
|
|
15041
15195
|
if (resolvedCold) scopedResults.push(resolvedCold.result);
|
|
15042
15196
|
continue;
|
|
15043
15197
|
}
|
|
15044
|
-
if (
|
|
15045
|
-
if (recallRoots.some((recallRoot) => isPathInsideStorageRoot(recallRoot,
|
|
15198
|
+
if (path15.isAbsolute(result.path)) {
|
|
15199
|
+
if (recallRoots.some((recallRoot) => isPathInsideStorageRoot(recallRoot, path15.resolve(result.path)))) {
|
|
15046
15200
|
scopedResults.push(result);
|
|
15047
15201
|
}
|
|
15048
15202
|
continue;
|
|
@@ -15763,8 +15917,10 @@ var ExtractionDrain = class {
|
|
|
15763
15917
|
* persist step ends the host's preemption registration, so the drain registers
|
|
15764
15918
|
* it again before every later chunk; a fail-closed flush can then abort the
|
|
15765
15919
|
* next chunk's model request instead of waiting behind the whole window.
|
|
15920
|
+
* `preemptHandle`: the queue task's own preemption slot (per task, so two
|
|
15921
|
+
* concurrent automatic extractions cannot clobber each other's registration).
|
|
15766
15922
|
*/
|
|
15767
|
-
async run(turns, runOptions, preemptable = false) {
|
|
15923
|
+
async run(turns, runOptions, preemptable = false, preemptHandle) {
|
|
15768
15924
|
const budgetChars = this.deps.extractionWindowBudgetChars?.() ?? Number.POSITIVE_INFINITY;
|
|
15769
15925
|
const chunkable = runOptions.clearBufferAfterExtraction && !runOptions.forceExtractionAttempt && !runOptions.failOnExtractionFailure && !turns.some((turn) => turn.acceptedCapture === true) && Number.isFinite(budgetChars) && budgetChars > 0;
|
|
15770
15926
|
const chunks = chunkable ? chunkExtractionWindow(turns, budgetChars) : [];
|
|
@@ -15789,7 +15945,7 @@ var ExtractionDrain = class {
|
|
|
15789
15945
|
if (preemptable && position > 0) {
|
|
15790
15946
|
const local = new AbortController();
|
|
15791
15947
|
preempt = local;
|
|
15792
|
-
|
|
15948
|
+
preemptHandle?.arm(() => local.abort(preemptedExtractionError()));
|
|
15793
15949
|
chunkOptions = {
|
|
15794
15950
|
...chunkOptions,
|
|
15795
15951
|
abortSignal: runOptions.abortSignal ? AbortSignal.any([runOptions.abortSignal, local.signal]) : local.signal
|
|
@@ -15851,8 +16007,8 @@ var ExtractionDrain = class {
|
|
|
15851
16007
|
const reason = `dropped after ${dropAfter} repeated extraction failures (last result: status=${result.status} reason=${result.reason ?? "n/a"})`;
|
|
15852
16008
|
try {
|
|
15853
16009
|
const storage = await this.deps.getStorage();
|
|
15854
|
-
const
|
|
15855
|
-
log.warn(`buffer[${bufferKey}]: dropping ${chunk.length} turns \u2014 ${reason}; copy saved to ${
|
|
16010
|
+
const path42 = await storage.saveDroppedExtractionChunk(bufferKey, reason, chunk);
|
|
16011
|
+
log.warn(`buffer[${bufferKey}]: dropping ${chunk.length} turns \u2014 ${reason}; copy saved to ${path42}`);
|
|
15856
16012
|
} catch (err) {
|
|
15857
16013
|
log.warn(
|
|
15858
16014
|
`buffer[${bufferKey}]: could not save the dropped-chunk recovery copy; keeping the chunk in the buffer: ${describeError(err)}`
|
|
@@ -16420,8 +16576,8 @@ var TurnIngestionCoordinator = class {
|
|
|
16420
16576
|
}
|
|
16421
16577
|
if (settled) return;
|
|
16422
16578
|
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) => {
|
|
16579
|
+
const accepted = this.deps.extractionQueueCoordinator.enqueue(async (preemptHandle) => {
|
|
16580
|
+
await this.deps.extractionQueueCoordinator.runPreemptable(preemptHandle, preemptable, options.abortSignal, async (abortSignal) => {
|
|
16425
16581
|
if (settled) return;
|
|
16426
16582
|
if (typeof extractionDeadlineMs === "number" && extractionDeadlineMs <= Date.now()) {
|
|
16427
16583
|
settleTask(new ExtractionDeadlineError("queue_wait"));
|
|
@@ -16527,14 +16683,14 @@ var TurnIngestionCoordinator = class {
|
|
|
16527
16683
|
deadlineMs: extractionDeadlineMs,
|
|
16528
16684
|
bufferKey,
|
|
16529
16685
|
onDurableCommit: options.onDurableCommit,
|
|
16530
|
-
onBeforePersist: () =>
|
|
16686
|
+
onBeforePersist: () => preemptHandle?.disarm(),
|
|
16531
16687
|
abortSignal,
|
|
16532
16688
|
failOnExtractionFailure: options.failOnExtractionFailure === true,
|
|
16533
16689
|
writeNamespaceOverride: options.writeNamespaceOverride,
|
|
16534
16690
|
principalOverride: options.principalOverride,
|
|
16535
16691
|
scopeProfileWritePlan: effectiveScopePlan,
|
|
16536
16692
|
forceExtractionAttempt: options.forceExtractionAttempt === true
|
|
16537
|
-
}, preemptable);
|
|
16693
|
+
}, preemptable, preemptHandle);
|
|
16538
16694
|
settleTask(void 0, result);
|
|
16539
16695
|
} catch (err) {
|
|
16540
16696
|
const reason2 = abortSignal.reason;
|
|
@@ -16544,7 +16700,7 @@ var TurnIngestionCoordinator = class {
|
|
|
16544
16700
|
}
|
|
16545
16701
|
}
|
|
16546
16702
|
});
|
|
16547
|
-
}, { front: options.preemptRunning === true });
|
|
16703
|
+
}, { front: options.preemptRunning === true, key: bufferKey });
|
|
16548
16704
|
if (!accepted) {
|
|
16549
16705
|
settleTask(new Error("extraction queue is stopped"));
|
|
16550
16706
|
return;
|
|
@@ -16623,7 +16779,7 @@ var TurnIngestionCoordinator = class {
|
|
|
16623
16779
|
|
|
16624
16780
|
// src/orchestration/recall-introspection.ts
|
|
16625
16781
|
import { mkdir as mkdir5, readFile as readFile7, writeFile as writeFile5 } from "fs/promises";
|
|
16626
|
-
import
|
|
16782
|
+
import path17 from "path";
|
|
16627
16783
|
|
|
16628
16784
|
// src/taxonomy/default-taxonomy.ts
|
|
16629
16785
|
var DEFAULT_TAXONOMY = {
|
|
@@ -16746,7 +16902,7 @@ function generateResolverDocument(taxonomy) {
|
|
|
16746
16902
|
|
|
16747
16903
|
// src/taxonomy/taxonomy-loader.ts
|
|
16748
16904
|
import { readFile as readFile6, mkdir as mkdir4, writeFile as writeFile4 } from "fs/promises";
|
|
16749
|
-
import
|
|
16905
|
+
import path16 from "path";
|
|
16750
16906
|
var TAXONOMY_DIR = ".taxonomy";
|
|
16751
16907
|
var TAXONOMY_FILE = "taxonomy.json";
|
|
16752
16908
|
var MAX_SLUG_LENGTH = 32;
|
|
@@ -16844,7 +17000,7 @@ function validateTaxonomy(taxonomy) {
|
|
|
16844
17000
|
}
|
|
16845
17001
|
}
|
|
16846
17002
|
async function loadTaxonomy(memoryDir) {
|
|
16847
|
-
const taxonomyPath =
|
|
17003
|
+
const taxonomyPath = path16.join(memoryDir, TAXONOMY_DIR, TAXONOMY_FILE);
|
|
16848
17004
|
let raw;
|
|
16849
17005
|
try {
|
|
16850
17006
|
raw = await readFile6(taxonomyPath, "utf-8");
|
|
@@ -16894,16 +17050,16 @@ async function loadTaxonomy(memoryDir) {
|
|
|
16894
17050
|
}
|
|
16895
17051
|
async function saveTaxonomy(memoryDir, taxonomy) {
|
|
16896
17052
|
validateTaxonomy(taxonomy);
|
|
16897
|
-
const dir =
|
|
17053
|
+
const dir = path16.join(memoryDir, TAXONOMY_DIR);
|
|
16898
17054
|
await mkdir4(dir, { recursive: true });
|
|
16899
|
-
const filePath =
|
|
17055
|
+
const filePath = path16.join(dir, TAXONOMY_FILE);
|
|
16900
17056
|
await writeFile4(filePath, JSON.stringify(taxonomy, null, 2) + "\n", "utf-8");
|
|
16901
17057
|
}
|
|
16902
17058
|
function getTaxonomyDir(memoryDir) {
|
|
16903
|
-
return
|
|
17059
|
+
return path16.join(memoryDir, TAXONOMY_DIR);
|
|
16904
17060
|
}
|
|
16905
17061
|
function getTaxonomyFilePath(memoryDir) {
|
|
16906
|
-
return
|
|
17062
|
+
return path16.join(memoryDir, TAXONOMY_DIR, TAXONOMY_FILE);
|
|
16907
17063
|
}
|
|
16908
17064
|
|
|
16909
17065
|
// src/orchestration/recall-introspection.ts
|
|
@@ -16927,7 +17083,7 @@ var RecallIntrospectionCoordinator = class {
|
|
|
16927
17083
|
}
|
|
16928
17084
|
async getLastGraphRecallSnapshot(namespace) {
|
|
16929
17085
|
const storage = await this.deps.getStorage(namespace);
|
|
16930
|
-
const snapshotPath =
|
|
17086
|
+
const snapshotPath = path17.join(
|
|
16931
17087
|
storage.dir,
|
|
16932
17088
|
"state",
|
|
16933
17089
|
"last_graph_recall.json"
|
|
@@ -16966,7 +17122,7 @@ var RecallIntrospectionCoordinator = class {
|
|
|
16966
17122
|
}
|
|
16967
17123
|
async getLastIntentSnapshot(namespace) {
|
|
16968
17124
|
const storage = await this.deps.getStorage(namespace);
|
|
16969
|
-
const snapshotPath =
|
|
17125
|
+
const snapshotPath = path17.join(storage.dir, "state", "last_intent.json");
|
|
16970
17126
|
try {
|
|
16971
17127
|
const raw = await readFile7(snapshotPath, "utf-8");
|
|
16972
17128
|
const parsed = JSON.parse(raw);
|
|
@@ -16999,7 +17155,7 @@ var RecallIntrospectionCoordinator = class {
|
|
|
16999
17155
|
}
|
|
17000
17156
|
async getLastQmdRecallSnapshot(namespace) {
|
|
17001
17157
|
const storage = await this.deps.getStorage(namespace);
|
|
17002
|
-
const snapshotPath =
|
|
17158
|
+
const snapshotPath = path17.join(
|
|
17003
17159
|
storage.dir,
|
|
17004
17160
|
"state",
|
|
17005
17161
|
"last_qmd_recall.json"
|
|
@@ -17291,12 +17447,12 @@ var RecallIntrospectionCoordinator = class {
|
|
|
17291
17447
|
}
|
|
17292
17448
|
async recordLastIntentSnapshot(options) {
|
|
17293
17449
|
try {
|
|
17294
|
-
const snapshotPath =
|
|
17450
|
+
const snapshotPath = path17.join(
|
|
17295
17451
|
options.storage.dir,
|
|
17296
17452
|
"state",
|
|
17297
17453
|
"last_intent.json"
|
|
17298
17454
|
);
|
|
17299
|
-
await mkdir5(
|
|
17455
|
+
await mkdir5(path17.dirname(snapshotPath), { recursive: true });
|
|
17300
17456
|
await writeFile5(
|
|
17301
17457
|
snapshotPath,
|
|
17302
17458
|
JSON.stringify(options.snapshot, null, 2),
|
|
@@ -17308,12 +17464,12 @@ var RecallIntrospectionCoordinator = class {
|
|
|
17308
17464
|
}
|
|
17309
17465
|
async recordLastQmdRecallSnapshot(options) {
|
|
17310
17466
|
try {
|
|
17311
|
-
const snapshotPath =
|
|
17467
|
+
const snapshotPath = path17.join(
|
|
17312
17468
|
options.storage.dir,
|
|
17313
17469
|
"state",
|
|
17314
17470
|
"last_qmd_recall.json"
|
|
17315
17471
|
);
|
|
17316
|
-
await mkdir5(
|
|
17472
|
+
await mkdir5(path17.dirname(snapshotPath), { recursive: true });
|
|
17317
17473
|
await writeFile5(
|
|
17318
17474
|
snapshotPath,
|
|
17319
17475
|
JSON.stringify(options.snapshot, null, 2),
|
|
@@ -17328,8 +17484,8 @@ var RecallIntrospectionCoordinator = class {
|
|
|
17328
17484
|
const stateDir = await this.deps.resolveStateDirForNamespace(
|
|
17329
17485
|
options.namespace
|
|
17330
17486
|
);
|
|
17331
|
-
const snapshotPath =
|
|
17332
|
-
await mkdir5(
|
|
17487
|
+
const snapshotPath = path17.join(stateDir, "last_intent.json");
|
|
17488
|
+
await mkdir5(path17.dirname(snapshotPath), { recursive: true });
|
|
17333
17489
|
await writeFile5(
|
|
17334
17490
|
snapshotPath,
|
|
17335
17491
|
JSON.stringify(options.snapshot, null, 2),
|
|
@@ -17343,7 +17499,7 @@ var RecallIntrospectionCoordinator = class {
|
|
|
17343
17499
|
|
|
17344
17500
|
// src/orchestration/orchestrator-init.ts
|
|
17345
17501
|
import { readdir as readdir2, stat as stat2, unlink as unlink3 } from "fs/promises";
|
|
17346
|
-
import
|
|
17502
|
+
import path18 from "path";
|
|
17347
17503
|
|
|
17348
17504
|
// src/orchestration/startup-collection-checks.ts
|
|
17349
17505
|
async function startupDiscoveryWithTimeout(discover, configuredFallback, timeoutMs = qmdStartupCollectionCheckTimeoutMs()) {
|
|
@@ -17679,7 +17835,7 @@ var OrchestratorInitCoordinator = class {
|
|
|
17679
17835
|
const files = await readdir2(wsDir).catch(() => []);
|
|
17680
17836
|
for (const f of files) {
|
|
17681
17837
|
if (!f.startsWith(".compaction-reset-signal-")) continue;
|
|
17682
|
-
const fp =
|
|
17838
|
+
const fp = path18.join(wsDir, f);
|
|
17683
17839
|
const s = await stat2(fp).catch(() => null);
|
|
17684
17840
|
if (s && Date.now() - s.mtimeMs >= COMPACTION_SIGNAL_MAX_AGE_MS) {
|
|
17685
17841
|
await unlink3(fp).catch(() => {
|
|
@@ -18099,11 +18255,11 @@ var OrchestratorInitCoordinator = class {
|
|
|
18099
18255
|
};
|
|
18100
18256
|
|
|
18101
18257
|
// src/orchestration/persistence-index.ts
|
|
18102
|
-
import
|
|
18258
|
+
import path20 from "path";
|
|
18103
18259
|
|
|
18104
18260
|
// src/orchestration/recall-recognition-index.ts
|
|
18105
18261
|
import { promises as fsp } from "fs";
|
|
18106
|
-
import
|
|
18262
|
+
import path19 from "path";
|
|
18107
18263
|
import { setTimeout as delay } from "timers/promises";
|
|
18108
18264
|
var writeChains = /* @__PURE__ */ new Map();
|
|
18109
18265
|
var LOCK_POLL_MS = 10;
|
|
@@ -18154,7 +18310,7 @@ async function withRecognitionIndexLock(memoryDir, op) {
|
|
|
18154
18310
|
} catch (error) {
|
|
18155
18311
|
const code = error?.code;
|
|
18156
18312
|
if (code === "ENOENT") {
|
|
18157
|
-
await fsp.mkdir(
|
|
18313
|
+
await fsp.mkdir(path19.dirname(lockDir), { recursive: true }).catch(() => void 0);
|
|
18158
18314
|
continue;
|
|
18159
18315
|
}
|
|
18160
18316
|
if (code !== "EEXIST") throw error;
|
|
@@ -18405,7 +18561,7 @@ var PersistenceIndexCoordinator = class {
|
|
|
18405
18561
|
const allMems = allMemsForGraph ?? [];
|
|
18406
18562
|
for (const m of allMems) {
|
|
18407
18563
|
if (m.frontmatter.entityRef === entityRef) {
|
|
18408
|
-
const rel =
|
|
18564
|
+
const rel = path20.relative(storage.dir, m.path);
|
|
18409
18565
|
if (rel !== memoryRelPath) entitySiblings.push(rel);
|
|
18410
18566
|
}
|
|
18411
18567
|
}
|
|
@@ -18601,7 +18757,7 @@ var PersistenceIndexCoordinator = class {
|
|
|
18601
18757
|
|
|
18602
18758
|
// src/orchestration/workspace-ops.ts
|
|
18603
18759
|
import { lstat as lstat2, mkdir as mkdir6, readFile as readFile8, readdir as readdir3, realpath as realpath2, writeFile as writeFile6 } from "fs/promises";
|
|
18604
|
-
import
|
|
18760
|
+
import path21 from "path";
|
|
18605
18761
|
|
|
18606
18762
|
// src/maintenance/pattern-reinforcement.ts
|
|
18607
18763
|
function patternReinforcementKey(content) {
|
|
@@ -20505,8 +20661,8 @@ var MeetingsService = class {
|
|
|
20505
20661
|
// src/orchestration/workspace-ops.ts
|
|
20506
20662
|
var MEETINGS_BUILD_DEBOUNCE_MS = 5e3;
|
|
20507
20663
|
function matchesMemoryPath(candidatePath, requestedPath, memoryDir) {
|
|
20508
|
-
const normalizedCandidate =
|
|
20509
|
-
return normalizedCandidate ===
|
|
20664
|
+
const normalizedCandidate = path21.resolve(candidatePath);
|
|
20665
|
+
return normalizedCandidate === path21.resolve(requestedPath) || normalizedCandidate === path21.resolve(memoryDir, requestedPath);
|
|
20510
20666
|
}
|
|
20511
20667
|
function accessTrackingPathCandidates(storageDir, memoryPath) {
|
|
20512
20668
|
const candidates = qmdResultPathCandidates(storageDir, memoryPath);
|
|
@@ -20514,12 +20670,12 @@ function accessTrackingPathCandidates(storageDir, memoryPath) {
|
|
|
20514
20670
|
if (!parts) return candidates;
|
|
20515
20671
|
candidates.push(
|
|
20516
20672
|
...qmdResultPathCandidates(storageDir, parts.relativePath),
|
|
20517
|
-
...qmdResultPathCandidates(
|
|
20673
|
+
...qmdResultPathCandidates(path21.join(storageDir, "cold"), parts.relativePath)
|
|
20518
20674
|
);
|
|
20519
20675
|
return [...new Set(candidates)];
|
|
20520
20676
|
}
|
|
20521
20677
|
function canonicalMemoryPath(memoryPath, memoryDir) {
|
|
20522
|
-
return
|
|
20678
|
+
return path21.resolve(path21.isAbsolute(memoryPath) ? memoryPath : path21.resolve(memoryDir, memoryPath));
|
|
20523
20679
|
}
|
|
20524
20680
|
var WorkspaceOpsCoordinator = class {
|
|
20525
20681
|
constructor(deps) {
|
|
@@ -20601,15 +20757,15 @@ var WorkspaceOpsCoordinator = class {
|
|
|
20601
20757
|
this.deps.lastFileHygieneRunAtMs = now;
|
|
20602
20758
|
if (hygiene.rotateEnabled) {
|
|
20603
20759
|
for (const rel of hygiene.rotatePaths) {
|
|
20604
|
-
const abs =
|
|
20760
|
+
const abs = path21.isAbsolute(rel) ? rel : path21.join(this.deps.config.workspaceDir, rel);
|
|
20605
20761
|
try {
|
|
20606
20762
|
const raw = await readFile8(abs, "utf-8");
|
|
20607
20763
|
if (raw.length > hygiene.rotateMaxBytes) {
|
|
20608
|
-
const archiveDir =
|
|
20764
|
+
const archiveDir = path21.join(
|
|
20609
20765
|
this.deps.config.workspaceDir,
|
|
20610
20766
|
hygiene.archiveDir
|
|
20611
20767
|
);
|
|
20612
|
-
const base =
|
|
20768
|
+
const base = path21.basename(abs);
|
|
20613
20769
|
const prefix = base.toUpperCase().replace(/\.MD$/i, "").replace(/[^A-Z0-9]+/g, "-") || "FILE";
|
|
20614
20770
|
const { newContent } = await rotateMarkdownFileToArchive({
|
|
20615
20771
|
filePath: abs,
|
|
@@ -20634,8 +20790,8 @@ var WorkspaceOpsCoordinator = class {
|
|
|
20634
20790
|
log.warn(w.message);
|
|
20635
20791
|
}
|
|
20636
20792
|
if (hygiene.warningsLogEnabled && warnings.length > 0) {
|
|
20637
|
-
const fp =
|
|
20638
|
-
await mkdir6(
|
|
20793
|
+
const fp = path21.join(this.deps.config.memoryDir, hygiene.warningsLogPath);
|
|
20794
|
+
await mkdir6(path21.dirname(fp), { recursive: true });
|
|
20639
20795
|
const stamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
20640
20796
|
const block = `
|
|
20641
20797
|
|
|
@@ -20675,7 +20831,7 @@ var WorkspaceOpsCoordinator = class {
|
|
|
20675
20831
|
for (const categoryDir of RECALL_FALLBACK_DIRS) {
|
|
20676
20832
|
if (memoryRootReal === null) break;
|
|
20677
20833
|
for (const date of datesToScan) {
|
|
20678
|
-
const dateDir =
|
|
20834
|
+
const dateDir = path21.join(storage.dir, categoryDir, date);
|
|
20679
20835
|
try {
|
|
20680
20836
|
const dirStat = await lstat2(dateDir);
|
|
20681
20837
|
if (dirStat.isSymbolicLink() || !dirStat.isDirectory()) continue;
|
|
@@ -20684,7 +20840,7 @@ var WorkspaceOpsCoordinator = class {
|
|
|
20684
20840
|
for (const entry of entries) {
|
|
20685
20841
|
if (entry.isSymbolicLink()) continue;
|
|
20686
20842
|
if (!entry.name.endsWith(".md")) continue;
|
|
20687
|
-
const fullPath =
|
|
20843
|
+
const fullPath = path21.join(dateDir, entry.name);
|
|
20688
20844
|
try {
|
|
20689
20845
|
assertPathInsideRoot(memoryRootReal, await realpath2(fullPath), fullPath);
|
|
20690
20846
|
const memory = await storage.readMemoryByPath(fullPath);
|
|
@@ -20706,13 +20862,13 @@ var WorkspaceOpsCoordinator = class {
|
|
|
20706
20862
|
return a.frontmatter.created < b.frontmatter.created ? -1 : 1;
|
|
20707
20863
|
});
|
|
20708
20864
|
const hourlySummaries = [];
|
|
20709
|
-
const hourlyBaseDir =
|
|
20865
|
+
const hourlyBaseDir = path21.join(storage.dir, "summaries", "hourly");
|
|
20710
20866
|
try {
|
|
20711
20867
|
const sessionKeys = await readdir3(hourlyBaseDir, { withFileTypes: true });
|
|
20712
20868
|
for (const sk of sessionKeys) {
|
|
20713
20869
|
if (!sk.isDirectory()) continue;
|
|
20714
20870
|
for (const date of datesToScan) {
|
|
20715
|
-
const summaryFile =
|
|
20871
|
+
const summaryFile = path21.join(hourlyBaseDir, sk.name, `${date}.md`);
|
|
20716
20872
|
try {
|
|
20717
20873
|
const raw = await readFile8(summaryFile, "utf-8");
|
|
20718
20874
|
const filtered = filterHourlySummaryMarkdownForLocalDay(
|
|
@@ -21189,18 +21345,18 @@ ${reflectionsContent.trim()}
|
|
|
21189
21345
|
// src/orchestration/namespace-read-fanout.ts
|
|
21190
21346
|
import { existsSync, readFileSync } from "fs";
|
|
21191
21347
|
import { stat as stat3 } from "fs/promises";
|
|
21192
|
-
import
|
|
21348
|
+
import path23 from "path";
|
|
21193
21349
|
|
|
21194
21350
|
// src/orchestration/orchestrator-namespace-scope.ts
|
|
21195
|
-
import
|
|
21351
|
+
import path22 from "path";
|
|
21196
21352
|
function computeSemanticDedupScope(targetStorage, config) {
|
|
21197
21353
|
if (!resolveNamespaceCapabilities(config).namespaces) return {};
|
|
21198
|
-
const memoryDir =
|
|
21199
|
-
const storageDir =
|
|
21354
|
+
const memoryDir = path22.resolve(config.memoryDir);
|
|
21355
|
+
const storageDir = path22.resolve(targetStorage.dir);
|
|
21200
21356
|
if (storageDir === memoryDir) {
|
|
21201
21357
|
return { pathExcludePrefixes: ["namespaces/"] };
|
|
21202
21358
|
}
|
|
21203
|
-
let rel =
|
|
21359
|
+
let rel = path22.relative(memoryDir, storageDir);
|
|
21204
21360
|
if (!rel || rel.startsWith("..")) {
|
|
21205
21361
|
log.debug(
|
|
21206
21362
|
`semantic dedup: target storage dir ${storageDir} is outside memoryDir ${memoryDir}; scoping lookup to absolute path prefix`
|
|
@@ -21253,7 +21409,7 @@ var NamespaceReadFanoutCoordinator = class {
|
|
|
21253
21409
|
loadNamespaceStorageDirHintsFromCatalog() {
|
|
21254
21410
|
if (this.deps.namespaceStorageDirHintsLoaded || !this.deps.namespaceCatalog.enabled) return;
|
|
21255
21411
|
this.deps.namespaceStorageDirHintsLoaded = true;
|
|
21256
|
-
const catalogPath =
|
|
21412
|
+
const catalogPath = path23.join(this.deps.config.memoryDir, "state", "namespaces.jsonl");
|
|
21257
21413
|
if (!existsSync(catalogPath)) return;
|
|
21258
21414
|
let body;
|
|
21259
21415
|
try {
|
|
@@ -21290,7 +21446,7 @@ var NamespaceReadFanoutCoordinator = class {
|
|
|
21290
21446
|
if (!this.deps.storageDirMatchesNamespaceHint(record.namespace, record.storageDir)) {
|
|
21291
21447
|
continue;
|
|
21292
21448
|
}
|
|
21293
|
-
const resolvedStorageDir =
|
|
21449
|
+
const resolvedStorageDir = path23.resolve(record.storageDir);
|
|
21294
21450
|
const current = preferredByStorageDir.get(resolvedStorageDir);
|
|
21295
21451
|
preferredByStorageDir.set(
|
|
21296
21452
|
resolvedStorageDir,
|
|
@@ -21475,12 +21631,12 @@ var NamespaceReadFanoutCoordinator = class {
|
|
|
21475
21631
|
}
|
|
21476
21632
|
async resolveStateDirForNamespace(namespace) {
|
|
21477
21633
|
if (!resolveNamespaceCapabilities(this.deps.config).namespaces) {
|
|
21478
|
-
return
|
|
21634
|
+
return path23.join(this.deps.config.memoryDir, "state");
|
|
21479
21635
|
}
|
|
21480
21636
|
if (namespace !== this.deps.config.defaultNamespace) {
|
|
21481
|
-
return
|
|
21637
|
+
return path23.join(this.deps.config.memoryDir, "namespaces", namespace, "state");
|
|
21482
21638
|
}
|
|
21483
|
-
const candidate =
|
|
21639
|
+
const candidate = path23.join(
|
|
21484
21640
|
this.deps.config.memoryDir,
|
|
21485
21641
|
"namespaces",
|
|
21486
21642
|
this.deps.config.defaultNamespace
|
|
@@ -21488,11 +21644,11 @@ var NamespaceReadFanoutCoordinator = class {
|
|
|
21488
21644
|
try {
|
|
21489
21645
|
const candidateStat = await stat3(candidate);
|
|
21490
21646
|
if (candidateStat.isDirectory()) {
|
|
21491
|
-
return
|
|
21647
|
+
return path23.join(candidate, "state");
|
|
21492
21648
|
}
|
|
21493
21649
|
} catch {
|
|
21494
21650
|
}
|
|
21495
|
-
return
|
|
21651
|
+
return path23.join(this.deps.config.memoryDir, "state");
|
|
21496
21652
|
}
|
|
21497
21653
|
namespaceFromPath(p) {
|
|
21498
21654
|
if (!resolveNamespaceCapabilities(this.deps.config).namespaces) return this.deps.config.defaultNamespace;
|
|
@@ -21972,7 +22128,7 @@ var Orchestrator = class {
|
|
|
21972
22128
|
if (this.destroyed) throw new Error("orchestrator has been destroyed");
|
|
21973
22129
|
if (!this._dependencyPropagationDelivery) {
|
|
21974
22130
|
this._dependencyPropagationDelivery = new DependencyPropagationDelivery({
|
|
21975
|
-
queueRoot:
|
|
22131
|
+
queueRoot: path24.join(this.config.memoryDir, "state", "dependency-propagation"),
|
|
21976
22132
|
config: this.config,
|
|
21977
22133
|
extraction: this.extraction,
|
|
21978
22134
|
getStorage: (namespace) => this.getStorage(namespace),
|
|
@@ -22323,7 +22479,7 @@ var Orchestrator = class {
|
|
|
22323
22479
|
const defaultNs = normalizeNamespaceIdentity(this.config.defaultNamespace);
|
|
22324
22480
|
if (ns !== defaultNs && !isSafeRouteNamespace(ns)) return;
|
|
22325
22481
|
if (!this.storageDirMatchesNamespaceHint(ns, storageDir)) return;
|
|
22326
|
-
const resolvedStorageDir =
|
|
22482
|
+
const resolvedStorageDir = path24.resolve(storageDir);
|
|
22327
22483
|
let hints = this.namespaceStorageDirHints.get(resolvedStorageDir);
|
|
22328
22484
|
if (!hints) {
|
|
22329
22485
|
hints = /* @__PURE__ */ new Set();
|
|
@@ -22334,21 +22490,21 @@ var Orchestrator = class {
|
|
|
22334
22490
|
storageDirMatchesNamespaceHint(namespace, storageDir) {
|
|
22335
22491
|
const ns = normalizeNamespaceIdentity(namespace);
|
|
22336
22492
|
if (!ns) return false;
|
|
22337
|
-
const resolvedStorageDir =
|
|
22338
|
-
const resolvedMemoryDir =
|
|
22493
|
+
const resolvedStorageDir = path24.resolve(storageDir);
|
|
22494
|
+
const resolvedMemoryDir = path24.resolve(this.config.memoryDir);
|
|
22339
22495
|
const defaultNs = normalizeNamespaceIdentity(this.config.defaultNamespace);
|
|
22340
22496
|
if (resolvedStorageDir === resolvedMemoryDir) return ns === defaultNs;
|
|
22341
|
-
const resolvedNamespacesDir =
|
|
22497
|
+
const resolvedNamespacesDir = path24.join(resolvedMemoryDir, "namespaces");
|
|
22342
22498
|
if (!isPathInsideStorageRoot(resolvedNamespacesDir, resolvedStorageDir)) return false;
|
|
22343
|
-
const rawRoot =
|
|
22344
|
-
const tokenRoot =
|
|
22499
|
+
const rawRoot = path24.resolve(resolvedNamespacesDir, ns);
|
|
22500
|
+
const tokenRoot = path24.resolve(resolvedNamespacesDir, namespaceIdentityToken(ns));
|
|
22345
22501
|
return resolvedStorageDir === rawRoot || resolvedStorageDir === tokenRoot;
|
|
22346
22502
|
}
|
|
22347
22503
|
namespaceStorageDirHintOwnershipRank(record, resolvedStorageDir, configured) {
|
|
22348
|
-
if (resolvedStorageDir ===
|
|
22504
|
+
if (resolvedStorageDir === path24.resolve(this.config.memoryDir)) {
|
|
22349
22505
|
return record.namespace === normalizeNamespaceIdentity(this.config.defaultNamespace) ? 0 : 3;
|
|
22350
22506
|
}
|
|
22351
|
-
const leaf =
|
|
22507
|
+
const leaf = path24.basename(resolvedStorageDir);
|
|
22352
22508
|
const tokenOwnsRoot = namespaceIdentityToken(record.namespace) === leaf;
|
|
22353
22509
|
if (tokenOwnsRoot && configured.has(record.namespace)) return 0;
|
|
22354
22510
|
if (record.namespace === leaf) return 1;
|
|
@@ -22489,7 +22645,7 @@ var Orchestrator = class {
|
|
|
22489
22645
|
StorageManager.setOkfConformanceDefault(config.memoryDir, config.okf?.conformanceEnabled);
|
|
22490
22646
|
this.profiler = new ProfilingCollector({
|
|
22491
22647
|
enabled: resolvePipelineProcessingCapabilities(this.config).profiling,
|
|
22492
|
-
storageDir: config.profilingStorageDir ||
|
|
22648
|
+
storageDir: config.profilingStorageDir || path24.join(config.memoryDir, "profiling"),
|
|
22493
22649
|
maxTraces: config.profilingMaxTraces
|
|
22494
22650
|
});
|
|
22495
22651
|
this.namespaceCatalog = new NamespaceCatalog(config);
|
|
@@ -22567,7 +22723,7 @@ var Orchestrator = class {
|
|
|
22567
22723
|
bindStorage(this.storage, this.config.defaultNamespace);
|
|
22568
22724
|
this.storageRouter.onStorageCreated = bindStorage;
|
|
22569
22725
|
this.storageRouter.forEachCachedStorage(bindStorage);
|
|
22570
|
-
this.extractionQueueCoordinator = new ExtractionQueueCoordinator();
|
|
22726
|
+
this.extractionQueueCoordinator = new ExtractionQueueCoordinator(config.extractionQueueConcurrency);
|
|
22571
22727
|
this.recallResultFormatter = new RecallResultFormatter(this.config);
|
|
22572
22728
|
const conversationIndexRuntime = createConversationIndexRuntime(config, {
|
|
22573
22729
|
getQmd: () => this.conversationQmd,
|
|
@@ -22580,7 +22736,7 @@ var Orchestrator = class {
|
|
|
22580
22736
|
this.compounding = resolveConsolidationCapabilities(config).compounding ? new CompoundingEngine(config, this.storage) : void 0;
|
|
22581
22737
|
this.buffer = new SmartBuffer(config, this.storage);
|
|
22582
22738
|
this.transcript = new TranscriptManager(config);
|
|
22583
|
-
this.conversationIndexDir =
|
|
22739
|
+
this.conversationIndexDir = path24.join(
|
|
22584
22740
|
config.memoryDir,
|
|
22585
22741
|
"conversation-index",
|
|
22586
22742
|
"chunks"
|
|
@@ -22731,7 +22887,7 @@ var Orchestrator = class {
|
|
|
22731
22887
|
getHandleHistory: () => this.handleHistory
|
|
22732
22888
|
});
|
|
22733
22889
|
this.threading = new ThreadingManager(
|
|
22734
|
-
|
|
22890
|
+
path24.join(config.memoryDir, "threads"),
|
|
22735
22891
|
config.threadingGapMinutes
|
|
22736
22892
|
);
|
|
22737
22893
|
const lifecycleCaps = resolveMemoryLifecycleCapabilities(config);
|
|
@@ -24845,9 +25001,9 @@ function readStructuralSymbol(entry) {
|
|
|
24845
25001
|
const rec = entry;
|
|
24846
25002
|
const symbol = typeof rec.symbol === "string" ? rec.symbol.trim() : "";
|
|
24847
25003
|
if (!symbol) return null;
|
|
24848
|
-
const
|
|
25004
|
+
const path42 = typeof rec.path === "string" && rec.path.length > 0 ? rec.path : void 0;
|
|
24849
25005
|
const kind = typeof rec.kind === "string" && rec.kind.length > 0 ? rec.kind : void 0;
|
|
24850
|
-
const item =
|
|
25006
|
+
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
25007
|
return item;
|
|
24852
25008
|
}
|
|
24853
25009
|
function classifySpawnError(err) {
|
|
@@ -24921,7 +25077,7 @@ var DEFAULT_GRACE_PERIOD_DAYS = 7;
|
|
|
24921
25077
|
|
|
24922
25078
|
// src/binary-lifecycle/backend.ts
|
|
24923
25079
|
import fsp2 from "fs/promises";
|
|
24924
|
-
import
|
|
25080
|
+
import path25 from "path";
|
|
24925
25081
|
var FilesystemBackend = class {
|
|
24926
25082
|
type = "filesystem";
|
|
24927
25083
|
basePath;
|
|
@@ -24929,19 +25085,19 @@ var FilesystemBackend = class {
|
|
|
24929
25085
|
if (!basePath || basePath.trim().length === 0) {
|
|
24930
25086
|
throw new Error("FilesystemBackend requires a non-empty basePath");
|
|
24931
25087
|
}
|
|
24932
|
-
this.basePath =
|
|
25088
|
+
this.basePath = path25.resolve(basePath);
|
|
24933
25089
|
}
|
|
24934
25090
|
resolveRemotePath(remotePath) {
|
|
24935
|
-
const resolved =
|
|
24936
|
-
const relative =
|
|
24937
|
-
if (relative === ".." || relative.startsWith(`..${
|
|
25091
|
+
const resolved = path25.isAbsolute(remotePath) ? path25.resolve(remotePath) : path25.resolve(this.basePath, remotePath);
|
|
25092
|
+
const relative = path25.relative(this.basePath, resolved);
|
|
25093
|
+
if (relative === ".." || relative.startsWith(`..${path25.sep}`) || path25.isAbsolute(relative)) {
|
|
24938
25094
|
throw new Error(`FilesystemBackend remotePath escapes basePath: ${JSON.stringify(remotePath)}`);
|
|
24939
25095
|
}
|
|
24940
25096
|
return resolved;
|
|
24941
25097
|
}
|
|
24942
25098
|
isInsideBase(candidate, realBase) {
|
|
24943
|
-
const relative =
|
|
24944
|
-
return relative === "" || relative !== ".." && !relative.startsWith(`..${
|
|
25099
|
+
const relative = path25.relative(realBase, candidate);
|
|
25100
|
+
return relative === "" || relative !== ".." && !relative.startsWith(`..${path25.sep}`) && !path25.isAbsolute(relative);
|
|
24945
25101
|
}
|
|
24946
25102
|
async realBasePathIfExists() {
|
|
24947
25103
|
try {
|
|
@@ -24970,13 +25126,13 @@ var FilesystemBackend = class {
|
|
|
24970
25126
|
}
|
|
24971
25127
|
async ensureSafeParentDirectory(dest) {
|
|
24972
25128
|
const realBase = await this.ensureBaseDirectory();
|
|
24973
|
-
const destDir =
|
|
24974
|
-
const relativeDir =
|
|
24975
|
-
const segments = relativeDir === "" ? [] : relativeDir.split(
|
|
25129
|
+
const destDir = path25.dirname(dest);
|
|
25130
|
+
const relativeDir = path25.relative(this.basePath, destDir);
|
|
25131
|
+
const segments = relativeDir === "" ? [] : relativeDir.split(path25.sep);
|
|
24976
25132
|
let current = this.basePath;
|
|
24977
25133
|
for (const segment of segments) {
|
|
24978
25134
|
if (segment === "." || segment === "") continue;
|
|
24979
|
-
current =
|
|
25135
|
+
current = path25.join(current, segment);
|
|
24980
25136
|
try {
|
|
24981
25137
|
const stat5 = await fsp2.lstat(current);
|
|
24982
25138
|
if (stat5.isSymbolicLink()) {
|
|
@@ -25004,13 +25160,13 @@ var FilesystemBackend = class {
|
|
|
25004
25160
|
if (realBase === null) {
|
|
25005
25161
|
return null;
|
|
25006
25162
|
}
|
|
25007
|
-
const destDir =
|
|
25008
|
-
const relativeDir =
|
|
25009
|
-
const segments = relativeDir === "" ? [] : relativeDir.split(
|
|
25163
|
+
const destDir = path25.dirname(dest);
|
|
25164
|
+
const relativeDir = path25.relative(this.basePath, destDir);
|
|
25165
|
+
const segments = relativeDir === "" ? [] : relativeDir.split(path25.sep);
|
|
25010
25166
|
let current = this.basePath;
|
|
25011
25167
|
for (const segment of segments) {
|
|
25012
25168
|
if (segment === "." || segment === "") continue;
|
|
25013
|
-
current =
|
|
25169
|
+
current = path25.join(current, segment);
|
|
25014
25170
|
let stat5;
|
|
25015
25171
|
try {
|
|
25016
25172
|
stat5 = await fsp2.lstat(current);
|
|
@@ -25058,7 +25214,7 @@ var FilesystemBackend = class {
|
|
|
25058
25214
|
return dest;
|
|
25059
25215
|
}
|
|
25060
25216
|
async upload(localPath, remotePath) {
|
|
25061
|
-
if (
|
|
25217
|
+
if (path25.isAbsolute(remotePath)) {
|
|
25062
25218
|
throw new Error(`FilesystemBackend upload remotePath must be relative: ${JSON.stringify(remotePath)}`);
|
|
25063
25219
|
}
|
|
25064
25220
|
const dest = this.resolveRemotePath(remotePath);
|
|
@@ -25131,7 +25287,7 @@ function createBackend(cfg) {
|
|
|
25131
25287
|
|
|
25132
25288
|
// src/binary-lifecycle/scanner.ts
|
|
25133
25289
|
import fsp3 from "fs/promises";
|
|
25134
|
-
import
|
|
25290
|
+
import path26 from "path";
|
|
25135
25291
|
import crypto from "crypto";
|
|
25136
25292
|
function matchesPatterns(filename, patterns) {
|
|
25137
25293
|
const lower = filename.toLowerCase();
|
|
@@ -25156,8 +25312,8 @@ async function scanForBinaries(memoryDir, config, manifest) {
|
|
|
25156
25312
|
return;
|
|
25157
25313
|
}
|
|
25158
25314
|
for (const entry of entries) {
|
|
25159
|
-
const fullPath =
|
|
25160
|
-
const relativePath =
|
|
25315
|
+
const fullPath = path26.join(dir, entry.name);
|
|
25316
|
+
const relativePath = path26.relative(memoryDir, fullPath).split(path26.sep).join("/");
|
|
25161
25317
|
if (entry.isDirectory()) {
|
|
25162
25318
|
if (entry.name === ".binary-lifecycle") continue;
|
|
25163
25319
|
await walk(fullPath);
|
|
@@ -25197,15 +25353,15 @@ async function hashFile(filePath) {
|
|
|
25197
25353
|
|
|
25198
25354
|
// src/binary-lifecycle/manifest.ts
|
|
25199
25355
|
import fsp4 from "fs/promises";
|
|
25200
|
-
import
|
|
25356
|
+
import path27 from "path";
|
|
25201
25357
|
import crypto2 from "crypto";
|
|
25202
25358
|
var MANIFEST_DIR = ".binary-lifecycle";
|
|
25203
25359
|
var MANIFEST_FILE = "manifest.json";
|
|
25204
25360
|
function manifestDir(memoryDir) {
|
|
25205
|
-
return
|
|
25361
|
+
return path27.join(memoryDir, MANIFEST_DIR);
|
|
25206
25362
|
}
|
|
25207
25363
|
function manifestPath(memoryDir) {
|
|
25208
|
-
return
|
|
25364
|
+
return path27.join(memoryDir, MANIFEST_DIR, MANIFEST_FILE);
|
|
25209
25365
|
}
|
|
25210
25366
|
async function readManifest(memoryDir) {
|
|
25211
25367
|
const filePath = manifestPath(memoryDir);
|
|
@@ -25257,13 +25413,13 @@ function emptyManifest() {
|
|
|
25257
25413
|
|
|
25258
25414
|
// src/binary-lifecycle/pipeline.ts
|
|
25259
25415
|
import fsp5 from "fs/promises";
|
|
25260
|
-
import
|
|
25416
|
+
import path28 from "path";
|
|
25261
25417
|
import crypto3 from "crypto";
|
|
25262
25418
|
var historicalIdCache = new HistoricalEntityCanonicalIdCache();
|
|
25263
25419
|
function isRecallCorpusMarkdown(mdPath, memoryDir) {
|
|
25264
|
-
const rel =
|
|
25265
|
-
if (rel.startsWith("..") ||
|
|
25266
|
-
const top = rel.split(
|
|
25420
|
+
const rel = path28.relative(memoryDir, mdPath);
|
|
25421
|
+
if (rel.startsWith("..") || path28.isAbsolute(rel)) return false;
|
|
25422
|
+
const top = rel.split(path28.sep)[0];
|
|
25267
25423
|
return RECALL_FALLBACK_DIRS.includes(top);
|
|
25268
25424
|
}
|
|
25269
25425
|
async function hashFile2(filePath) {
|
|
@@ -25287,13 +25443,13 @@ function escapeRegex(s) {
|
|
|
25287
25443
|
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
25288
25444
|
}
|
|
25289
25445
|
function resolveManifestAssetPath(memoryDir, originalPath) {
|
|
25290
|
-
if (originalPath.length === 0 || originalPath.includes("\0") || originalPath.includes("\\") ||
|
|
25446
|
+
if (originalPath.length === 0 || originalPath.includes("\0") || originalPath.includes("\\") || path28.isAbsolute(originalPath) || path28.win32.isAbsolute(originalPath)) {
|
|
25291
25447
|
return null;
|
|
25292
25448
|
}
|
|
25293
|
-
const memoryRoot =
|
|
25294
|
-
const fullPath =
|
|
25295
|
-
const relative =
|
|
25296
|
-
if (relative === "" || relative === ".." || relative.startsWith(`..${
|
|
25449
|
+
const memoryRoot = path28.resolve(memoryDir);
|
|
25450
|
+
const fullPath = path28.resolve(memoryRoot, originalPath);
|
|
25451
|
+
const relative = path28.relative(memoryRoot, fullPath);
|
|
25452
|
+
if (relative === "" || relative === ".." || relative.startsWith(`..${path28.sep}`) || path28.isAbsolute(relative)) {
|
|
25297
25453
|
return null;
|
|
25298
25454
|
}
|
|
25299
25455
|
return fullPath;
|
|
@@ -25304,7 +25460,7 @@ function validateBinaryLifecycleConfig(config) {
|
|
|
25304
25460
|
}
|
|
25305
25461
|
}
|
|
25306
25462
|
function remotePathForAsset(backend, relPath) {
|
|
25307
|
-
const normalized = relPath.split(
|
|
25463
|
+
const normalized = relPath.split(path28.sep).join("/");
|
|
25308
25464
|
if (backend.type === "filesystem") {
|
|
25309
25465
|
return `.binary-lifecycle/mirrors/${normalized}`;
|
|
25310
25466
|
}
|
|
@@ -25317,11 +25473,11 @@ async function stageMirror(memoryDir, newPaths, backend, assets, log2, dryRun) {
|
|
|
25317
25473
|
let mirrored = 0;
|
|
25318
25474
|
const errors = [];
|
|
25319
25475
|
for (const relPath of newPaths) {
|
|
25320
|
-
const fullPath =
|
|
25476
|
+
const fullPath = path28.join(memoryDir, relPath);
|
|
25321
25477
|
try {
|
|
25322
25478
|
const stat5 = await fsp5.stat(fullPath);
|
|
25323
25479
|
const contentHash = await hashFile2(fullPath);
|
|
25324
|
-
const ext =
|
|
25480
|
+
const ext = path28.extname(relPath);
|
|
25325
25481
|
const mimeType = guessMimeType(ext);
|
|
25326
25482
|
const remotePath = remotePathForAsset(backend, relPath);
|
|
25327
25483
|
let backendLocation = remotePath;
|
|
@@ -25472,7 +25628,7 @@ async function stageRedirect(memoryDir, assets, log2, dryRun, readMarkdownFile,
|
|
|
25472
25628
|
for (const update of updates) {
|
|
25473
25629
|
try {
|
|
25474
25630
|
await withRawEntityPageMutation(memoryDir, update.mdPath, async () => {
|
|
25475
|
-
const stateDir =
|
|
25631
|
+
const stateDir = path28.join(memoryDir, "state");
|
|
25476
25632
|
const kind = classifyEntityRefWritePath(memoryDir, update.mdPath);
|
|
25477
25633
|
if (kind === "memory") {
|
|
25478
25634
|
const idsAtWrite = historicalIdCache.get(stateDir);
|
|
@@ -25565,10 +25721,10 @@ async function countRemainingLocalReferences(memoryDir, asset, assetAbsolute, md
|
|
|
25565
25721
|
return { remaining, errors };
|
|
25566
25722
|
}
|
|
25567
25723
|
function markdownReferencePattern(asset, assetAbsolute, mdPath) {
|
|
25568
|
-
const mdDir =
|
|
25724
|
+
const mdDir = path28.dirname(mdPath);
|
|
25569
25725
|
const candidates = /* @__PURE__ */ new Set();
|
|
25570
25726
|
const addCandidate = (candidate) => {
|
|
25571
|
-
const normalized = candidate.split(
|
|
25727
|
+
const normalized = candidate.split(path28.sep).join("/");
|
|
25572
25728
|
if (normalized.length === 0) return;
|
|
25573
25729
|
candidates.add(normalized);
|
|
25574
25730
|
const isParentTraversal = normalized === ".." || normalized.startsWith("../");
|
|
@@ -25576,10 +25732,10 @@ function markdownReferencePattern(asset, assetAbsolute, mdPath) {
|
|
|
25576
25732
|
candidates.add(`./${normalized}`);
|
|
25577
25733
|
}
|
|
25578
25734
|
};
|
|
25579
|
-
addCandidate(
|
|
25580
|
-
const originalPath = asset.originalPath.split(
|
|
25581
|
-
const originalAsFileRelative =
|
|
25582
|
-
if (
|
|
25735
|
+
addCandidate(path28.relative(mdDir, assetAbsolute));
|
|
25736
|
+
const originalPath = asset.originalPath.split(path28.sep).join("/");
|
|
25737
|
+
const originalAsFileRelative = path28.resolve(mdDir, ...originalPath.split("/"));
|
|
25738
|
+
if (path28.resolve(originalAsFileRelative) === path28.resolve(assetAbsolute)) {
|
|
25583
25739
|
addCandidate(originalPath);
|
|
25584
25740
|
}
|
|
25585
25741
|
addCandidate(`/${originalPath}`);
|
|
@@ -25675,7 +25831,7 @@ async function findMarkdownFiles(dir) {
|
|
|
25675
25831
|
return;
|
|
25676
25832
|
}
|
|
25677
25833
|
for (const entry of entries) {
|
|
25678
|
-
const full =
|
|
25834
|
+
const full = path28.join(current, entry.name);
|
|
25679
25835
|
if (entry.isDirectory()) {
|
|
25680
25836
|
if (entry.name === ".binary-lifecycle") continue;
|
|
25681
25837
|
await walk(full);
|
|
@@ -25750,7 +25906,7 @@ async function runBinaryLifecyclePipeline(memoryDir, config, backend, log2, opts
|
|
|
25750
25906
|
|
|
25751
25907
|
// src/projection/index.ts
|
|
25752
25908
|
import fs from "fs";
|
|
25753
|
-
import
|
|
25909
|
+
import path29 from "path";
|
|
25754
25910
|
var VALID_PROJECTION_CATEGORIES = new Set(ALL_CATEGORY_KEYS);
|
|
25755
25911
|
async function generateContextTree(options) {
|
|
25756
25912
|
const startTime = Date.now();
|
|
@@ -25765,8 +25921,8 @@ async function generateContextTree(options) {
|
|
|
25765
25921
|
let nodesGenerated = 0;
|
|
25766
25922
|
let nodesSkipped = 0;
|
|
25767
25923
|
const categoryCounts = {};
|
|
25768
|
-
const resolvedMemoryDir =
|
|
25769
|
-
const resolvedOutputDir =
|
|
25924
|
+
const resolvedMemoryDir = path29.resolve(memoryDir);
|
|
25925
|
+
const resolvedOutputDir = path29.resolve(outputDir);
|
|
25770
25926
|
const requestedCategories = validateProjectionCategories(filterCategories);
|
|
25771
25927
|
const realMemoryDir = assertSafeMemoryRoot(resolvedMemoryDir);
|
|
25772
25928
|
assertNotSymlink(resolvedOutputDir, "context tree outputDir");
|
|
@@ -25804,7 +25960,7 @@ async function generateContextTree(options) {
|
|
|
25804
25960
|
}
|
|
25805
25961
|
}
|
|
25806
25962
|
if (includeEntities) {
|
|
25807
|
-
const entitiesDir =
|
|
25963
|
+
const entitiesDir = path29.join(memoryDir, "entities");
|
|
25808
25964
|
if (fs.existsSync(entitiesDir)) {
|
|
25809
25965
|
assertSafeInputRoot(realMemoryDir, entitiesDir, "entities root");
|
|
25810
25966
|
categoryCounts["entity"] = 0;
|
|
@@ -25816,7 +25972,7 @@ async function generateContextTree(options) {
|
|
|
25816
25972
|
continue;
|
|
25817
25973
|
}
|
|
25818
25974
|
const content = fs.readFileSync(filePath, "utf8");
|
|
25819
|
-
const fileName =
|
|
25975
|
+
const fileName = path29.basename(filePath, ".md");
|
|
25820
25976
|
const node = projectEntityNode(fileName, content);
|
|
25821
25977
|
const outputPath = resolveContainedOutputPath(realOutputDir, "entities", `${fileName}.md`);
|
|
25822
25978
|
writeProjectedContent(realOutputDir, outputPath, node.content);
|
|
@@ -25828,7 +25984,7 @@ async function generateContextTree(options) {
|
|
|
25828
25984
|
}
|
|
25829
25985
|
const shouldIncludeQuestions = includeQuestions && (requestedCategories === void 0 || requestedCategories.includes("question"));
|
|
25830
25986
|
if (shouldIncludeQuestions) {
|
|
25831
|
-
const questionsDir =
|
|
25987
|
+
const questionsDir = path29.join(memoryDir, "questions");
|
|
25832
25988
|
if (fs.existsSync(questionsDir)) {
|
|
25833
25989
|
assertSafeInputRoot(realMemoryDir, questionsDir, "questions root");
|
|
25834
25990
|
categoryCounts["question"] = 0;
|
|
@@ -25869,8 +26025,8 @@ async function generateContextTree(options) {
|
|
|
25869
26025
|
};
|
|
25870
26026
|
}
|
|
25871
26027
|
function isPathInside(root, candidate) {
|
|
25872
|
-
const relative =
|
|
25873
|
-
return relative === "" || !relative.startsWith("..") && !
|
|
26028
|
+
const relative = path29.relative(root, candidate);
|
|
26029
|
+
return relative === "" || !relative.startsWith("..") && !path29.isAbsolute(relative);
|
|
25874
26030
|
}
|
|
25875
26031
|
function assertNotSymlink(targetPath, label) {
|
|
25876
26032
|
try {
|
|
@@ -25907,12 +26063,12 @@ function assertSafeInputRoot(realMemoryDir, targetPath, label) {
|
|
|
25907
26063
|
}
|
|
25908
26064
|
function assertSafeOutputTarget(realOutputDir, outputPath) {
|
|
25909
26065
|
let current = realOutputDir;
|
|
25910
|
-
const relative =
|
|
25911
|
-
if (relative.startsWith("..") ||
|
|
26066
|
+
const relative = path29.relative(realOutputDir, outputPath);
|
|
26067
|
+
if (relative.startsWith("..") || path29.isAbsolute(relative)) {
|
|
25912
26068
|
throw new Error(`context tree output path escapes outputDir: ${outputPath}`);
|
|
25913
26069
|
}
|
|
25914
|
-
for (const segment of relative.split(
|
|
25915
|
-
current =
|
|
26070
|
+
for (const segment of relative.split(path29.sep).filter(Boolean)) {
|
|
26071
|
+
current = path29.join(current, segment);
|
|
25916
26072
|
try {
|
|
25917
26073
|
const stat5 = fs.lstatSync(current);
|
|
25918
26074
|
if (stat5.isSymbolicLink()) {
|
|
@@ -25942,17 +26098,17 @@ function validateProjectionCategories(categories) {
|
|
|
25942
26098
|
return validated;
|
|
25943
26099
|
}
|
|
25944
26100
|
function resolveContainedOutputPath(outputRoot, ...segments) {
|
|
25945
|
-
const resolved =
|
|
25946
|
-
const relative =
|
|
25947
|
-
if (relative === "" || !relative.startsWith("..") && !
|
|
26101
|
+
const resolved = path29.resolve(outputRoot, ...segments);
|
|
26102
|
+
const relative = path29.relative(outputRoot, resolved);
|
|
26103
|
+
if (relative === "" || !relative.startsWith("..") && !path29.isAbsolute(relative)) {
|
|
25948
26104
|
return resolved;
|
|
25949
26105
|
}
|
|
25950
26106
|
throw new Error(`context tree output path escapes outputDir: ${segments.join("/")}`);
|
|
25951
26107
|
}
|
|
25952
26108
|
function writeProjectedContent(realOutputDir, outputPath, generatedContent) {
|
|
25953
26109
|
assertSafeOutputTarget(realOutputDir, outputPath);
|
|
25954
|
-
fs.mkdirSync(
|
|
25955
|
-
const realParent = fs.realpathSync(
|
|
26110
|
+
fs.mkdirSync(path29.dirname(outputPath), { recursive: true });
|
|
26111
|
+
const realParent = fs.realpathSync(path29.dirname(outputPath));
|
|
25956
26112
|
if (!isPathInside(realOutputDir, realParent)) {
|
|
25957
26113
|
throw new Error(`context tree output path escapes outputDir: ${outputPath}`);
|
|
25958
26114
|
}
|
|
@@ -25991,7 +26147,7 @@ function walkR(dir, realMemoryDir) {
|
|
|
25991
26147
|
const results = [];
|
|
25992
26148
|
function walk(directory) {
|
|
25993
26149
|
for (const entry of fs.readdirSync(directory, { withFileTypes: true })) {
|
|
25994
|
-
const fullPath =
|
|
26150
|
+
const fullPath = path29.join(directory, entry.name);
|
|
25995
26151
|
if (entry.isSymbolicLink()) {
|
|
25996
26152
|
throw new Error(`context tree input path contains symlink: ${fullPath}`);
|
|
25997
26153
|
}
|
|
@@ -26044,13 +26200,13 @@ function extractBody(content) {
|
|
|
26044
26200
|
}
|
|
26045
26201
|
function projectNode(filePath, category, fm, rawContent) {
|
|
26046
26202
|
const body = extractBody(rawContent);
|
|
26047
|
-
const fileName =
|
|
26048
|
-
const dateDir =
|
|
26203
|
+
const fileName = path29.basename(filePath, ".md");
|
|
26204
|
+
const dateDir = path29.basename(path29.dirname(filePath));
|
|
26049
26205
|
let relPath;
|
|
26050
26206
|
if (/^\d{4}-\d{2}-\d{2}$/.test(dateDir)) {
|
|
26051
|
-
relPath =
|
|
26207
|
+
relPath = path29.join(category, dateDir, `${fileName}.md`);
|
|
26052
26208
|
} else {
|
|
26053
|
-
relPath =
|
|
26209
|
+
relPath = path29.join(category, `${fileName}.md`);
|
|
26054
26210
|
}
|
|
26055
26211
|
const generatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
26056
26212
|
const md = `# ${fm.id}
|
|
@@ -26096,7 +26252,7 @@ function projectEntityNode(fileName, content) {
|
|
|
26096
26252
|
${content}
|
|
26097
26253
|
`;
|
|
26098
26254
|
return {
|
|
26099
|
-
path:
|
|
26255
|
+
path: path29.join("entities", `${fileName}.md`),
|
|
26100
26256
|
category: "entity",
|
|
26101
26257
|
title: fileName,
|
|
26102
26258
|
content: md,
|
|
@@ -26149,7 +26305,7 @@ function generateIndex(categoryCounts, outputDir) {
|
|
|
26149
26305
|
|
|
26150
26306
|
// src/onboarding/index.ts
|
|
26151
26307
|
import fs2 from "fs";
|
|
26152
|
-
import
|
|
26308
|
+
import path30 from "path";
|
|
26153
26309
|
var LANGUAGE_RULES = [
|
|
26154
26310
|
{
|
|
26155
26311
|
language: "TypeScript",
|
|
@@ -26251,7 +26407,7 @@ function onboard(options) {
|
|
|
26251
26407
|
maxDepth = 6,
|
|
26252
26408
|
excludeDirs = []
|
|
26253
26409
|
} = options;
|
|
26254
|
-
const directory =
|
|
26410
|
+
const directory = path30.resolve(options.directory ?? process.cwd());
|
|
26255
26411
|
let rootStat;
|
|
26256
26412
|
try {
|
|
26257
26413
|
rootStat = fs2.statSync(directory);
|
|
@@ -26293,7 +26449,7 @@ function walkDir(root, exclude, maxDepth) {
|
|
|
26293
26449
|
}
|
|
26294
26450
|
for (const entry of entries) {
|
|
26295
26451
|
if (exclude.has(entry.name)) continue;
|
|
26296
|
-
const fullPath =
|
|
26452
|
+
const fullPath = path30.join(dir, entry.name);
|
|
26297
26453
|
if (entry.isDirectory()) {
|
|
26298
26454
|
walk(fullPath, depth + 1);
|
|
26299
26455
|
} else if (entry.isFile()) {
|
|
@@ -26308,11 +26464,11 @@ function detectLanguages(files, root) {
|
|
|
26308
26464
|
const results = [];
|
|
26309
26465
|
const extCounts = /* @__PURE__ */ new Map();
|
|
26310
26466
|
for (const f of files) {
|
|
26311
|
-
const ext =
|
|
26467
|
+
const ext = path30.extname(f).toLowerCase();
|
|
26312
26468
|
if (ext) extCounts.set(ext, (extCounts.get(ext) ?? 0) + 1);
|
|
26313
26469
|
}
|
|
26314
26470
|
const rootFiles = new Set(
|
|
26315
|
-
files.filter((f) =>
|
|
26471
|
+
files.filter((f) => path30.dirname(f) === root).map((f) => path30.basename(f))
|
|
26316
26472
|
);
|
|
26317
26473
|
for (const rule of LANGUAGE_RULES) {
|
|
26318
26474
|
const evidence = [];
|
|
@@ -26356,7 +26512,7 @@ function detectLanguages(files, root) {
|
|
|
26356
26512
|
}
|
|
26357
26513
|
function detectShape(files, root) {
|
|
26358
26514
|
const rootFiles = new Set(
|
|
26359
|
-
files.filter((f) =>
|
|
26515
|
+
files.filter((f) => path30.dirname(f) === root).map((f) => path30.basename(f))
|
|
26360
26516
|
);
|
|
26361
26517
|
const rootDirs = /* @__PURE__ */ new Set();
|
|
26362
26518
|
try {
|
|
@@ -26367,7 +26523,7 @@ function detectShape(files, root) {
|
|
|
26367
26523
|
}
|
|
26368
26524
|
const evidence = [];
|
|
26369
26525
|
if (rootFiles.has("package.json")) {
|
|
26370
|
-
const pkg = readJsonSafe(
|
|
26526
|
+
const pkg = readJsonSafe(path30.join(root, "package.json"));
|
|
26371
26527
|
if (pkg?.workspaces) {
|
|
26372
26528
|
evidence.push("package.json has workspaces");
|
|
26373
26529
|
return { shape: "monorepo", evidence };
|
|
@@ -26381,13 +26537,13 @@ function detectShape(files, root) {
|
|
|
26381
26537
|
evidence.push("workspace manifest found");
|
|
26382
26538
|
return { shape: "workspace", evidence };
|
|
26383
26539
|
}
|
|
26384
|
-
const cargoToml = readTomlWorkspace(
|
|
26540
|
+
const cargoToml = readTomlWorkspace(path30.join(root, "Cargo.toml"));
|
|
26385
26541
|
if (cargoToml) {
|
|
26386
26542
|
evidence.push("Cargo.toml has workspace");
|
|
26387
26543
|
return { shape: "workspace", evidence };
|
|
26388
26544
|
}
|
|
26389
26545
|
if (rootFiles.has("package.json")) {
|
|
26390
|
-
const pkg = readJsonSafe(
|
|
26546
|
+
const pkg = readJsonSafe(path30.join(root, "package.json"));
|
|
26391
26547
|
if (pkg?.exports || pkg?.main) {
|
|
26392
26548
|
if (pkg?.bin) {
|
|
26393
26549
|
evidence.push("package.json has bin");
|
|
@@ -26421,8 +26577,8 @@ function discoverDocs(files, root) {
|
|
|
26421
26577
|
{ pattern: /^\.editorconfig$/i, kind: "config" }
|
|
26422
26578
|
];
|
|
26423
26579
|
for (const filePath of files) {
|
|
26424
|
-
const basename =
|
|
26425
|
-
const relPath =
|
|
26580
|
+
const basename = path30.basename(filePath).toLowerCase();
|
|
26581
|
+
const relPath = path30.relative(root, filePath);
|
|
26426
26582
|
let kind;
|
|
26427
26583
|
for (const { pattern, kind: k } of docPatterns) {
|
|
26428
26584
|
if (pattern.test(basename)) {
|
|
@@ -26434,7 +26590,7 @@ function discoverDocs(files, root) {
|
|
|
26434
26590
|
kind = "docs";
|
|
26435
26591
|
}
|
|
26436
26592
|
if (!kind && (basename.endsWith(".md") || basename.endsWith(".mdx"))) {
|
|
26437
|
-
if (
|
|
26593
|
+
if (path30.dirname(relPath) === "." || isUnderDocsDir(relPath)) {
|
|
26438
26594
|
kind = "docs";
|
|
26439
26595
|
}
|
|
26440
26596
|
}
|
|
@@ -26455,7 +26611,7 @@ function discoverDocs(files, root) {
|
|
|
26455
26611
|
return docs;
|
|
26456
26612
|
}
|
|
26457
26613
|
function isUnderDocsDir(relPath) {
|
|
26458
|
-
const parts = relPath.split(
|
|
26614
|
+
const parts = relPath.split(path30.sep);
|
|
26459
26615
|
return parts[0] === "docs" || parts[0] === "doc" || parts[0] === "documentation";
|
|
26460
26616
|
}
|
|
26461
26617
|
function buildPlan(languages, shape, docs, _root) {
|
|
@@ -26499,7 +26655,7 @@ function readTomlWorkspace(filePath) {
|
|
|
26499
26655
|
|
|
26500
26656
|
// src/curation/index.ts
|
|
26501
26657
|
import fs3 from "fs";
|
|
26502
|
-
import
|
|
26658
|
+
import path31 from "path";
|
|
26503
26659
|
import crypto4 from "crypto";
|
|
26504
26660
|
async function curate(options) {
|
|
26505
26661
|
const startTime = Date.now();
|
|
@@ -26590,12 +26746,12 @@ function resolveTargets(targetPath) {
|
|
|
26590
26746
|
const extensions = /* @__PURE__ */ new Set([".md", ".txt", ".mdx", ".rst"]);
|
|
26591
26747
|
function walk(dir) {
|
|
26592
26748
|
for (const entry of fs3.readdirSync(dir, { withFileTypes: true })) {
|
|
26593
|
-
const fullPath =
|
|
26749
|
+
const fullPath = path31.join(dir, entry.name);
|
|
26594
26750
|
if (entry.isDirectory()) {
|
|
26595
26751
|
if (entry.name !== "node_modules" && entry.name !== ".git") {
|
|
26596
26752
|
walk(fullPath);
|
|
26597
26753
|
}
|
|
26598
|
-
} else if (extensions.has(
|
|
26754
|
+
} else if (extensions.has(path31.extname(entry.name).toLowerCase())) {
|
|
26599
26755
|
results.push(fullPath);
|
|
26600
26756
|
}
|
|
26601
26757
|
}
|
|
@@ -26604,12 +26760,12 @@ function resolveTargets(targetPath) {
|
|
|
26604
26760
|
return results;
|
|
26605
26761
|
}
|
|
26606
26762
|
function resolveProvenanceRoot(targetPath) {
|
|
26607
|
-
const resolvedTarget =
|
|
26763
|
+
const resolvedTarget = path31.resolve(targetPath);
|
|
26608
26764
|
const stat5 = fs3.statSync(resolvedTarget);
|
|
26609
|
-
return stat5.isFile() ?
|
|
26765
|
+
return stat5.isFile() ? path31.dirname(resolvedTarget) : resolvedTarget;
|
|
26610
26766
|
}
|
|
26611
26767
|
function extractStatements(content, filePath, projectRoot, source, sourceFileHash, categoryOverride, confidence, entityRef, tags) {
|
|
26612
|
-
const relativePath =
|
|
26768
|
+
const relativePath = path31.relative(projectRoot, path31.resolve(filePath)) || path31.basename(filePath);
|
|
26613
26769
|
const statements = [];
|
|
26614
26770
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
26615
26771
|
const paragraphs = content.split(/\n{2,}/).map((p) => p.trim()).filter((p) => p.length > 20 && p.length < 2e3);
|
|
@@ -26703,7 +26859,7 @@ function loadExistingMemories(memoryDir) {
|
|
|
26703
26859
|
if (!fs3.existsSync(memoryDir)) return result;
|
|
26704
26860
|
const dirs = ALL_CATEGORY_DIRS;
|
|
26705
26861
|
for (const dir of dirs) {
|
|
26706
|
-
const fullDir =
|
|
26862
|
+
const fullDir = path31.join(memoryDir, dir);
|
|
26707
26863
|
if (!fs3.existsSync(fullDir)) continue;
|
|
26708
26864
|
walkFiles(fullDir, (filePath) => {
|
|
26709
26865
|
const content = readFileSafe(filePath);
|
|
@@ -26726,11 +26882,11 @@ function writeStatement(stmt, memoryDir) {
|
|
|
26726
26882
|
const now = /* @__PURE__ */ new Date();
|
|
26727
26883
|
const dateDir = now.toISOString().split("T")[0];
|
|
26728
26884
|
const categoryDir = getCategoryDir(memoryDir, stmt.category);
|
|
26729
|
-
const dir =
|
|
26885
|
+
const dir = path31.join(categoryDir, dateDir);
|
|
26730
26886
|
fs3.mkdirSync(dir, { recursive: true });
|
|
26731
26887
|
const fileName = `${stmt.category}-${Date.now()}-${stmt.id.slice(0, 8)}.md`;
|
|
26732
|
-
const filePath =
|
|
26733
|
-
const historicalIds = historicalIdCache2.get(
|
|
26888
|
+
const filePath = path31.join(dir, fileName);
|
|
26889
|
+
const historicalIds = historicalIdCache2.get(path31.join(memoryDir, "state"));
|
|
26734
26890
|
const rawBody = `${[
|
|
26735
26891
|
"---",
|
|
26736
26892
|
`id: ${stmt.id}`,
|
|
@@ -26753,7 +26909,7 @@ ${stmt.content}
|
|
|
26753
26909
|
fs3.writeFileSync(filePath, body);
|
|
26754
26910
|
try {
|
|
26755
26911
|
repairContentAfterJournalMoveSync({
|
|
26756
|
-
stateDir:
|
|
26912
|
+
stateDir: path31.join(memoryDir, "state"),
|
|
26757
26913
|
cache: historicalIdCache2,
|
|
26758
26914
|
idsAtWrite: historicalIds,
|
|
26759
26915
|
rawContent: rawBody,
|
|
@@ -26814,7 +26970,7 @@ function extractBody2(content) {
|
|
|
26814
26970
|
}
|
|
26815
26971
|
function walkFiles(dir, callback) {
|
|
26816
26972
|
for (const entry of fs3.readdirSync(dir, { withFileTypes: true })) {
|
|
26817
|
-
const fullPath =
|
|
26973
|
+
const fullPath = path31.join(dir, entry.name);
|
|
26818
26974
|
if (entry.isDirectory()) {
|
|
26819
26975
|
walkFiles(fullPath, callback);
|
|
26820
26976
|
} else if (entry.name.endsWith(".md")) {
|
|
@@ -26825,7 +26981,7 @@ function walkFiles(dir, callback) {
|
|
|
26825
26981
|
|
|
26826
26982
|
// src/sync/index.ts
|
|
26827
26983
|
import fs4 from "fs";
|
|
26828
|
-
import
|
|
26984
|
+
import path32 from "path";
|
|
26829
26985
|
import crypto5 from "crypto";
|
|
26830
26986
|
var DEFAULT_EXTENSIONS = /* @__PURE__ */ new Set([".md", ".txt", ".mdx", ".rst"]);
|
|
26831
26987
|
var DEFAULT_EXCLUDE2 = /* @__PURE__ */ new Set([
|
|
@@ -26847,7 +27003,7 @@ function syncChanges(options) {
|
|
|
26847
27003
|
} = options;
|
|
26848
27004
|
const extSet = new Set(extensions);
|
|
26849
27005
|
const excludeSet = /* @__PURE__ */ new Set([...DEFAULT_EXCLUDE2, ...excludeDirs]);
|
|
26850
|
-
const stateFilePath = options.stateFile ??
|
|
27006
|
+
const stateFilePath = options.stateFile ?? path32.join(memoryDir, ".sync-state.json");
|
|
26851
27007
|
const prevState = loadState(stateFilePath);
|
|
26852
27008
|
const currentFiles = scanFiles(sourceDir, extSet, excludeSet);
|
|
26853
27009
|
const changes = computeDiff(currentFiles, prevState.fileHashes, sourceDir);
|
|
@@ -26863,7 +27019,7 @@ function syncChanges(options) {
|
|
|
26863
27019
|
for (const [relPath, hash] of Object.entries(currentFiles)) {
|
|
26864
27020
|
newState.fileHashes[relPath] = hash;
|
|
26865
27021
|
}
|
|
26866
|
-
fs4.mkdirSync(
|
|
27022
|
+
fs4.mkdirSync(path32.dirname(stateFilePath), { recursive: true });
|
|
26867
27023
|
fs4.writeFileSync(stateFilePath, JSON.stringify(newState, null, 2));
|
|
26868
27024
|
}
|
|
26869
27025
|
return {
|
|
@@ -26929,13 +27085,13 @@ function scanFiles(root, extensions, exclude) {
|
|
|
26929
27085
|
}
|
|
26930
27086
|
for (const entry of entries) {
|
|
26931
27087
|
if (exclude.has(entry.name)) continue;
|
|
26932
|
-
const fullPath =
|
|
27088
|
+
const fullPath = path32.join(dir, entry.name);
|
|
26933
27089
|
if (entry.isDirectory()) {
|
|
26934
27090
|
walk(fullPath);
|
|
26935
27091
|
} else if (entry.isFile()) {
|
|
26936
|
-
const ext =
|
|
27092
|
+
const ext = path32.extname(entry.name).toLowerCase();
|
|
26937
27093
|
if (!extensions.has(ext)) continue;
|
|
26938
|
-
const relPath =
|
|
27094
|
+
const relPath = path32.relative(root, fullPath);
|
|
26939
27095
|
try {
|
|
26940
27096
|
const content = fs4.readFileSync(fullPath, "utf8");
|
|
26941
27097
|
result[relPath] = hashContent2(content);
|
|
@@ -26950,7 +27106,7 @@ function scanFiles(root, extensions, exclude) {
|
|
|
26950
27106
|
function computeDiff(current, previous, sourceDir) {
|
|
26951
27107
|
const changes = [];
|
|
26952
27108
|
for (const [relPath, hash] of Object.entries(current)) {
|
|
26953
|
-
const fullPath =
|
|
27109
|
+
const fullPath = path32.join(sourceDir, relPath);
|
|
26954
27110
|
if (!(relPath in previous)) {
|
|
26955
27111
|
let size = 0;
|
|
26956
27112
|
try {
|
|
@@ -26983,7 +27139,7 @@ function computeDiff(current, previous, sourceDir) {
|
|
|
26983
27139
|
for (const relPath of Object.keys(previous)) {
|
|
26984
27140
|
if (!(relPath in current)) {
|
|
26985
27141
|
changes.push({
|
|
26986
|
-
filePath:
|
|
27142
|
+
filePath: path32.join(sourceDir, relPath),
|
|
26987
27143
|
relativePath: relPath,
|
|
26988
27144
|
type: "deleted",
|
|
26989
27145
|
currentHash: "",
|
|
@@ -27013,21 +27169,21 @@ function hashContent2(content) {
|
|
|
27013
27169
|
import { spawnSync } from "child_process";
|
|
27014
27170
|
import crypto6 from "crypto";
|
|
27015
27171
|
import fs5 from "fs";
|
|
27016
|
-
import
|
|
27172
|
+
import path33 from "path";
|
|
27017
27173
|
var historicalIdCache3 = new HistoricalEntityCanonicalIdCache();
|
|
27018
27174
|
var MANIFEST_VERSION = 1;
|
|
27019
27175
|
var MANIFEST_LOCK_STALE_MS = 3e4;
|
|
27020
27176
|
var MANIFEST_LOCK_TIMEOUT_MS = MANIFEST_LOCK_STALE_MS + 1e4;
|
|
27021
27177
|
var MANIFEST_LOCK_SLEEP_MS = 20;
|
|
27022
27178
|
function normalizeSpaceMemoryDir(memoryDir) {
|
|
27023
|
-
return
|
|
27179
|
+
return path33.resolve(memoryDir);
|
|
27024
27180
|
}
|
|
27025
27181
|
function getSpacesDir(baseDir) {
|
|
27026
27182
|
const homeDir = baseDir ?? resolveHomeDir();
|
|
27027
|
-
return
|
|
27183
|
+
return path33.join(homeDir, ".config", "engram", "spaces");
|
|
27028
27184
|
}
|
|
27029
27185
|
function getManifestPath(baseDir) {
|
|
27030
|
-
return
|
|
27186
|
+
return path33.join(getSpacesDir(baseDir), "manifest.json");
|
|
27031
27187
|
}
|
|
27032
27188
|
function loadManifest(baseDir, memoryDirOverride) {
|
|
27033
27189
|
if (fs5.existsSync(getManifestPath(baseDir))) {
|
|
@@ -27074,9 +27230,9 @@ function readManifestUnlocked(baseDir, memoryDirOverride, options = {}) {
|
|
|
27074
27230
|
}
|
|
27075
27231
|
function saveManifestUnlocked(manifest, baseDir) {
|
|
27076
27232
|
const manifestPath2 = getManifestPath(baseDir);
|
|
27077
|
-
const manifestDir2 =
|
|
27233
|
+
const manifestDir2 = path33.dirname(manifestPath2);
|
|
27078
27234
|
fs5.mkdirSync(manifestDir2, { recursive: true });
|
|
27079
|
-
const tempPath =
|
|
27235
|
+
const tempPath = path33.join(manifestDir2, `.manifest.${process.pid}.${Date.now()}.${crypto6.randomUUID()}.tmp`);
|
|
27080
27236
|
try {
|
|
27081
27237
|
fs5.writeFileSync(tempPath, `${JSON.stringify(manifest, null, 2)}
|
|
27082
27238
|
`, { flag: "wx" });
|
|
@@ -27091,7 +27247,7 @@ function saveManifestUnlocked(manifest, baseDir) {
|
|
|
27091
27247
|
}
|
|
27092
27248
|
function withManifestLock(baseDir, operation) {
|
|
27093
27249
|
const lockDir = `${getManifestPath(baseDir)}.lock`;
|
|
27094
|
-
fs5.mkdirSync(
|
|
27250
|
+
fs5.mkdirSync(path33.dirname(lockDir), { recursive: true });
|
|
27095
27251
|
const lockOwner = acquireManifestLock(lockDir);
|
|
27096
27252
|
try {
|
|
27097
27253
|
return operation();
|
|
@@ -27117,7 +27273,7 @@ function acquireManifestLock(lockDir) {
|
|
|
27117
27273
|
try {
|
|
27118
27274
|
fs5.mkdirSync(lockDir, { recursive: false });
|
|
27119
27275
|
try {
|
|
27120
|
-
fs5.writeFileSync(
|
|
27276
|
+
fs5.writeFileSync(path33.join(lockDir, "owner"), `${owner}
|
|
27121
27277
|
`, { flag: "wx" });
|
|
27122
27278
|
} catch (error) {
|
|
27123
27279
|
fs5.rmSync(lockDir, { recursive: true, force: true });
|
|
@@ -27147,7 +27303,7 @@ function acquireManifestLock(lockDir) {
|
|
|
27147
27303
|
}
|
|
27148
27304
|
function releaseManifestLock(lockDir, owner) {
|
|
27149
27305
|
try {
|
|
27150
|
-
const ownerPath =
|
|
27306
|
+
const ownerPath = path33.join(lockDir, "owner");
|
|
27151
27307
|
if (fs5.readFileSync(ownerPath, "utf8").trim() === owner) {
|
|
27152
27308
|
fs5.rmSync(lockDir, { recursive: true, force: true });
|
|
27153
27309
|
}
|
|
@@ -27163,7 +27319,7 @@ function removeStaleManifestLock(lockDir) {
|
|
|
27163
27319
|
try {
|
|
27164
27320
|
fs5.mkdirSync(reclaimDir, { recursive: false });
|
|
27165
27321
|
try {
|
|
27166
|
-
fs5.writeFileSync(
|
|
27322
|
+
fs5.writeFileSync(path33.join(reclaimDir, "owner"), `${reclaimOwner}
|
|
27167
27323
|
`, { flag: "wx" });
|
|
27168
27324
|
} catch (error) {
|
|
27169
27325
|
fs5.rmSync(reclaimDir, { recursive: true, force: true });
|
|
@@ -27238,7 +27394,7 @@ function readManifestLockSnapshot(lockDir) {
|
|
|
27238
27394
|
throw error;
|
|
27239
27395
|
}
|
|
27240
27396
|
try {
|
|
27241
|
-
const owner = fs5.readFileSync(
|
|
27397
|
+
const owner = fs5.readFileSync(path33.join(lockDir, "owner"), "utf8").trim();
|
|
27242
27398
|
return { mtimeMs: stat5.mtimeMs, owner };
|
|
27243
27399
|
} catch (error) {
|
|
27244
27400
|
if (error.code === "ENOENT") {
|
|
@@ -27310,8 +27466,8 @@ function sleepSync(ms) {
|
|
|
27310
27466
|
}
|
|
27311
27467
|
function createPersonalSpace(baseDir, memoryDirOverride) {
|
|
27312
27468
|
const homeDir = baseDir ?? resolveHomeDir();
|
|
27313
|
-
const standalonePath =
|
|
27314
|
-
const openclawPath =
|
|
27469
|
+
const standalonePath = path33.join(homeDir, ".engram", "memory");
|
|
27470
|
+
const openclawPath = path33.join(homeDir, ".openclaw", "workspace", "memory", "local");
|
|
27315
27471
|
const memoryDir = memoryDirOverride ?? readEnvVar("REMNIC_MEMORY_DIR") ?? readEnvVar("ENGRAM_MEMORY_DIR") ?? (fs5.existsSync(standalonePath) ? standalonePath : fs5.existsSync(openclawPath) ? openclawPath : standalonePath);
|
|
27316
27472
|
const normalizedMemoryDir = normalizeSpaceMemoryDir(memoryDir);
|
|
27317
27473
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -27340,7 +27496,7 @@ function createSpace(options) {
|
|
|
27340
27496
|
const id = options.name.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-");
|
|
27341
27497
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
27342
27498
|
const memoryDir = normalizeSpaceMemoryDir(
|
|
27343
|
-
options.memoryDir ??
|
|
27499
|
+
options.memoryDir ?? path33.join(getSpacesDir(options.baseDir), id, "memory")
|
|
27344
27500
|
);
|
|
27345
27501
|
const space = updateManifest(options.baseDir, (manifest) => {
|
|
27346
27502
|
if (manifest.spaces.some((s) => s.id === id)) {
|
|
@@ -27586,14 +27742,14 @@ async function mergeSpaces(sourceSpaceId, targetSpaceId, options) {
|
|
|
27586
27742
|
};
|
|
27587
27743
|
}
|
|
27588
27744
|
function getAuditLog(baseDir) {
|
|
27589
|
-
const auditPath =
|
|
27745
|
+
const auditPath = path33.join(getSpacesDir(baseDir), "audit.jsonl");
|
|
27590
27746
|
if (!fs5.existsSync(auditPath)) return [];
|
|
27591
27747
|
const lines = fs5.readFileSync(auditPath, "utf8").trim().split("\n");
|
|
27592
27748
|
return lines.filter((l) => l.trim()).map((l) => JSON.parse(l));
|
|
27593
27749
|
}
|
|
27594
27750
|
function appendAudit(entry, baseDir) {
|
|
27595
|
-
const auditPath =
|
|
27596
|
-
fs5.mkdirSync(
|
|
27751
|
+
const auditPath = path33.join(getSpacesDir(baseDir), "audit.jsonl");
|
|
27752
|
+
fs5.mkdirSync(path33.dirname(auditPath), { recursive: true });
|
|
27597
27753
|
const full = {
|
|
27598
27754
|
id: crypto6.randomUUID(),
|
|
27599
27755
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -27614,11 +27770,11 @@ async function copyMemories(sourceDir, targetDir, options) {
|
|
|
27614
27770
|
sourceFiles.filter((p) => {
|
|
27615
27771
|
const rp = safeRealpath(p);
|
|
27616
27772
|
if (!rp || !isPathInsideRoot(rp, sourceRoot)) return false;
|
|
27617
|
-
const rel =
|
|
27618
|
-
const mapped =
|
|
27773
|
+
const rel = path33.relative(sourceRoot, rp);
|
|
27774
|
+
const mapped = path33.resolve(targetRoot, rel);
|
|
27619
27775
|
if (!isPathInsideRoot(mapped, targetRoot)) return false;
|
|
27620
27776
|
return classifyEntityRefWritePath(targetRoot, mapped) === "entity";
|
|
27621
|
-
}).map((p) =>
|
|
27777
|
+
}).map((p) => path33.basename(p, ".md"))
|
|
27622
27778
|
);
|
|
27623
27779
|
const firstEntityId = sourceEntityIds.values().next().value;
|
|
27624
27780
|
if (firstEntityId === void 0) {
|
|
@@ -27626,7 +27782,7 @@ async function copyMemories(sourceDir, targetDir, options) {
|
|
|
27626
27782
|
}
|
|
27627
27783
|
return withRawEntityPageMutation(
|
|
27628
27784
|
targetRoot,
|
|
27629
|
-
|
|
27785
|
+
path33.join(targetRoot, "entities", `${firstEntityId}.md`),
|
|
27630
27786
|
async () => copyPreparedMemories(
|
|
27631
27787
|
sourceFiles,
|
|
27632
27788
|
sourceRoot,
|
|
@@ -27653,14 +27809,14 @@ function copyPreparedMemories(sourceFiles, sourceRoot, targetRoot, sourceEntityI
|
|
|
27653
27809
|
continue;
|
|
27654
27810
|
}
|
|
27655
27811
|
const content = fs5.readFileSync(sourcePath, "utf8");
|
|
27656
|
-
const relativePath =
|
|
27657
|
-
const targetPath =
|
|
27812
|
+
const relativePath = path33.relative(sourceRoot, sourceRealPath);
|
|
27813
|
+
const targetPath = path33.resolve(targetRoot, relativePath);
|
|
27658
27814
|
if (!isPathInsideRoot(targetPath, targetRoot)) {
|
|
27659
27815
|
skipped++;
|
|
27660
27816
|
continue;
|
|
27661
27817
|
}
|
|
27662
27818
|
const targetKind = classifyEntityRefWritePath(targetRoot, targetPath);
|
|
27663
|
-
const idsAtCompare = historicalIdCache3.get(
|
|
27819
|
+
const idsAtCompare = historicalIdCache3.get(path33.join(targetRoot, "state"));
|
|
27664
27820
|
const sourceRef = targetKind === "memory" ? readEntityRefFromFrontmatter(content) : null;
|
|
27665
27821
|
const refHasSourceClaimant = sourceRef !== null && sourceEntityIds.has(sourceRef);
|
|
27666
27822
|
const canonicalContent = targetKind === "memory" && !refHasSourceClaimant ? canonicalizeEntityRefFrontmatter(content, idsAtCompare) : content;
|
|
@@ -27687,7 +27843,7 @@ function copyPreparedMemories(sourceFiles, sourceRoot, targetRoot, sourceEntityI
|
|
|
27687
27843
|
if (fs5.existsSync(targetPath) && !options?.force) {
|
|
27688
27844
|
const targetContent = fs5.readFileSync(targetPath, "utf8");
|
|
27689
27845
|
const targetHash = hashContent3(targetContent);
|
|
27690
|
-
if (hashContent3(canonicalContent) === targetHash && historicalIdCache3.get(
|
|
27846
|
+
if (hashContent3(canonicalContent) === targetHash && historicalIdCache3.get(path33.join(targetRoot, "state")) === idsAtCompare) {
|
|
27691
27847
|
skipped++;
|
|
27692
27848
|
continue;
|
|
27693
27849
|
}
|
|
@@ -27703,13 +27859,13 @@ function copyPreparedMemories(sourceFiles, sourceRoot, targetRoot, sourceEntityI
|
|
|
27703
27859
|
continue;
|
|
27704
27860
|
}
|
|
27705
27861
|
}
|
|
27706
|
-
fs5.mkdirSync(
|
|
27707
|
-
const targetParentRealPath = safeRealpath(
|
|
27862
|
+
fs5.mkdirSync(path33.dirname(targetPath), { recursive: true });
|
|
27863
|
+
const targetParentRealPath = safeRealpath(path33.dirname(targetPath));
|
|
27708
27864
|
if (!targetParentRealPath || !isPathInsideRoot(targetParentRealPath, targetRoot)) {
|
|
27709
27865
|
skipped++;
|
|
27710
27866
|
continue;
|
|
27711
27867
|
}
|
|
27712
|
-
const stateDir =
|
|
27868
|
+
const stateDir = path33.join(targetRoot, "state");
|
|
27713
27869
|
if (targetKind === "memory" && !refHasSourceClaimant) {
|
|
27714
27870
|
const idsAtWrite = historicalIdCache3.get(stateDir);
|
|
27715
27871
|
const written = canonicalizeEntityRefFrontmatter(content, idsAtWrite);
|
|
@@ -27753,7 +27909,7 @@ function copyPreparedMemories(sourceFiles, sourceRoot, targetRoot, sourceEntityI
|
|
|
27753
27909
|
bumpMemoryCorpusVersionForDir(targetRoot);
|
|
27754
27910
|
}
|
|
27755
27911
|
if (reconcileNeeded) {
|
|
27756
|
-
requestEntityCanonicalIdReconcileSync(
|
|
27912
|
+
requestEntityCanonicalIdReconcileSync(path33.join(targetRoot, "state"));
|
|
27757
27913
|
}
|
|
27758
27914
|
return { merged, conflicts, skipped };
|
|
27759
27915
|
}
|
|
@@ -27764,7 +27920,7 @@ function walkMd(dir) {
|
|
|
27764
27920
|
const results = [];
|
|
27765
27921
|
function walk(d) {
|
|
27766
27922
|
for (const entry of fs5.readdirSync(d, { withFileTypes: true })) {
|
|
27767
|
-
const fullPath =
|
|
27923
|
+
const fullPath = path33.join(d, entry.name);
|
|
27768
27924
|
if (entry.isSymbolicLink()) {
|
|
27769
27925
|
continue;
|
|
27770
27926
|
}
|
|
@@ -27793,8 +27949,8 @@ function safeRealpath(filePath) {
|
|
|
27793
27949
|
}
|
|
27794
27950
|
}
|
|
27795
27951
|
function isPathInsideRoot(candidatePath, rootPath) {
|
|
27796
|
-
const relative =
|
|
27797
|
-
return relative === "" || !relative.startsWith("..") && !
|
|
27952
|
+
const relative = path33.relative(rootPath, candidatePath);
|
|
27953
|
+
return relative === "" || !relative.startsWith("..") && !path33.isAbsolute(relative);
|
|
27798
27954
|
}
|
|
27799
27955
|
function parseSimpleFrontmatter(content) {
|
|
27800
27956
|
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
@@ -27915,7 +28071,7 @@ var REMNIC_RECALL_DECISION_RULES = `## When to Use Recall vs Direct Read
|
|
|
27915
28071
|
// src/memory-extension/codex-publisher.ts
|
|
27916
28072
|
import fs6 from "fs";
|
|
27917
28073
|
import os from "os";
|
|
27918
|
-
import
|
|
28074
|
+
import path34 from "path";
|
|
27919
28075
|
var REMNIC_EXTENSION_DIR_NAME = "remnic";
|
|
27920
28076
|
function resolveEnvHome(env) {
|
|
27921
28077
|
if (env === void 0) return resolveHomeDir();
|
|
@@ -27924,12 +28080,12 @@ function resolveEnvHome(env) {
|
|
|
27924
28080
|
function expandTildeWithHome(input, homeDir) {
|
|
27925
28081
|
if (input === "~") return homeDir;
|
|
27926
28082
|
if (input.startsWith("~/") || input.startsWith("~\\")) {
|
|
27927
|
-
return
|
|
28083
|
+
return path34.join(homeDir, input.slice(2));
|
|
27928
28084
|
}
|
|
27929
28085
|
return input;
|
|
27930
28086
|
}
|
|
27931
28087
|
function normalizeHostRoot(input, homeDir) {
|
|
27932
|
-
return
|
|
28088
|
+
return path34.resolve(expandTildeWithHome(input.trim(), homeDir));
|
|
27933
28089
|
}
|
|
27934
28090
|
var CodexMemoryExtensionPublisher = class {
|
|
27935
28091
|
hostId = "codex";
|
|
@@ -27943,12 +28099,12 @@ var CodexMemoryExtensionPublisher = class {
|
|
|
27943
28099
|
async resolveExtensionRoot(env) {
|
|
27944
28100
|
const homeDir = resolveEnvHome(env);
|
|
27945
28101
|
const codexHomeInput = env === void 0 ? readEnvVar("CODEX_HOME")?.trim() : env.CODEX_HOME?.trim();
|
|
27946
|
-
const codexHome = codexHomeInput ? normalizeHostRoot(codexHomeInput, homeDir) :
|
|
27947
|
-
return
|
|
28102
|
+
const codexHome = codexHomeInput ? normalizeHostRoot(codexHomeInput, homeDir) : path34.resolve(homeDir, ".codex");
|
|
28103
|
+
return path34.join(codexHome, "memories_extensions", REMNIC_EXTENSION_DIR_NAME);
|
|
27948
28104
|
}
|
|
27949
28105
|
async isHostAvailable() {
|
|
27950
28106
|
try {
|
|
27951
|
-
const home = readEnvVar("CODEX_HOME")?.trim() ||
|
|
28107
|
+
const home = readEnvVar("CODEX_HOME")?.trim() || path34.join(resolveHomeDir(), ".codex");
|
|
27952
28108
|
return fs6.existsSync(home);
|
|
27953
28109
|
} catch {
|
|
27954
28110
|
return false;
|
|
@@ -27999,7 +28155,7 @@ When running inside the Codex phase-2 consolidation sandbox:
|
|
|
27999
28155
|
}
|
|
28000
28156
|
async publish(ctx) {
|
|
28001
28157
|
const extensionRoot = await this.resolveExtensionRoot();
|
|
28002
|
-
const instructionsPath =
|
|
28158
|
+
const instructionsPath = path34.join(extensionRoot, "instructions.md");
|
|
28003
28159
|
const filesWritten = [];
|
|
28004
28160
|
const skipped = [];
|
|
28005
28161
|
ctx.log.info(`Publishing Codex memory extension to ${extensionRoot}`);
|
|
@@ -28631,9 +28787,9 @@ function buildWeeklyActivitySummary(cards, options) {
|
|
|
28631
28787
|
// src/activity/timeline/weekly-persist.ts
|
|
28632
28788
|
import { randomBytes as randomBytes3 } from "crypto";
|
|
28633
28789
|
import { mkdirSync, readFileSync as readFileSync2, renameSync, unlinkSync, writeFileSync } from "fs";
|
|
28634
|
-
import
|
|
28790
|
+
import path35 from "path";
|
|
28635
28791
|
var WEEKLY_SNAPSHOT_FORMAT_VERSION = 1;
|
|
28636
|
-
var WEEKLY_SNAPSHOT_DIR =
|
|
28792
|
+
var WEEKLY_SNAPSHOT_DIR = path35.join("activity", "weekly");
|
|
28637
28793
|
function requireToken(value, name) {
|
|
28638
28794
|
if (typeof value !== "string" || value.trim().length === 0) {
|
|
28639
28795
|
throw new TypeError(`${name} must be a non-empty string`);
|
|
@@ -28656,8 +28812,8 @@ function weeklySnapshotPath(input) {
|
|
|
28656
28812
|
const identity = hashActivityBody(
|
|
28657
28813
|
`${input.summary.weekStartUtc}\0${input.summary.weekEndUtc}\0${sourceRevision}\0${configHash}`
|
|
28658
28814
|
);
|
|
28659
|
-
return
|
|
28660
|
-
|
|
28815
|
+
return path35.join(
|
|
28816
|
+
path35.resolve(memoryDir),
|
|
28661
28817
|
WEEKLY_SNAPSHOT_DIR,
|
|
28662
28818
|
namespaceIdentityToken(namespace),
|
|
28663
28819
|
`${weekDate}--${identity}.json`
|
|
@@ -28687,7 +28843,7 @@ function persistWeeklySnapshot(input) {
|
|
|
28687
28843
|
throw error;
|
|
28688
28844
|
}
|
|
28689
28845
|
}
|
|
28690
|
-
mkdirSync(
|
|
28846
|
+
mkdirSync(path35.dirname(filePath), { recursive: true, mode: 448 });
|
|
28691
28847
|
const tmpPath = `${filePath}.${process.pid}.${randomBytes3(8).toString("hex")}.tmp`;
|
|
28692
28848
|
writeFileSync(tmpPath, text, { encoding: "utf8", mode: 384 });
|
|
28693
28849
|
try {
|
|
@@ -29339,7 +29495,7 @@ function selectRecapForDay(input) {
|
|
|
29339
29495
|
|
|
29340
29496
|
// src/activity/journal-read.ts
|
|
29341
29497
|
import { closeSync, constants as fsConstants, fstatSync, lstatSync, openSync, readFileSync as readFileSync3, realpathSync, statSync as statSync2 } from "fs";
|
|
29342
|
-
import
|
|
29498
|
+
import path36 from "path";
|
|
29343
29499
|
|
|
29344
29500
|
// src/activity/journal-section.ts
|
|
29345
29501
|
function parseAtxHeading(line) {
|
|
@@ -29530,8 +29686,8 @@ function readJournalForDate(input) {
|
|
|
29530
29686
|
const relative = resolveVaultNotePath(input.vault.dailyNotePath, input.date, {
|
|
29531
29687
|
timezone: input.timezone
|
|
29532
29688
|
});
|
|
29533
|
-
const root =
|
|
29534
|
-
const filePath =
|
|
29689
|
+
const root = path36.resolve(expandTildePath(input.vault.vaultPath));
|
|
29690
|
+
const filePath = path36.join(root, relative);
|
|
29535
29691
|
try {
|
|
29536
29692
|
const rootStat = lstatSync(root);
|
|
29537
29693
|
if (rootStat.isSymbolicLink() || !rootStat.isDirectory()) {
|
|
@@ -29540,8 +29696,8 @@ function readJournalForDate(input) {
|
|
|
29540
29696
|
} catch {
|
|
29541
29697
|
return { ok: true, exists: false, reason: "missing_file", filePath };
|
|
29542
29698
|
}
|
|
29543
|
-
const lexical =
|
|
29544
|
-
if (lexical.length === 0 || lexical === ".." || lexical.startsWith(`..${
|
|
29699
|
+
const lexical = path36.relative(root, filePath);
|
|
29700
|
+
if (lexical.length === 0 || lexical === ".." || lexical.startsWith(`..${path36.sep}`) || path36.isAbsolute(lexical)) {
|
|
29545
29701
|
return { ok: false, reason: "path_escape", filePath };
|
|
29546
29702
|
}
|
|
29547
29703
|
if (!containedBySymlinks(root, filePath)) {
|
|
@@ -29574,11 +29730,11 @@ function containedBySymlinks(root, dest) {
|
|
|
29574
29730
|
try {
|
|
29575
29731
|
if (statSync2(probe).isFile() || statSync2(probe).isDirectory()) {
|
|
29576
29732
|
const real = realpathSync(probe);
|
|
29577
|
-
return real === realRoot || real.startsWith(`${realRoot}${
|
|
29733
|
+
return real === realRoot || real.startsWith(`${realRoot}${path36.sep}`);
|
|
29578
29734
|
}
|
|
29579
29735
|
} catch {
|
|
29580
29736
|
}
|
|
29581
|
-
const parent =
|
|
29737
|
+
const parent = path36.dirname(probe);
|
|
29582
29738
|
if (parent === probe) return false;
|
|
29583
29739
|
probe = parent;
|
|
29584
29740
|
}
|
|
@@ -29589,15 +29745,15 @@ function symlinkRejected() {
|
|
|
29589
29745
|
return err;
|
|
29590
29746
|
}
|
|
29591
29747
|
function readVerifiedDailyNote(root, filePath) {
|
|
29592
|
-
const relative =
|
|
29593
|
-
const parts = relative.split(
|
|
29748
|
+
const relative = path36.relative(root, filePath);
|
|
29749
|
+
const parts = relative.split(path36.sep).filter((part) => part.length > 0 && part !== ".");
|
|
29594
29750
|
let cursor = root;
|
|
29595
29751
|
for (const part of parts) {
|
|
29596
|
-
cursor =
|
|
29752
|
+
cursor = path36.join(cursor, part);
|
|
29597
29753
|
const st = lstatSync(cursor);
|
|
29598
29754
|
if (st.isSymbolicLink()) throw symlinkRejected();
|
|
29599
29755
|
}
|
|
29600
|
-
const parent =
|
|
29756
|
+
const parent = path36.dirname(filePath);
|
|
29601
29757
|
const parentLstat = lstatSync(parent);
|
|
29602
29758
|
if (parentLstat.isSymbolicLink() || !parentLstat.isDirectory()) throw symlinkRejected();
|
|
29603
29759
|
const nofollow = fsConstants.O_NOFOLLOW ?? 0;
|
|
@@ -29621,7 +29777,7 @@ function readVerifiedDailyNote(root, filePath) {
|
|
|
29621
29777
|
try {
|
|
29622
29778
|
const fdPath = realpathSync(`/proc/self/fd/${fd}`);
|
|
29623
29779
|
const realRoot = realpathSync(root);
|
|
29624
|
-
if (fdPath !== realRoot && !fdPath.startsWith(`${realRoot}${
|
|
29780
|
+
if (fdPath !== realRoot && !fdPath.startsWith(`${realRoot}${path36.sep}`)) {
|
|
29625
29781
|
throw symlinkRejected();
|
|
29626
29782
|
}
|
|
29627
29783
|
} catch (err) {
|
|
@@ -29636,11 +29792,11 @@ function readVerifiedDailyNote(root, filePath) {
|
|
|
29636
29792
|
// src/activity/journal-state.ts
|
|
29637
29793
|
import { createHash as createHash11, randomBytes as randomBytes4 } from "crypto";
|
|
29638
29794
|
import { mkdirSync as mkdirSync2, readFileSync as readFileSync4, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
29639
|
-
import
|
|
29795
|
+
import path37 from "path";
|
|
29640
29796
|
var STATE_DIR_NAME = "state";
|
|
29641
29797
|
var STATE_FILE_NAME = "timeline.json";
|
|
29642
29798
|
function timelineStatePath(memoryDir) {
|
|
29643
|
-
return
|
|
29799
|
+
return path37.join(memoryDir, STATE_DIR_NAME, STATE_FILE_NAME);
|
|
29644
29800
|
}
|
|
29645
29801
|
function hashJournalText(text) {
|
|
29646
29802
|
return createHash11("sha256").update(text, "utf8").digest("hex");
|
|
@@ -29666,14 +29822,14 @@ function readTimelineState(memoryDir) {
|
|
|
29666
29822
|
}
|
|
29667
29823
|
function writeTimelineState(memoryDir, state) {
|
|
29668
29824
|
const filePath = timelineStatePath(memoryDir);
|
|
29669
|
-
mkdirSync2(
|
|
29825
|
+
mkdirSync2(path37.dirname(filePath), { recursive: true });
|
|
29670
29826
|
const tempPath = `${filePath}.${process.pid}.${randomBytes4(8).toString("hex")}.tmp`;
|
|
29671
29827
|
writeFileSync2(tempPath, `${JSON.stringify(state, null, 2)}
|
|
29672
29828
|
`);
|
|
29673
29829
|
renameSync2(tempPath, filePath);
|
|
29674
29830
|
}
|
|
29675
29831
|
function journalDateLockPath(memoryDir, date) {
|
|
29676
|
-
return
|
|
29832
|
+
return path37.join(memoryDir, STATE_DIR_NAME, `journal-extract-${date}.lock`);
|
|
29677
29833
|
}
|
|
29678
29834
|
function timelineStateLockPath(memoryDir) {
|
|
29679
29835
|
return `${timelineStatePath(memoryDir)}.lock`;
|
|
@@ -30381,7 +30537,7 @@ function normalizeDropKeys(keys) {
|
|
|
30381
30537
|
}
|
|
30382
30538
|
|
|
30383
30539
|
// src/activity/vault-wikilink.ts
|
|
30384
|
-
import
|
|
30540
|
+
import path38 from "path";
|
|
30385
30541
|
function formatVaultWikilink(notePath) {
|
|
30386
30542
|
if (typeof notePath !== "string" || notePath.trim().length === 0) {
|
|
30387
30543
|
throw new RangeError("Vault wikilink path must be a non-empty relative path.");
|
|
@@ -30389,7 +30545,7 @@ function formatVaultWikilink(notePath) {
|
|
|
30389
30545
|
if (notePath.includes("\n") || notePath.includes("\r")) {
|
|
30390
30546
|
throw new RangeError("Vault wikilink path must not contain newlines.");
|
|
30391
30547
|
}
|
|
30392
|
-
if (
|
|
30548
|
+
if (path38.posix.isAbsolute(notePath) || path38.win32.isAbsolute(notePath)) {
|
|
30393
30549
|
throw new RangeError("Vault wikilink path must be relative; absolute paths are rejected.");
|
|
30394
30550
|
}
|
|
30395
30551
|
if (notePath.split(/[\\/]/).some((segment) => segment === "..")) {
|
|
@@ -30411,7 +30567,7 @@ function stripVaultMdSuffix(notePath) {
|
|
|
30411
30567
|
}
|
|
30412
30568
|
|
|
30413
30569
|
// src/activity/vault-join.ts
|
|
30414
|
-
import
|
|
30570
|
+
import path39 from "path";
|
|
30415
30571
|
function joinVaultSegments(parts) {
|
|
30416
30572
|
if (parts.length === 0) {
|
|
30417
30573
|
throw new RangeError("Vault path parts must be a non-empty list.");
|
|
@@ -30426,7 +30582,7 @@ function joinVaultSegments(parts) {
|
|
|
30426
30582
|
if (part.includes("\n") || part.includes("\r")) {
|
|
30427
30583
|
throw new RangeError("Vault path part must not contain a newline.");
|
|
30428
30584
|
}
|
|
30429
|
-
if (
|
|
30585
|
+
if (path39.posix.isAbsolute(part) || path39.win32.isAbsolute(part)) {
|
|
30430
30586
|
throw new RangeError("Vault path part must be relative.");
|
|
30431
30587
|
}
|
|
30432
30588
|
if (part.split("/").includes("..")) {
|
|
@@ -30481,7 +30637,7 @@ function planVaultDryRun(inputs) {
|
|
|
30481
30637
|
// src/session-summaries/index.ts
|
|
30482
30638
|
import { createHash as createHash12 } from "crypto";
|
|
30483
30639
|
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
|
|
30640
|
+
import path40 from "path";
|
|
30485
30641
|
|
|
30486
30642
|
// src/session-summaries/adapters.ts
|
|
30487
30643
|
var VALID_ROLES = /* @__PURE__ */ new Set(["user", "assistant", "tool", "system", "other"]);
|
|
@@ -30986,7 +31142,7 @@ function shortHash(value, length = 16) {
|
|
|
30986
31142
|
async function listTranscriptFiles(root, maxFiles) {
|
|
30987
31143
|
const out = [];
|
|
30988
31144
|
let truncated = false;
|
|
30989
|
-
const entrySortKey = (entryName, isDirectory) => isDirectory ? `${entryName}${
|
|
31145
|
+
const entrySortKey = (entryName, isDirectory) => isDirectory ? `${entryName}${path40.sep}` : entryName;
|
|
30990
31146
|
async function visit(dir) {
|
|
30991
31147
|
if (truncated) return;
|
|
30992
31148
|
const entries = (await readdir4(dir, { withFileTypes: true })).sort(
|
|
@@ -30996,13 +31152,13 @@ async function listTranscriptFiles(root, maxFiles) {
|
|
|
30996
31152
|
if (truncated) return;
|
|
30997
31153
|
if (entry.name.startsWith(".")) continue;
|
|
30998
31154
|
if (entry.isSymbolicLink()) continue;
|
|
30999
|
-
const fullPath =
|
|
31155
|
+
const fullPath = path40.join(dir, entry.name);
|
|
31000
31156
|
if (entry.isDirectory()) {
|
|
31001
31157
|
await visit(fullPath);
|
|
31002
31158
|
continue;
|
|
31003
31159
|
}
|
|
31004
31160
|
if (!entry.isFile()) continue;
|
|
31005
|
-
const ext =
|
|
31161
|
+
const ext = path40.extname(entry.name).toLowerCase();
|
|
31006
31162
|
if (!SUPPORTED_EXTENSIONS.has(ext)) continue;
|
|
31007
31163
|
out.push(fullPath);
|
|
31008
31164
|
if (out.length > maxFiles) {
|
|
@@ -31029,7 +31185,7 @@ function normalizeInputDir(inputDir) {
|
|
|
31029
31185
|
if (typeof inputDir !== "string" || inputDir.trim().length === 0) {
|
|
31030
31186
|
throw new Error("inputDir must be a non-empty string");
|
|
31031
31187
|
}
|
|
31032
|
-
return
|
|
31188
|
+
return path40.resolve(expandTildePath(inputDir.trim()));
|
|
31033
31189
|
}
|
|
31034
31190
|
function initRoleCounts() {
|
|
31035
31191
|
return {
|
|
@@ -31186,11 +31342,11 @@ async function collectLocalSessionSummaries(options) {
|
|
|
31186
31342
|
continue;
|
|
31187
31343
|
}
|
|
31188
31344
|
seenFileHashes.add(fileHash);
|
|
31189
|
-
const fileExtension =
|
|
31345
|
+
const fileExtension = path40.extname(filePath).toLowerCase();
|
|
31190
31346
|
const parsed = await adapter.parseFile(
|
|
31191
31347
|
{
|
|
31192
31348
|
content,
|
|
31193
|
-
fileName:
|
|
31349
|
+
fileName: path40.basename(filePath),
|
|
31194
31350
|
fileExtension,
|
|
31195
31351
|
fileRef: fileHash
|
|
31196
31352
|
},
|
|
@@ -31246,7 +31402,7 @@ async function collectLocalSessionSummaries(options) {
|
|
|
31246
31402
|
}
|
|
31247
31403
|
async function readRedactionConfig(pathLike) {
|
|
31248
31404
|
if (!pathLike) return void 0;
|
|
31249
|
-
const raw = await readFile9(
|
|
31405
|
+
const raw = await readFile9(path40.resolve(expandTildePath(pathLike)), "utf-8");
|
|
31250
31406
|
const parsed = JSON.parse(raw);
|
|
31251
31407
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
31252
31408
|
throw new Error("redaction config must be a JSON object");
|
|
@@ -31259,15 +31415,15 @@ function toJsonl(drafts) {
|
|
|
31259
31415
|
}
|
|
31260
31416
|
function defaultDraftOutputPath(memoryDir, generatedAt) {
|
|
31261
31417
|
const stamp = generatedAt.replace(/[:.]/g, "-");
|
|
31262
|
-
return
|
|
31263
|
-
|
|
31418
|
+
return path40.join(
|
|
31419
|
+
path40.resolve(expandTildePath(memoryDir)),
|
|
31264
31420
|
"state",
|
|
31265
31421
|
"session-summary-drafts",
|
|
31266
31422
|
`session-summaries-${stamp}.jsonl`
|
|
31267
31423
|
);
|
|
31268
31424
|
}
|
|
31269
31425
|
async function writeDrafts(filePath, drafts) {
|
|
31270
|
-
await mkdir7(
|
|
31426
|
+
await mkdir7(path40.dirname(filePath), { recursive: true });
|
|
31271
31427
|
const tempPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
|
|
31272
31428
|
try {
|
|
31273
31429
|
await writeFile7(tempPath, toJsonl(drafts), "utf-8");
|
|
@@ -31285,7 +31441,7 @@ async function runLocalSessionSummaryCliCommand(options) {
|
|
|
31285
31441
|
});
|
|
31286
31442
|
const wroteFiles = [];
|
|
31287
31443
|
if (options.output) {
|
|
31288
|
-
const outputPath =
|
|
31444
|
+
const outputPath = path40.resolve(expandTildePath(options.output));
|
|
31289
31445
|
await writeDrafts(outputPath, report.drafts);
|
|
31290
31446
|
wroteFiles.push(outputPath);
|
|
31291
31447
|
}
|
|
@@ -31320,19 +31476,19 @@ async function runLocalSessionSummaryCliCommand(options) {
|
|
|
31320
31476
|
|
|
31321
31477
|
// src/transfer/capsule-fork.ts
|
|
31322
31478
|
import { lstat as lstat4, mkdir as mkdir8, readFile as readFile10, realpath as realpath3, writeFile as writeFile8 } from "fs/promises";
|
|
31323
|
-
import
|
|
31479
|
+
import path41 from "path";
|
|
31324
31480
|
async function forkCapsule(opts) {
|
|
31325
31481
|
validateForkId(opts.forkId);
|
|
31326
|
-
const rootAbs =
|
|
31482
|
+
const rootAbs = path41.resolve(opts.targetRoot);
|
|
31327
31483
|
await assertIsDirectoryNotSymlink(rootAbs, "forkCapsule", "targetRoot");
|
|
31328
|
-
const forkDirAbs =
|
|
31484
|
+
const forkDirAbs = path41.join(rootAbs, "forks", opts.forkId);
|
|
31329
31485
|
const forkEntryExists = await pathEntryExists(forkDirAbs);
|
|
31330
31486
|
if (forkEntryExists) {
|
|
31331
31487
|
throw new Error(
|
|
31332
31488
|
`forkCapsule: fork path already exists \u2014 forkId "${opts.forkId}" is already in use at: ${forkDirAbs}`
|
|
31333
31489
|
);
|
|
31334
31490
|
}
|
|
31335
|
-
const archiveAbs =
|
|
31491
|
+
const archiveAbs = path41.resolve(opts.sourceArchive);
|
|
31336
31492
|
const importResult = await importCapsule({
|
|
31337
31493
|
archivePath: archiveAbs,
|
|
31338
31494
|
root: rootAbs,
|
|
@@ -31354,10 +31510,10 @@ async function forkCapsule(opts) {
|
|
|
31354
31510
|
importedRecords: importResult.imported.length,
|
|
31355
31511
|
skippedRecords: importResult.skipped.length
|
|
31356
31512
|
};
|
|
31357
|
-
const lineagePath =
|
|
31513
|
+
const lineagePath = path41.join(forkDirAbs, "lineage.json");
|
|
31358
31514
|
const rootReal = await realpath3(rootAbs);
|
|
31359
31515
|
await assertRealpathInsideRoot(rootReal, lineagePath, `forks/${opts.forkId}/lineage.json`, "forkCapsule");
|
|
31360
|
-
await mkdir8(
|
|
31516
|
+
await mkdir8(path41.dirname(lineagePath), { recursive: true });
|
|
31361
31517
|
await writeFile8(lineagePath, JSON.stringify(lineage, null, 2) + "\n", "utf-8");
|
|
31362
31518
|
return {
|
|
31363
31519
|
archivePath: archiveAbs,
|
|
@@ -31371,11 +31527,11 @@ async function readForkLineage(targetRoot, forkId) {
|
|
|
31371
31527
|
if (typeof forkId !== "string" || forkId.length === 0 || forkId.length > 64 || !CAPSULE_ID_PATTERN.test(forkId)) {
|
|
31372
31528
|
return null;
|
|
31373
31529
|
}
|
|
31374
|
-
const rootAbs =
|
|
31530
|
+
const rootAbs = path41.resolve(targetRoot);
|
|
31375
31531
|
const rootReal = await realpath3(rootAbs).catch(() => rootAbs);
|
|
31376
|
-
const lineagePath =
|
|
31377
|
-
const rel =
|
|
31378
|
-
if (rel.startsWith("..") ||
|
|
31532
|
+
const lineagePath = path41.join(rootReal, "forks", forkId, "lineage.json");
|
|
31533
|
+
const rel = path41.relative(rootReal, lineagePath);
|
|
31534
|
+
if (rel.startsWith("..") || path41.isAbsolute(rel)) {
|
|
31379
31535
|
return null;
|
|
31380
31536
|
}
|
|
31381
31537
|
if (!await isLineagePathContained(rootReal, lineagePath)) {
|
|
@@ -31416,19 +31572,19 @@ async function pathEntryExists(absPath) {
|
|
|
31416
31572
|
async function isLineagePathContained(rootReal, lineagePath) {
|
|
31417
31573
|
let existing = lineagePath;
|
|
31418
31574
|
const suffix = [];
|
|
31419
|
-
while (existing !==
|
|
31575
|
+
while (existing !== path41.dirname(existing)) {
|
|
31420
31576
|
const st = await lstat4(existing).catch(() => null);
|
|
31421
31577
|
if (st !== null) break;
|
|
31422
|
-
suffix.unshift(
|
|
31423
|
-
existing =
|
|
31578
|
+
suffix.unshift(path41.basename(existing));
|
|
31579
|
+
existing = path41.dirname(existing);
|
|
31424
31580
|
}
|
|
31425
31581
|
const existingReal = await realpath3(existing).catch(() => existing);
|
|
31426
|
-
const targetReal = suffix.length > 0 ?
|
|
31427
|
-
const rel =
|
|
31582
|
+
const targetReal = suffix.length > 0 ? path41.join(existingReal, ...suffix) : existingReal;
|
|
31583
|
+
const rel = path41.relative(rootReal, targetReal);
|
|
31428
31584
|
if (rel === "") return true;
|
|
31429
31585
|
if (rel === "..") return false;
|
|
31430
|
-
if (rel.startsWith(`..${
|
|
31431
|
-
if (
|
|
31586
|
+
if (rel.startsWith(`..${path41.sep}`)) return false;
|
|
31587
|
+
if (path41.isAbsolute(rel)) return false;
|
|
31432
31588
|
return true;
|
|
31433
31589
|
}
|
|
31434
31590
|
|
|
@@ -31621,4 +31777,4 @@ export {
|
|
|
31621
31777
|
qmdStartupCollectionChecksWithTimeout,
|
|
31622
31778
|
Orchestrator
|
|
31623
31779
|
};
|
|
31624
|
-
//# sourceMappingURL=chunk-
|
|
31780
|
+
//# sourceMappingURL=chunk-LFYEQK45.js.map
|