@hasna/mementos 0.14.84 → 0.14.86
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/bun.lock +63 -4
- package/dist/cli/index.js +769 -261
- package/dist/diagnostics/historical-project-registration-receipt.js +1675 -0
- package/dist/index.js +343 -85
- package/dist/mcp/index.js +419 -99
- package/dist/pg-sync-worker.js +7 -5
- package/dist/project-registration.js +309 -68
- package/dist/sdk/index.js +123 -30
- package/dist/server/index.js +677 -317
- package/dist/storage.js +63 -26
- package/hasna.contract.json +5 -4
- package/package.json +6 -4
- package/dist/cli/__fixtures__/clean-fallback-stub-server.d.ts +0 -2
- package/dist/cli/__fixtures__/clean-fallback-stub-server.d.ts.map +0 -1
- package/dist/cli/brains.d.ts +0 -3
- package/dist/cli/brains.d.ts.map +0 -1
- package/dist/cli/commands/agent.d.ts +0 -3
- package/dist/cli/commands/agent.d.ts.map +0 -1
- package/dist/cli/commands/consolidation.d.ts +0 -3
- package/dist/cli/commands/consolidation.d.ts.map +0 -1
- package/dist/cli/commands/entity.d.ts +0 -3
- package/dist/cli/commands/entity.d.ts.map +0 -1
- package/dist/cli/commands/graph.d.ts +0 -3
- package/dist/cli/commands/graph.d.ts.map +0 -1
- package/dist/cli/commands/info-context.d.ts +0 -3
- package/dist/cli/commands/info-context.d.ts.map +0 -1
- package/dist/cli/commands/info-history.d.ts +0 -3
- package/dist/cli/commands/info-history.d.ts.map +0 -1
- package/dist/cli/commands/info-report.d.ts +0 -3
- package/dist/cli/commands/info-report.d.ts.map +0 -1
- package/dist/cli/commands/info-stale.d.ts +0 -3
- package/dist/cli/commands/info-stale.d.ts.map +0 -1
- package/dist/cli/commands/info-stats.d.ts +0 -3
- package/dist/cli/commands/info-stats.d.ts.map +0 -1
- package/dist/cli/commands/info.d.ts +0 -12
- package/dist/cli/commands/info.d.ts.map +0 -1
- package/dist/cli/commands/init.d.ts +0 -3
- package/dist/cli/commands/init.d.ts.map +0 -1
- package/dist/cli/commands/io-backup.d.ts +0 -3
- package/dist/cli/commands/io-backup.d.ts.map +0 -1
- package/dist/cli/commands/io-clean.d.ts +0 -3
- package/dist/cli/commands/io-clean.d.ts.map +0 -1
- package/dist/cli/commands/io-export.d.ts +0 -3
- package/dist/cli/commands/io-export.d.ts.map +0 -1
- package/dist/cli/commands/io-import.d.ts +0 -3
- package/dist/cli/commands/io-import.d.ts.map +0 -1
- package/dist/cli/commands/io-restore.d.ts +0 -3
- package/dist/cli/commands/io-restore.d.ts.map +0 -1
- package/dist/cli/commands/io.d.ts +0 -12
- package/dist/cli/commands/io.d.ts.map +0 -1
- package/dist/cli/commands/memory-cmd-bulk.d.ts +0 -3
- package/dist/cli/commands/memory-cmd-bulk.d.ts.map +0 -1
- package/dist/cli/commands/memory-cmd-chain.d.ts +0 -3
- package/dist/cli/commands/memory-cmd-chain.d.ts.map +0 -1
- package/dist/cli/commands/memory-cmd-crud.d.ts +0 -3
- package/dist/cli/commands/memory-cmd-crud.d.ts.map +0 -1
- package/dist/cli/commands/memory-cmd-diff.d.ts +0 -3
- package/dist/cli/commands/memory-cmd-diff.d.ts.map +0 -1
- package/dist/cli/commands/memory-cmd-list.d.ts +0 -3
- package/dist/cli/commands/memory-cmd-list.d.ts.map +0 -1
- package/dist/cli/commands/memory-cmd-recall-exit.d.ts +0 -3
- package/dist/cli/commands/memory-cmd-recall-exit.d.ts.map +0 -1
- package/dist/cli/commands/memory-cmd-recall.d.ts +0 -3
- package/dist/cli/commands/memory-cmd-recall.d.ts.map +0 -1
- package/dist/cli/commands/memory-cmd-remove.d.ts +0 -3
- package/dist/cli/commands/memory-cmd-remove.d.ts.map +0 -1
- package/dist/cli/commands/memory-cmd-search.d.ts +0 -3
- package/dist/cli/commands/memory-cmd-search.d.ts.map +0 -1
- package/dist/cli/commands/memory-cmd-tail.d.ts +0 -3
- package/dist/cli/commands/memory-cmd-tail.d.ts.map +0 -1
- package/dist/cli/commands/memory-cmd-util.d.ts +0 -3
- package/dist/cli/commands/memory-cmd-util.d.ts.map +0 -1
- package/dist/cli/commands/memory-cmd-view.d.ts +0 -3
- package/dist/cli/commands/memory-cmd-view.d.ts.map +0 -1
- package/dist/cli/commands/memory-cmd-watch.d.ts +0 -3
- package/dist/cli/commands/memory-cmd-watch.d.ts.map +0 -1
- package/dist/cli/commands/memory-cmd-when-to-use.d.ts +0 -3
- package/dist/cli/commands/memory-cmd-when-to-use.d.ts.map +0 -1
- package/dist/cli/commands/memory.d.ts +0 -3
- package/dist/cli/commands/memory.d.ts.map +0 -1
- package/dist/cli/commands/project-panel.d.ts +0 -3
- package/dist/cli/commands/project-panel.d.ts.map +0 -1
- package/dist/cli/commands/project.d.ts +0 -3
- package/dist/cli/commands/project.d.ts.map +0 -1
- package/dist/cli/commands/relation.d.ts +0 -3
- package/dist/cli/commands/relation.d.ts.map +0 -1
- package/dist/cli/commands/storage.d.ts +0 -3
- package/dist/cli/commands/storage.d.ts.map +0 -1
- package/dist/cli/commands/system-auto-memory.d.ts +0 -3
- package/dist/cli/commands/system-auto-memory.d.ts.map +0 -1
- package/dist/cli/commands/system-completions.d.ts +0 -13
- package/dist/cli/commands/system-completions.d.ts.map +0 -1
- package/dist/cli/commands/system-config.d.ts +0 -3
- package/dist/cli/commands/system-config.d.ts.map +0 -1
- package/dist/cli/commands/system-doctor.d.ts +0 -3
- package/dist/cli/commands/system-doctor.d.ts.map +0 -1
- package/dist/cli/commands/system-hooks.d.ts +0 -3
- package/dist/cli/commands/system-hooks.d.ts.map +0 -1
- package/dist/cli/commands/system-mcp.d.ts +0 -3
- package/dist/cli/commands/system-mcp.d.ts.map +0 -1
- package/dist/cli/commands/system-misc.d.ts +0 -3
- package/dist/cli/commands/system-misc.d.ts.map +0 -1
- package/dist/cli/commands/system-profile.d.ts +0 -3
- package/dist/cli/commands/system-profile.d.ts.map +0 -1
- package/dist/cli/commands/system-session.d.ts +0 -3
- package/dist/cli/commands/system-session.d.ts.map +0 -1
- package/dist/cli/commands/system-sessions.d.ts +0 -3
- package/dist/cli/commands/system-sessions.d.ts.map +0 -1
- package/dist/cli/commands/system-synthesis.d.ts +0 -3
- package/dist/cli/commands/system-synthesis.d.ts.map +0 -1
- package/dist/cli/commands/system-synthesized-profile.d.ts +0 -3
- package/dist/cli/commands/system-synthesized-profile.d.ts.map +0 -1
- package/dist/cli/commands/system-tools.d.ts +0 -3
- package/dist/cli/commands/system-tools.d.ts.map +0 -1
- package/dist/cli/commands/system-watch.d.ts +0 -3
- package/dist/cli/commands/system-watch.d.ts.map +0 -1
- package/dist/cli/commands/system.d.ts +0 -3
- package/dist/cli/commands/system.d.ts.map +0 -1
- package/dist/cli/exit-codes.d.ts +0 -13
- package/dist/cli/exit-codes.d.ts.map +0 -1
- package/dist/cli/global-options.d.ts +0 -27
- package/dist/cli/global-options.d.ts.map +0 -1
- package/dist/cli/helpers.d.ts +0 -119
- package/dist/cli/helpers.d.ts.map +0 -1
- package/dist/cli/index.d.ts +0 -3
- package/dist/cli/index.d.ts.map +0 -1
- package/dist/cli/register-all.d.ts +0 -17
- package/dist/cli/register-all.d.ts.map +0 -1
- package/dist/cli/startup-side-effects.d.ts +0 -9
- package/dist/cli/startup-side-effects.d.ts.map +0 -1
- package/dist/db/__fixtures__/fail-closed-stub-server.d.ts +0 -2
- package/dist/db/__fixtures__/fail-closed-stub-server.d.ts.map +0 -1
- package/dist/db/acl.d.ts +0 -34
- package/dist/db/acl.d.ts.map +0 -1
- package/dist/db/agents.d.ts +0 -21
- package/dist/db/agents.d.ts.map +0 -1
- package/dist/db/analytics.d.ts +0 -107
- package/dist/db/analytics.d.ts.map +0 -1
- package/dist/db/api-mode.d.ts +0 -127
- package/dist/db/api-mode.d.ts.map +0 -1
- package/dist/db/audit.d.ts +0 -53
- package/dist/db/audit.d.ts.map +0 -1
- package/dist/db/database.d.ts +0 -26
- package/dist/db/database.d.ts.map +0 -1
- package/dist/db/entities.d.ts +0 -62
- package/dist/db/entities.d.ts.map +0 -1
- package/dist/db/entity-memories.d.ts +0 -34
- package/dist/db/entity-memories.d.ts.map +0 -1
- package/dist/db/feedback.d.ts +0 -9
- package/dist/db/feedback.d.ts.map +0 -1
- package/dist/db/locks.d.ts +0 -63
- package/dist/db/locks.d.ts.map +0 -1
- package/dist/db/machines.d.ts +0 -23
- package/dist/db/machines.d.ts.map +0 -1
- package/dist/db/memories.d.ts +0 -137
- package/dist/db/memories.d.ts.map +0 -1
- package/dist/db/memory-links.d.ts +0 -21
- package/dist/db/memory-links.d.ts.map +0 -1
- package/dist/db/memory-project-link.d.ts +0 -13
- package/dist/db/memory-project-link.d.ts.map +0 -1
- package/dist/db/migrations.d.ts +0 -3
- package/dist/db/migrations.d.ts.map +0 -1
- package/dist/db/pg-migrate.d.ts +0 -27
- package/dist/db/pg-migrate.d.ts.map +0 -1
- package/dist/db/pg-migrations.d.ts +0 -2
- package/dist/db/pg-migrations.d.ts.map +0 -1
- package/dist/db/projects.d.ts +0 -27
- package/dist/db/projects.d.ts.map +0 -1
- package/dist/db/ratings.d.ts +0 -23
- package/dist/db/ratings.d.ts.map +0 -1
- package/dist/db/relations.d.ts +0 -49
- package/dist/db/relations.d.ts.map +0 -1
- package/dist/db/session-jobs.d.ts +0 -49
- package/dist/db/session-jobs.d.ts.map +0 -1
- package/dist/db/store-backend.d.ts +0 -42
- package/dist/db/store-backend.d.ts.map +0 -1
- package/dist/db/subscriptions.d.ts +0 -24
- package/dist/db/subscriptions.d.ts.map +0 -1
- package/dist/db/synthesis.d.ts +0 -101
- package/dist/db/synthesis.d.ts.map +0 -1
- package/dist/db/tasks.d.ts +0 -89
- package/dist/db/tasks.d.ts.map +0 -1
- package/dist/db/tool-events.d.ts +0 -27
- package/dist/db/tool-events.d.ts.map +0 -1
- package/dist/db/webhook_hooks.d.ts +0 -25
- package/dist/db/webhook_hooks.d.ts.map +0 -1
- package/dist/generated/storage-kit/backend.d.ts +0 -20
- package/dist/generated/storage-kit/backend.d.ts.map +0 -1
- package/dist/generated/storage-kit/health.d.ts +0 -20
- package/dist/generated/storage-kit/health.d.ts.map +0 -1
- package/dist/generated/storage-kit/index.d.ts +0 -8
- package/dist/generated/storage-kit/index.d.ts.map +0 -1
- package/dist/generated/storage-kit/migrations.d.ts +0 -48
- package/dist/generated/storage-kit/migrations.d.ts.map +0 -1
- package/dist/generated/storage-kit/own.d.ts +0 -11
- package/dist/generated/storage-kit/own.d.ts.map +0 -1
- package/dist/generated/storage-kit/pool.d.ts +0 -35
- package/dist/generated/storage-kit/pool.d.ts.map +0 -1
- package/dist/generated/storage-kit/query.d.ts +0 -36
- package/dist/generated/storage-kit/query.d.ts.map +0 -1
- package/dist/generated/storage-kit/tls.d.ts +0 -53
- package/dist/generated/storage-kit/tls.d.ts.map +0 -1
- package/dist/index.d.ts +0 -45
- package/dist/index.d.ts.map +0 -1
- package/dist/lib/activation-matcher.d.ts +0 -17
- package/dist/lib/activation-matcher.d.ts.map +0 -1
- package/dist/lib/asmr/categorizer.d.ts +0 -31
- package/dist/lib/asmr/categorizer.d.ts.map +0 -1
- package/dist/lib/asmr/context-agent.d.ts +0 -4
- package/dist/lib/asmr/context-agent.d.ts.map +0 -1
- package/dist/lib/asmr/ensemble.d.ts +0 -23
- package/dist/lib/asmr/ensemble.d.ts.map +0 -1
- package/dist/lib/asmr/fact-agent.d.ts +0 -4
- package/dist/lib/asmr/fact-agent.d.ts.map +0 -1
- package/dist/lib/asmr/index.d.ts +0 -7
- package/dist/lib/asmr/index.d.ts.map +0 -1
- package/dist/lib/asmr/orchestrator.d.ts +0 -4
- package/dist/lib/asmr/orchestrator.d.ts.map +0 -1
- package/dist/lib/asmr/recall.d.ts +0 -3
- package/dist/lib/asmr/recall.d.ts.map +0 -1
- package/dist/lib/asmr/temporal-agent.d.ts +0 -4
- package/dist/lib/asmr/temporal-agent.d.ts.map +0 -1
- package/dist/lib/asmr/types.d.ts +0 -27
- package/dist/lib/asmr/types.d.ts.map +0 -1
- package/dist/lib/auto-inject-orchestrator.d.ts +0 -57
- package/dist/lib/auto-inject-orchestrator.d.ts.map +0 -1
- package/dist/lib/auto-memory-queue.d.ts +0 -48
- package/dist/lib/auto-memory-queue.d.ts.map +0 -1
- package/dist/lib/auto-memory.d.ts +0 -19
- package/dist/lib/auto-memory.d.ts.map +0 -1
- package/dist/lib/bench.d.ts +0 -20
- package/dist/lib/bench.d.ts.map +0 -1
- package/dist/lib/built-in-hooks.d.ts +0 -12
- package/dist/lib/built-in-hooks.d.ts.map +0 -1
- package/dist/lib/channel-pusher.d.ts +0 -39
- package/dist/lib/channel-pusher.d.ts.map +0 -1
- package/dist/lib/config.d.ts +0 -9
- package/dist/lib/config.d.ts.map +0 -1
- package/dist/lib/connectors/files.d.ts +0 -8
- package/dist/lib/connectors/files.d.ts.map +0 -1
- package/dist/lib/connectors/github.d.ts +0 -7
- package/dist/lib/connectors/github.d.ts.map +0 -1
- package/dist/lib/connectors/index.d.ts +0 -12
- package/dist/lib/connectors/index.d.ts.map +0 -1
- package/dist/lib/connectors/notion.d.ts +0 -7
- package/dist/lib/connectors/notion.d.ts.map +0 -1
- package/dist/lib/connectors/types.d.ts +0 -27
- package/dist/lib/connectors/types.d.ts.map +0 -1
- package/dist/lib/consolidation.d.ts +0 -52
- package/dist/lib/consolidation.d.ts.map +0 -1
- package/dist/lib/context-extractor.d.ts +0 -14
- package/dist/lib/context-extractor.d.ts.map +0 -1
- package/dist/lib/context.d.ts +0 -36
- package/dist/lib/context.d.ts.map +0 -1
- package/dist/lib/contradiction.d.ts +0 -50
- package/dist/lib/contradiction.d.ts.map +0 -1
- package/dist/lib/decay.d.ts +0 -35
- package/dist/lib/decay.d.ts.map +0 -1
- package/dist/lib/dedup.d.ts +0 -33
- package/dist/lib/dedup.d.ts.map +0 -1
- package/dist/lib/duration.d.ts +0 -28
- package/dist/lib/duration.d.ts.map +0 -1
- package/dist/lib/embeddings.d.ts +0 -20
- package/dist/lib/embeddings.d.ts.map +0 -1
- package/dist/lib/enum-validation.d.ts +0 -20
- package/dist/lib/enum-validation.d.ts.map +0 -1
- package/dist/lib/export-v1.d.ts +0 -30
- package/dist/lib/export-v1.d.ts.map +0 -1
- package/dist/lib/extractor.d.ts +0 -9
- package/dist/lib/extractor.d.ts.map +0 -1
- package/dist/lib/extractors/audio.d.ts +0 -8
- package/dist/lib/extractors/audio.d.ts.map +0 -1
- package/dist/lib/extractors/index.d.ts +0 -12
- package/dist/lib/extractors/index.d.ts.map +0 -1
- package/dist/lib/extractors/ocr.d.ts +0 -7
- package/dist/lib/extractors/ocr.d.ts.map +0 -1
- package/dist/lib/extractors/pdf.d.ts +0 -7
- package/dist/lib/extractors/pdf.d.ts.map +0 -1
- package/dist/lib/extractors/types.d.ts +0 -12
- package/dist/lib/extractors/types.d.ts.map +0 -1
- package/dist/lib/file-deps.d.ts +0 -27
- package/dist/lib/file-deps.d.ts.map +0 -1
- package/dist/lib/focus.d.ts +0 -58
- package/dist/lib/focus.d.ts.map +0 -1
- package/dist/lib/gatherer.d.ts +0 -16
- package/dist/lib/gatherer.d.ts.map +0 -1
- package/dist/lib/gdpr.d.ts +0 -39
- package/dist/lib/gdpr.d.ts.map +0 -1
- package/dist/lib/hooks.d.ts +0 -50
- package/dist/lib/hooks.d.ts.map +0 -1
- package/dist/lib/importers/index.d.ts +0 -38
- package/dist/lib/importers/index.d.ts.map +0 -1
- package/dist/lib/injector.d.ts +0 -89
- package/dist/lib/injector.d.ts.map +0 -1
- package/dist/lib/machine-visibility.d.ts +0 -6
- package/dist/lib/machine-visibility.d.ts.map +0 -1
- package/dist/lib/matryoshka.d.ts +0 -50
- package/dist/lib/matryoshka.d.ts.map +0 -1
- package/dist/lib/memory-lock.d.ts +0 -58
- package/dist/lib/memory-lock.d.ts.map +0 -1
- package/dist/lib/model-config.d.ts +0 -14
- package/dist/lib/model-config.d.ts.map +0 -1
- package/dist/lib/open-sessions-connector.d.ts +0 -60
- package/dist/lib/open-sessions-connector.d.ts.map +0 -1
- package/dist/lib/package-version.d.ts +0 -3
- package/dist/lib/package-version.d.ts.map +0 -1
- package/dist/lib/poisoning.d.ts +0 -19
- package/dist/lib/poisoning.d.ts.map +0 -1
- package/dist/lib/poll.d.ts +0 -17
- package/dist/lib/poll.d.ts.map +0 -1
- package/dist/lib/procedural-extractor.d.ts +0 -21
- package/dist/lib/procedural-extractor.d.ts.map +0 -1
- package/dist/lib/profile-sync.d.ts +0 -20
- package/dist/lib/profile-sync.d.ts.map +0 -1
- package/dist/lib/profile-synthesizer.d.ts +0 -20
- package/dist/lib/profile-synthesizer.d.ts.map +0 -1
- package/dist/lib/project-detect.d.ts +0 -18
- package/dist/lib/project-detect.d.ts.map +0 -1
- package/dist/lib/project-panel.d.ts +0 -7
- package/dist/lib/project-panel.d.ts.map +0 -1
- package/dist/lib/providers/anthropic.d.ts +0 -21
- package/dist/lib/providers/anthropic.d.ts.map +0 -1
- package/dist/lib/providers/base.d.ts +0 -96
- package/dist/lib/providers/base.d.ts.map +0 -1
- package/dist/lib/providers/cerebras.d.ts +0 -20
- package/dist/lib/providers/cerebras.d.ts.map +0 -1
- package/dist/lib/providers/grok.d.ts +0 -19
- package/dist/lib/providers/grok.d.ts.map +0 -1
- package/dist/lib/providers/index.d.ts +0 -7
- package/dist/lib/providers/index.d.ts.map +0 -1
- package/dist/lib/providers/openai-compat.d.ts +0 -18
- package/dist/lib/providers/openai-compat.d.ts.map +0 -1
- package/dist/lib/providers/openai.d.ts +0 -20
- package/dist/lib/providers/openai.d.ts.map +0 -1
- package/dist/lib/providers/registry.d.ts +0 -38
- package/dist/lib/providers/registry.d.ts.map +0 -1
- package/dist/lib/quality.d.ts +0 -16
- package/dist/lib/quality.d.ts.map +0 -1
- package/dist/lib/redact.d.ts +0 -10
- package/dist/lib/redact.d.ts.map +0 -1
- package/dist/lib/reflection.d.ts +0 -83
- package/dist/lib/reflection.d.ts.map +0 -1
- package/dist/lib/retention.d.ts +0 -17
- package/dist/lib/retention.d.ts.map +0 -1
- package/dist/lib/retired-storage-mode.d.ts +0 -11
- package/dist/lib/retired-storage-mode.d.ts.map +0 -1
- package/dist/lib/search.d.ts +0 -52
- package/dist/lib/search.d.ts.map +0 -1
- package/dist/lib/session-auto-resolve.d.ts +0 -28
- package/dist/lib/session-auto-resolve.d.ts.map +0 -1
- package/dist/lib/session-processor.d.ts +0 -38
- package/dist/lib/session-processor.d.ts.map +0 -1
- package/dist/lib/session-queue.d.ts +0 -28
- package/dist/lib/session-queue.d.ts.map +0 -1
- package/dist/lib/session-registry.d.ts +0 -47
- package/dist/lib/session-registry.d.ts.map +0 -1
- package/dist/lib/session-start-briefing.d.ts +0 -10
- package/dist/lib/session-start-briefing.d.ts.map +0 -1
- package/dist/lib/session-watcher.d.ts +0 -30
- package/dist/lib/session-watcher.d.ts.map +0 -1
- package/dist/lib/storage-sync.d.ts +0 -45
- package/dist/lib/storage-sync.d.ts.map +0 -1
- package/dist/lib/sync.d.ts +0 -10
- package/dist/lib/sync.d.ts.map +0 -1
- package/dist/lib/synthesis/corpus-builder.d.ts +0 -30
- package/dist/lib/synthesis/corpus-builder.d.ts.map +0 -1
- package/dist/lib/synthesis/executor.d.ts +0 -14
- package/dist/lib/synthesis/executor.d.ts.map +0 -1
- package/dist/lib/synthesis/index.d.ts +0 -37
- package/dist/lib/synthesis/index.d.ts.map +0 -1
- package/dist/lib/synthesis/llm-analyzer.d.ts +0 -18
- package/dist/lib/synthesis/llm-analyzer.d.ts.map +0 -1
- package/dist/lib/synthesis/metrics.d.ts +0 -13
- package/dist/lib/synthesis/metrics.d.ts.map +0 -1
- package/dist/lib/synthesis/scheduler.d.ts +0 -18
- package/dist/lib/synthesis/scheduler.d.ts.map +0 -1
- package/dist/lib/synthesis/validator.d.ts +0 -19
- package/dist/lib/synthesis/validator.d.ts.map +0 -1
- package/dist/lib/task-runner.d.ts +0 -37
- package/dist/lib/task-runner.d.ts.map +0 -1
- package/dist/lib/tool-lesson-extractor.d.ts +0 -24
- package/dist/lib/tool-lesson-extractor.d.ts.map +0 -1
- package/dist/lib/tool-memory-synthesizer.d.ts +0 -28
- package/dist/lib/tool-memory-synthesizer.d.ts.map +0 -1
- package/dist/lib/topic-clusterer.d.ts +0 -21
- package/dist/lib/topic-clusterer.d.ts.map +0 -1
- package/dist/lib/when-to-use-generator.d.ts +0 -22
- package/dist/lib/when-to-use-generator.d.ts.map +0 -1
- package/dist/mcp/http.d.ts +0 -17
- package/dist/mcp/http.d.ts.map +0 -1
- package/dist/mcp/index.d.ts +0 -6
- package/dist/mcp/index.d.ts.map +0 -1
- package/dist/mcp/memory-broadcast.d.ts +0 -12
- package/dist/mcp/memory-broadcast.d.ts.map +0 -1
- package/dist/mcp/tools/agent-tools.d.ts +0 -3
- package/dist/mcp/tools/agent-tools.d.ts.map +0 -1
- package/dist/mcp/tools/auto-memory-tools.d.ts +0 -5
- package/dist/mcp/tools/auto-memory-tools.d.ts.map +0 -1
- package/dist/mcp/tools/bulk-tools.d.ts +0 -3
- package/dist/mcp/tools/bulk-tools.d.ts.map +0 -1
- package/dist/mcp/tools/consolidation-tools.d.ts +0 -3
- package/dist/mcp/tools/consolidation-tools.d.ts.map +0 -1
- package/dist/mcp/tools/focus-tools.d.ts +0 -3
- package/dist/mcp/tools/focus-tools.d.ts.map +0 -1
- package/dist/mcp/tools/graph-entity-tools.d.ts +0 -3
- package/dist/mcp/tools/graph-entity-tools.d.ts.map +0 -1
- package/dist/mcp/tools/graph-query-tools.d.ts +0 -3
- package/dist/mcp/tools/graph-query-tools.d.ts.map +0 -1
- package/dist/mcp/tools/graph-relation-tools.d.ts +0 -3
- package/dist/mcp/tools/graph-relation-tools.d.ts.map +0 -1
- package/dist/mcp/tools/graph-tools.d.ts +0 -3
- package/dist/mcp/tools/graph-tools.d.ts.map +0 -1
- package/dist/mcp/tools/graph-utils.d.ts +0 -5
- package/dist/mcp/tools/graph-utils.d.ts.map +0 -1
- package/dist/mcp/tools/hook-tools.d.ts +0 -3
- package/dist/mcp/tools/hook-tools.d.ts.map +0 -1
- package/dist/mcp/tools/lock-tools.d.ts +0 -3
- package/dist/mcp/tools/lock-tools.d.ts.map +0 -1
- package/dist/mcp/tools/memory-audit.d.ts +0 -3
- package/dist/mcp/tools/memory-audit.d.ts.map +0 -1
- package/dist/mcp/tools/memory-crud.d.ts +0 -3
- package/dist/mcp/tools/memory-crud.d.ts.map +0 -1
- package/dist/mcp/tools/memory-health.d.ts +0 -3
- package/dist/mcp/tools/memory-health.d.ts.map +0 -1
- package/dist/mcp/tools/memory-history.d.ts +0 -3
- package/dist/mcp/tools/memory-history.d.ts.map +0 -1
- package/dist/mcp/tools/memory-inject.d.ts +0 -3
- package/dist/mcp/tools/memory-inject.d.ts.map +0 -1
- package/dist/mcp/tools/memory-io.d.ts +0 -3
- package/dist/mcp/tools/memory-io.d.ts.map +0 -1
- package/dist/mcp/tools/memory-lifecycle.d.ts +0 -3
- package/dist/mcp/tools/memory-lifecycle.d.ts.map +0 -1
- package/dist/mcp/tools/memory-search.d.ts +0 -3
- package/dist/mcp/tools/memory-search.d.ts.map +0 -1
- package/dist/mcp/tools/memory-stats.d.ts +0 -3
- package/dist/mcp/tools/memory-stats.d.ts.map +0 -1
- package/dist/mcp/tools/memory-tools.d.ts +0 -17
- package/dist/mcp/tools/memory-tools.d.ts.map +0 -1
- package/dist/mcp/tools/memory-utils.d.ts +0 -27
- package/dist/mcp/tools/memory-utils.d.ts.map +0 -1
- package/dist/mcp/tools/memory-validation.d.ts +0 -3
- package/dist/mcp/tools/memory-validation.d.ts.map +0 -1
- package/dist/mcp/tools/project-tools.d.ts +0 -3
- package/dist/mcp/tools/project-tools.d.ts.map +0 -1
- package/dist/mcp/tools/session-tools.d.ts +0 -3
- package/dist/mcp/tools/session-tools.d.ts.map +0 -1
- package/dist/mcp/tools/storage-tools.d.ts +0 -3
- package/dist/mcp/tools/storage-tools.d.ts.map +0 -1
- package/dist/mcp/tools/synthesis-tools.d.ts +0 -3
- package/dist/mcp/tools/synthesis-tools.d.ts.map +0 -1
- package/dist/mcp/tools/system-tools-events.d.ts +0 -3
- package/dist/mcp/tools/system-tools-events.d.ts.map +0 -1
- package/dist/mcp/tools/system-tools-memory-admin.d.ts +0 -3
- package/dist/mcp/tools/system-tools-memory-admin.d.ts.map +0 -1
- package/dist/mcp/tools/system-tools-shared.d.ts +0 -23
- package/dist/mcp/tools/system-tools-shared.d.ts.map +0 -1
- package/dist/mcp/tools/system-tools.d.ts +0 -3
- package/dist/mcp/tools/system-tools.d.ts.map +0 -1
- package/dist/mcp/tools/tool-registry.d.ts +0 -30
- package/dist/mcp/tools/tool-registry.d.ts.map +0 -1
- package/dist/mcp/tools/utility-tools.d.ts +0 -3
- package/dist/mcp/tools/utility-tools.d.ts.map +0 -1
- package/dist/memory-project-link/index.d.ts +0 -2
- package/dist/memory-project-link/index.d.ts.map +0 -1
- package/dist/memory-project-link/schema.d.ts +0 -5
- package/dist/memory-project-link/schema.d.ts.map +0 -1
- package/dist/pg-sync-worker.d.ts +0 -2
- package/dist/pg-sync-worker.d.ts.map +0 -1
- package/dist/project-registration/authority.d.ts +0 -43
- package/dist/project-registration/authority.d.ts.map +0 -1
- package/dist/project-registration/http.d.ts +0 -32
- package/dist/project-registration/http.d.ts.map +0 -1
- package/dist/project-registration/identity.d.ts +0 -20
- package/dist/project-registration/identity.d.ts.map +0 -1
- package/dist/project-registration/index.d.ts +0 -11
- package/dist/project-registration/index.d.ts.map +0 -1
- package/dist/project-registration/project-references.d.ts +0 -71
- package/dist/project-registration/project-references.d.ts.map +0 -1
- package/dist/project-registration/project-resources.d.ts +0 -22
- package/dist/project-registration/project-resources.d.ts.map +0 -1
- package/dist/project-registration/schema.d.ts +0 -5
- package/dist/project-registration/schema.d.ts.map +0 -1
- package/dist/project-registration/types.d.ts +0 -293
- package/dist/project-registration/types.d.ts.map +0 -1
- package/dist/project-registration.d.ts +0 -2
- package/dist/project-registration.d.ts.map +0 -1
- package/dist/sdk/index.d.ts +0 -971
- package/dist/sdk/index.d.ts.map +0 -1
- package/dist/server/auth.d.ts +0 -11
- package/dist/server/auth.d.ts.map +0 -1
- package/dist/server/helpers.d.ts +0 -22
- package/dist/server/helpers.d.ts.map +0 -1
- package/dist/server/index.d.ts +0 -14
- package/dist/server/index.d.ts.map +0 -1
- package/dist/server/openapi.d.ts +0 -2
- package/dist/server/openapi.d.ts.map +0 -1
- package/dist/server/router.d.ts +0 -17
- package/dist/server/router.d.ts.map +0 -1
- package/dist/server/routes/agents.d.ts +0 -2
- package/dist/server/routes/agents.d.ts.map +0 -1
- package/dist/server/routes/entities.d.ts +0 -2
- package/dist/server/routes/entities.d.ts.map +0 -1
- package/dist/server/routes/memories-bulk.d.ts +0 -2
- package/dist/server/routes/memories-bulk.d.ts.map +0 -1
- package/dist/server/routes/memories-crud.d.ts +0 -2
- package/dist/server/routes/memories-crud.d.ts.map +0 -1
- package/dist/server/routes/memories-io.d.ts +0 -2
- package/dist/server/routes/memories-io.d.ts.map +0 -1
- package/dist/server/routes/memories-misc.d.ts +0 -2
- package/dist/server/routes/memories-misc.d.ts.map +0 -1
- package/dist/server/routes/memories-search.d.ts +0 -2
- package/dist/server/routes/memories-search.d.ts.map +0 -1
- package/dist/server/routes/memories-stats.d.ts +0 -2
- package/dist/server/routes/memories-stats.d.ts.map +0 -1
- package/dist/server/routes/memories.d.ts +0 -19
- package/dist/server/routes/memories.d.ts.map +0 -1
- package/dist/server/routes/memory-project-link.d.ts +0 -2
- package/dist/server/routes/memory-project-link.d.ts.map +0 -1
- package/dist/server/routes/project-registration.d.ts +0 -2
- package/dist/server/routes/project-registration.d.ts.map +0 -1
- package/dist/server/routes/projects.d.ts +0 -2
- package/dist/server/routes/projects.d.ts.map +0 -1
- package/dist/server/routes/system-auto-memory.d.ts +0 -2
- package/dist/server/routes/system-auto-memory.d.ts.map +0 -1
- package/dist/server/routes/system-chain.d.ts +0 -2
- package/dist/server/routes/system-chain.d.ts.map +0 -1
- package/dist/server/routes/system-consolidation.d.ts +0 -2
- package/dist/server/routes/system-consolidation.d.ts.map +0 -1
- package/dist/server/routes/system-hooks.d.ts +0 -2
- package/dist/server/routes/system-hooks.d.ts.map +0 -1
- package/dist/server/routes/system-sessions.d.ts +0 -2
- package/dist/server/routes/system-sessions.d.ts.map +0 -1
- package/dist/server/routes/system-subscriptions.d.ts +0 -2
- package/dist/server/routes/system-subscriptions.d.ts.map +0 -1
- package/dist/server/routes/system-synthesis.d.ts +0 -2
- package/dist/server/routes/system-synthesis.d.ts.map +0 -1
- package/dist/server/routes/system-tools.d.ts +0 -2
- package/dist/server/routes/system-tools.d.ts.map +0 -1
- package/dist/server/routes/system.d.ts +0 -2
- package/dist/server/routes/system.d.ts.map +0 -1
- package/dist/server/routes/tasks.d.ts +0 -2
- package/dist/server/routes/tasks.d.ts.map +0 -1
- package/dist/storage.d.ts +0 -266
- package/dist/storage.d.ts.map +0 -1
- package/dist/test-support/preload-local-store.d.ts +0 -2
- package/dist/test-support/preload-local-store.d.ts.map +0 -1
- package/dist/test-support/project-authority-identity.d.ts +0 -8
- package/dist/test-support/project-authority-identity.d.ts.map +0 -1
- package/dist/test-support/store-isolation.d.ts +0 -108
- package/dist/test-support/store-isolation.d.ts.map +0 -1
- package/dist/test-support/strip-ansi.d.ts +0 -3
- package/dist/test-support/strip-ansi.d.ts.map +0 -1
- package/dist/types/hooks.d.ts +0 -136
- package/dist/types/hooks.d.ts.map +0 -1
- package/dist/types/index.d.ts +0 -472
- package/dist/types/index.d.ts.map +0 -1
package/dist/cli/index.js
CHANGED
|
@@ -1011,7 +1011,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1011
1011
|
this._exitCallback = (err) => {
|
|
1012
1012
|
if (err.code !== "commander.executeSubCommandAsync") {
|
|
1013
1013
|
throw err;
|
|
1014
|
-
}
|
|
1014
|
+
}
|
|
1015
1015
|
};
|
|
1016
1016
|
}
|
|
1017
1017
|
return this;
|
|
@@ -2274,6 +2274,7 @@ function translateSql(sql) {
|
|
|
2274
2274
|
let translated = sql.replace(/\?/g, () => `$${++parameterIndex}`);
|
|
2275
2275
|
const ISO_FMT = `'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"'`;
|
|
2276
2276
|
translated = translated.replace(/datetime\s*\(\s*'now'\s*\)/gi, `to_char(now() AT TIME ZONE 'UTC', ${ISO_FMT})`);
|
|
2277
|
+
translated = translated.replace(/strftime\s*\(\s*'%Y-%m-%dT%H:%M:%fZ'\s*,\s*'now'\s*\)/gi, `to_char(now() AT TIME ZONE 'UTC', ${ISO_FMT})`);
|
|
2277
2278
|
translated = translated.replace(/datetime\s*\(\s*'now'\s*,\s*'(-?\d+)\s+(minutes?|hours?|days?|seconds?)'\s*\)/gi, (_match, amount, unit) => {
|
|
2278
2279
|
const parsed = parseInt(String(amount), 10);
|
|
2279
2280
|
const absolute = Math.abs(parsed);
|
|
@@ -2758,16 +2759,24 @@ function transferRows(target, table, rows, options) {
|
|
|
2758
2759
|
const conflictColumn = options.conflictColumn ?? "updated_at";
|
|
2759
2760
|
let written = 0;
|
|
2760
2761
|
let skipped = 0;
|
|
2762
|
+
let maxSyncedAt = null;
|
|
2761
2763
|
const errors = [];
|
|
2764
|
+
const bumpMaxSyncedAt = (row) => {
|
|
2765
|
+
const value = row[conflictColumn];
|
|
2766
|
+
if (typeof value === "string" && (maxSyncedAt === null || value > maxSyncedAt)) {
|
|
2767
|
+
maxSyncedAt = value;
|
|
2768
|
+
}
|
|
2769
|
+
};
|
|
2762
2770
|
if (rows.length === 0) {
|
|
2763
|
-
return { written, skipped, errors };
|
|
2771
|
+
return { written, skipped, errors, maxSyncedAt };
|
|
2764
2772
|
}
|
|
2765
2773
|
const columns = Object.keys(rows[0] ?? {});
|
|
2766
2774
|
if (!columns.includes(primaryKey)) {
|
|
2767
2775
|
return {
|
|
2768
2776
|
written,
|
|
2769
2777
|
skipped,
|
|
2770
|
-
errors: [`Table "${table}" has no "${primaryKey}" column; skipping`]
|
|
2778
|
+
errors: [`Table "${table}" has no "${primaryKey}" column; skipping`],
|
|
2779
|
+
maxSyncedAt
|
|
2771
2780
|
};
|
|
2772
2781
|
}
|
|
2773
2782
|
const hasConflictColumn = columns.includes(conflictColumn);
|
|
@@ -2780,6 +2789,7 @@ function transferRows(target, table, rows, options) {
|
|
|
2780
2789
|
const incomingTime = Date.parse(String(row[conflictColumn]));
|
|
2781
2790
|
if (Number.isFinite(existingTime) && Number.isFinite(incomingTime) && existingTime >= incomingTime) {
|
|
2782
2791
|
skipped++;
|
|
2792
|
+
bumpMaxSyncedAt(row);
|
|
2783
2793
|
continue;
|
|
2784
2794
|
}
|
|
2785
2795
|
}
|
|
@@ -2792,11 +2802,12 @@ function transferRows(target, table, rows, options) {
|
|
|
2792
2802
|
target.run(`INSERT INTO "${table}" (${columnList}) VALUES (${placeholders})`, ...columns.map((column) => row[column]));
|
|
2793
2803
|
}
|
|
2794
2804
|
written++;
|
|
2805
|
+
bumpMaxSyncedAt(row);
|
|
2795
2806
|
} catch (error) {
|
|
2796
2807
|
errors.push(`Row ${String(row[primaryKey] ?? "unknown")}: ${error instanceof Error ? error.message : String(error)}`);
|
|
2797
2808
|
}
|
|
2798
2809
|
}
|
|
2799
|
-
return { written, skipped, errors };
|
|
2810
|
+
return { written, skipped, errors, maxSyncedAt };
|
|
2800
2811
|
}
|
|
2801
2812
|
function incrementalSyncPush(local, remote, tables, options = {}) {
|
|
2802
2813
|
return runIncrementalSync("push", local, remote, local, tables, options);
|
|
@@ -2834,22 +2845,29 @@ function runIncrementalSync(direction, source, target, metaDb, tables, options)
|
|
|
2834
2845
|
rows = source.all(`SELECT * FROM "${table}"`);
|
|
2835
2846
|
stat.first_sync = true;
|
|
2836
2847
|
}
|
|
2848
|
+
let maxSyncedAt = null;
|
|
2837
2849
|
for (let offset = 0;offset < rows.length; offset += batchSize) {
|
|
2838
2850
|
const batch = rows.slice(offset, offset + batchSize);
|
|
2839
2851
|
const result = transferRows(target, table, batch, options);
|
|
2840
2852
|
stat.synced_rows += result.written;
|
|
2841
2853
|
stat.skipped_rows += result.skipped;
|
|
2842
2854
|
stat.errors.push(...result.errors);
|
|
2855
|
+
if (result.maxSyncedAt !== null && (maxSyncedAt === null || result.maxSyncedAt > maxSyncedAt)) {
|
|
2856
|
+
maxSyncedAt = result.maxSyncedAt;
|
|
2857
|
+
}
|
|
2843
2858
|
}
|
|
2844
2859
|
if (rows.length === 0) {
|
|
2845
2860
|
stat.skipped_rows = stat.total_rows;
|
|
2846
2861
|
}
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2862
|
+
const nextCursor = maxSyncedAt ?? meta?.last_synced_at ?? null;
|
|
2863
|
+
if (rows.length > 0 && stat.errors.length === 0 && nextCursor !== null) {
|
|
2864
|
+
upsertSyncMeta(metaDb, {
|
|
2865
|
+
table_name: table,
|
|
2866
|
+
last_synced_at: nextCursor,
|
|
2867
|
+
last_synced_row_count: stat.synced_rows,
|
|
2868
|
+
direction
|
|
2869
|
+
});
|
|
2870
|
+
}
|
|
2853
2871
|
} catch (error) {
|
|
2854
2872
|
stat.errors.push(`Table "${table}": ${error instanceof Error ? error.message : String(error)}`);
|
|
2855
2873
|
}
|
|
@@ -2877,8 +2895,13 @@ var init_storage = __esm(() => {
|
|
|
2877
2895
|
data;
|
|
2878
2896
|
closed = false;
|
|
2879
2897
|
lastError = null;
|
|
2898
|
+
generation = 0;
|
|
2880
2899
|
static DATA_BYTES = 128 * 1024 * 1024;
|
|
2881
|
-
static
|
|
2900
|
+
static queryTimeoutMs() {
|
|
2901
|
+
const raw = process.env["MEMENTOS_PGSYNC_QUERY_TIMEOUT_MS"]?.trim();
|
|
2902
|
+
const parsed = raw ? Number(raw) : Number.NaN;
|
|
2903
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : 60000;
|
|
2904
|
+
}
|
|
2882
2905
|
static resolveWorkerPath() {
|
|
2883
2906
|
const ext = import.meta.url.endsWith(".ts") ? ".ts" : ".js";
|
|
2884
2907
|
const here = fileURLToPath(new URL(".", import.meta.url));
|
|
@@ -2893,12 +2916,12 @@ var init_storage = __esm(() => {
|
|
|
2893
2916
|
}
|
|
2894
2917
|
return candidates[0];
|
|
2895
2918
|
}
|
|
2896
|
-
constructor(connectionString) {
|
|
2897
|
-
const control = new SharedArrayBuffer(
|
|
2919
|
+
constructor(connectionString, workerPath) {
|
|
2920
|
+
const control = new SharedArrayBuffer(12);
|
|
2898
2921
|
const dataSab = new SharedArrayBuffer(PgSyncPool.DATA_BYTES);
|
|
2899
2922
|
this.status = new Int32Array(control);
|
|
2900
2923
|
this.data = new Uint8Array(dataSab);
|
|
2901
|
-
this.worker = new Worker(PgSyncPool.resolveWorkerPath(), {
|
|
2924
|
+
this.worker = new Worker(workerPath ?? PgSyncPool.resolveWorkerPath(), {
|
|
2902
2925
|
workerData: {
|
|
2903
2926
|
dsn: stripSslParams(connectionString),
|
|
2904
2927
|
ssl: sslConfigFor(connectionString),
|
|
@@ -2916,21 +2939,35 @@ var init_storage = __esm(() => {
|
|
|
2916
2939
|
throw new Error("PgSyncPool is closed");
|
|
2917
2940
|
if (this.lastError)
|
|
2918
2941
|
throw this.lastError;
|
|
2942
|
+
const timeoutMs = PgSyncPool.queryTimeoutMs();
|
|
2943
|
+
const gen = ++this.generation;
|
|
2919
2944
|
Atomics.store(this.status, 0, 0);
|
|
2920
|
-
this.
|
|
2921
|
-
|
|
2922
|
-
const
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2945
|
+
Atomics.store(this.status, 2, 0);
|
|
2946
|
+
this.worker.postMessage({ sql, params, gen });
|
|
2947
|
+
const deadline = Date.now() + timeoutMs;
|
|
2948
|
+
for (;; ) {
|
|
2949
|
+
const remaining = deadline - Date.now();
|
|
2950
|
+
const responding = Atomics.load(this.status, 0);
|
|
2951
|
+
if (responding === gen) {
|
|
2952
|
+
const code = Atomics.load(this.status, 2);
|
|
2953
|
+
const len = Atomics.load(this.status, 1);
|
|
2954
|
+
const payload = JSON.parse(new TextDecoder().decode(this.data.subarray(0, len)));
|
|
2955
|
+
if (code === 2) {
|
|
2956
|
+
throw new Error(payload.message ?? "PostgreSQL error");
|
|
2957
|
+
}
|
|
2958
|
+
return payload;
|
|
2959
|
+
}
|
|
2960
|
+
if (responding !== 0) {
|
|
2961
|
+
Atomics.compareExchange(this.status, 0, responding, 0);
|
|
2962
|
+
continue;
|
|
2963
|
+
}
|
|
2964
|
+
if (remaining <= 0) {
|
|
2965
|
+
if (this.lastError)
|
|
2966
|
+
throw this.lastError;
|
|
2967
|
+
throw new Error(`PostgreSQL query timed out after ${timeoutMs}ms`);
|
|
2968
|
+
}
|
|
2969
|
+
Atomics.wait(this.status, 0, 0, remaining);
|
|
2932
2970
|
}
|
|
2933
|
-
return payload;
|
|
2934
2971
|
}
|
|
2935
2972
|
end() {
|
|
2936
2973
|
if (this.closed)
|
|
@@ -3171,7 +3208,16 @@ x-api-key: ${cfg.apiKey}
|
|
|
3171
3208
|
function apiJson(method, path, body, options) {
|
|
3172
3209
|
const raw = apiRequestRaw(method, path, body);
|
|
3173
3210
|
if (raw.status >= 200 && raw.status < 300) {
|
|
3174
|
-
|
|
3211
|
+
let data;
|
|
3212
|
+
if (raw.body.trim()) {
|
|
3213
|
+
try {
|
|
3214
|
+
data = JSON.parse(raw.body);
|
|
3215
|
+
} catch (e) {
|
|
3216
|
+
throw new ApiRequestError(`mementos cloud ${method} ${path} returned status ${raw.status} with a body that is not valid JSON (${e instanceof Error ? e.message : String(e)}) \u2014 the response is truncated or the server is unhealthy`, raw.status, raw.body.slice(0, 500));
|
|
3217
|
+
}
|
|
3218
|
+
} else {
|
|
3219
|
+
data = undefined;
|
|
3220
|
+
}
|
|
3175
3221
|
return { status: raw.status, data };
|
|
3176
3222
|
}
|
|
3177
3223
|
if (raw.status === 404 && options?.allow404) {
|
|
@@ -5258,8 +5304,12 @@ __export(exports_memories, {
|
|
|
5258
5304
|
updateMemory: () => updateMemory,
|
|
5259
5305
|
touchMemory: () => touchMemory,
|
|
5260
5306
|
semanticSearch: () => semanticSearch,
|
|
5307
|
+
reservedAgentIdViolation: () => reservedAgentIdViolation,
|
|
5261
5308
|
parseMemoryRow: () => parseMemoryRow,
|
|
5309
|
+
listMemoryHistoryPage: () => listMemoryHistoryPage,
|
|
5262
5310
|
listMemoryHistory: () => listMemoryHistory,
|
|
5311
|
+
listMemoriesPage: () => listMemoriesPage,
|
|
5312
|
+
listMemoriesBounded: () => listMemoriesBounded,
|
|
5263
5313
|
listMemories: () => listMemories,
|
|
5264
5314
|
listLowTrustMemories: () => listLowTrustMemories,
|
|
5265
5315
|
indexMemoryEmbedding: () => indexMemoryEmbedding,
|
|
@@ -5273,6 +5323,8 @@ __export(exports_memories, {
|
|
|
5273
5323
|
getMemoriesByKey: () => getMemoriesByKey,
|
|
5274
5324
|
deleteMemory: () => deleteMemory,
|
|
5275
5325
|
createMemory: () => createMemory,
|
|
5326
|
+
countMemoryHistory: () => countMemoryHistory,
|
|
5327
|
+
countMemories: () => countMemories,
|
|
5276
5328
|
cleanExpiredMemories: () => cleanExpiredMemories,
|
|
5277
5329
|
bulkUpsertMemories: () => bulkUpsertMemories,
|
|
5278
5330
|
bulkDeleteMemories: () => bulkDeleteMemories
|
|
@@ -5324,7 +5376,20 @@ function parseMemoryRow(row) {
|
|
|
5324
5376
|
accessed_at: row["accessed_at"] || null
|
|
5325
5377
|
};
|
|
5326
5378
|
}
|
|
5379
|
+
function reservedAgentIdViolation(agentId) {
|
|
5380
|
+
if (!agentId)
|
|
5381
|
+
return null;
|
|
5382
|
+
const normalized = agentId.trim().toLowerCase();
|
|
5383
|
+
if (RESERVED_AGENT_IDS.has(normalized)) {
|
|
5384
|
+
return `Reserved placeholder agent id "${agentId}" cannot own a memory. ` + `Refusing to write: test harnesses must not write memories under placeholder agent ` + `identities. Register a real agent (mementos register-agent <name>) and pass its id.`;
|
|
5385
|
+
}
|
|
5386
|
+
return null;
|
|
5387
|
+
}
|
|
5327
5388
|
function createMemory(input, dedupeMode = "merge", db) {
|
|
5389
|
+
const reservedViolation = reservedAgentIdViolation(input.agent_id);
|
|
5390
|
+
if (reservedViolation) {
|
|
5391
|
+
throw new Error(reservedViolation);
|
|
5392
|
+
}
|
|
5328
5393
|
if (!db && isApiMode()) {
|
|
5329
5394
|
const { status, data } = apiJson("POST", "/memories", { ...input, dedupe: dedupeMode });
|
|
5330
5395
|
if (!data || !data.id) {
|
|
@@ -5374,7 +5439,8 @@ function createMemory(input, dedupeMode = "merge", db) {
|
|
|
5374
5439
|
importance = ?, metadata = ?, expires_at = ?,
|
|
5375
5440
|
when_to_use = ?,
|
|
5376
5441
|
pinned = COALESCE(pinned, 0),
|
|
5377
|
-
version = version + 1, updated_at =
|
|
5442
|
+
version = version + 1, updated_at = ?,
|
|
5443
|
+
updated_by_agent = ?
|
|
5378
5444
|
WHERE id = ?`, [
|
|
5379
5445
|
safeValue,
|
|
5380
5446
|
input.category || "knowledge",
|
|
@@ -5385,6 +5451,7 @@ function createMemory(input, dedupeMode = "merge", db) {
|
|
|
5385
5451
|
expiresAt,
|
|
5386
5452
|
input.when_to_use || null,
|
|
5387
5453
|
timestamp,
|
|
5454
|
+
input.agent_id || null,
|
|
5388
5455
|
existing.id
|
|
5389
5456
|
]);
|
|
5390
5457
|
d.run("DELETE FROM memory_tags WHERE memory_id = ?", [existing.id]);
|
|
@@ -5489,6 +5556,12 @@ function bulkUpsertMemories(memories, db) {
|
|
|
5489
5556
|
errors.push(`Rejected "${key}": ${formatEnumViolation(violation)}`);
|
|
5490
5557
|
continue;
|
|
5491
5558
|
}
|
|
5559
|
+
const agentViolation = reservedAgentIdViolation(typeof mem["agent_id"] === "string" ? mem["agent_id"] : undefined);
|
|
5560
|
+
if (agentViolation) {
|
|
5561
|
+
rejected++;
|
|
5562
|
+
errors.push(`Rejected "${key}": ${agentViolation}`);
|
|
5563
|
+
continue;
|
|
5564
|
+
}
|
|
5492
5565
|
const timestamp = now();
|
|
5493
5566
|
let tags = [];
|
|
5494
5567
|
const rawTags = mem["tags"];
|
|
@@ -5639,29 +5712,7 @@ function getMemoriesByKey(key, scope, agentId, projectId, db) {
|
|
|
5639
5712
|
const rows = d.query(sql).all(...params);
|
|
5640
5713
|
return rows.map(parseMemoryRow);
|
|
5641
5714
|
}
|
|
5642
|
-
function
|
|
5643
|
-
if (!db && isApiMode()) {
|
|
5644
|
-
const f = filter || {};
|
|
5645
|
-
const q = toQuery({
|
|
5646
|
-
key: f.key,
|
|
5647
|
-
scope: f.scope,
|
|
5648
|
-
category: f.category,
|
|
5649
|
-
status: f.status,
|
|
5650
|
-
tags: f.tags,
|
|
5651
|
-
min_importance: f.min_importance,
|
|
5652
|
-
pinned: f.pinned,
|
|
5653
|
-
agent_id: f.agent_id,
|
|
5654
|
-
project_id: f.project_id,
|
|
5655
|
-
session_id: f.session_id,
|
|
5656
|
-
namespace: f.namespace,
|
|
5657
|
-
as_of: f.as_of,
|
|
5658
|
-
limit: f.limit,
|
|
5659
|
-
offset: f.offset
|
|
5660
|
-
});
|
|
5661
|
-
const { data } = apiJson("GET", `/memories${q}`);
|
|
5662
|
-
return data?.memories ?? [];
|
|
5663
|
-
}
|
|
5664
|
-
const d = db || getDatabase();
|
|
5715
|
+
function buildMemoryListConditions(filter) {
|
|
5665
5716
|
const conditions = [];
|
|
5666
5717
|
const params = [];
|
|
5667
5718
|
if (filter) {
|
|
@@ -5773,21 +5824,114 @@ function listMemories(filter, db) {
|
|
|
5773
5824
|
} else {
|
|
5774
5825
|
conditions.push("status = 'active'");
|
|
5775
5826
|
}
|
|
5827
|
+
return { conditions, params };
|
|
5828
|
+
}
|
|
5829
|
+
function listMemoriesPage(filter, db) {
|
|
5830
|
+
const f = filter || {};
|
|
5831
|
+
if (!db && isApiMode()) {
|
|
5832
|
+
const q = toQuery({
|
|
5833
|
+
key: f.key,
|
|
5834
|
+
scope: f.scope,
|
|
5835
|
+
category: f.category,
|
|
5836
|
+
status: f.status,
|
|
5837
|
+
tags: f.tags,
|
|
5838
|
+
min_importance: f.min_importance,
|
|
5839
|
+
pinned: f.pinned,
|
|
5840
|
+
agent_id: f.agent_id,
|
|
5841
|
+
project_id: f.project_id,
|
|
5842
|
+
session_id: f.session_id,
|
|
5843
|
+
machine_id: f.machine_id,
|
|
5844
|
+
visible_to_machine_id: f.visible_to_machine_id,
|
|
5845
|
+
search: f.search,
|
|
5846
|
+
source: f.source,
|
|
5847
|
+
flag: f.flag,
|
|
5848
|
+
namespace: f.namespace,
|
|
5849
|
+
as_of: f.as_of,
|
|
5850
|
+
limit: f.limit,
|
|
5851
|
+
offset: f.offset
|
|
5852
|
+
});
|
|
5853
|
+
const { data } = apiJson("GET", `/memories${q}`);
|
|
5854
|
+
return {
|
|
5855
|
+
rows: data?.memories ?? [],
|
|
5856
|
+
has_more: data?.has_more,
|
|
5857
|
+
next_cursor: data?.next_cursor ?? null
|
|
5858
|
+
};
|
|
5859
|
+
}
|
|
5860
|
+
const d = db || getDatabase();
|
|
5861
|
+
const { conditions, params } = buildMemoryListConditions(f);
|
|
5776
5862
|
let sql = "SELECT * FROM memories";
|
|
5777
5863
|
if (conditions.length > 0) {
|
|
5778
5864
|
sql += ` WHERE ${conditions.join(" AND ")}`;
|
|
5779
5865
|
}
|
|
5780
5866
|
sql += " ORDER BY importance DESC, created_at DESC";
|
|
5781
|
-
if (
|
|
5867
|
+
if (f.limit) {
|
|
5782
5868
|
sql += " LIMIT ?";
|
|
5783
|
-
params.push(
|
|
5869
|
+
params.push(f.limit);
|
|
5784
5870
|
}
|
|
5785
|
-
if (
|
|
5871
|
+
if (f.offset) {
|
|
5786
5872
|
sql += " OFFSET ?";
|
|
5787
|
-
params.push(
|
|
5873
|
+
params.push(f.offset);
|
|
5788
5874
|
}
|
|
5789
5875
|
const rows = d.query(sql).all(...params);
|
|
5790
|
-
|
|
5876
|
+
const parsed = rows.map(parseMemoryRow);
|
|
5877
|
+
const hasMore = f.limit !== undefined && parsed.length === f.limit;
|
|
5878
|
+
return {
|
|
5879
|
+
rows: parsed,
|
|
5880
|
+
has_more: hasMore,
|
|
5881
|
+
next_cursor: hasMore ? (f.offset ?? 0) + parsed.length : null
|
|
5882
|
+
};
|
|
5883
|
+
}
|
|
5884
|
+
function listMemories(filter, db) {
|
|
5885
|
+
return listMemoriesPage(filter, db).rows;
|
|
5886
|
+
}
|
|
5887
|
+
function listMemoriesBounded(filter = {}, target, db) {
|
|
5888
|
+
const pageSize = 1000;
|
|
5889
|
+
const maxPages = 1000;
|
|
5890
|
+
const want = target === undefined ? undefined : target + 1;
|
|
5891
|
+
const rows = [];
|
|
5892
|
+
const seenCursors = new Set;
|
|
5893
|
+
let cursor = filter.offset ?? 0;
|
|
5894
|
+
let pages = 0;
|
|
5895
|
+
for (;; ) {
|
|
5896
|
+
if (want !== undefined && rows.length >= want)
|
|
5897
|
+
break;
|
|
5898
|
+
if (++pages > maxPages) {
|
|
5899
|
+
throw new Error(`memories list traversal exceeded ${maxPages} pages while collecting rows \u2014 aborting (cursor cycle?)`);
|
|
5900
|
+
}
|
|
5901
|
+
const limit = Math.min(want === undefined ? pageSize : want - rows.length, pageSize);
|
|
5902
|
+
const page = listMemoriesPage({ ...filter, limit, offset: cursor }, db);
|
|
5903
|
+
rows.push(...page.rows);
|
|
5904
|
+
if (page.has_more === false)
|
|
5905
|
+
break;
|
|
5906
|
+
if (page.has_more === undefined && page.rows.length < limit)
|
|
5907
|
+
break;
|
|
5908
|
+
if (page.has_more === true && (page.next_cursor === null || page.next_cursor === undefined)) {
|
|
5909
|
+
throw new Error("memories list page claimed more results without a next cursor \u2014 aborting");
|
|
5910
|
+
}
|
|
5911
|
+
const next = page.next_cursor ?? cursor + page.rows.length;
|
|
5912
|
+
if (seenCursors.has(next)) {
|
|
5913
|
+
throw new Error("memories list traversal repeated a cursor \u2014 aborting");
|
|
5914
|
+
}
|
|
5915
|
+
seenCursors.add(next);
|
|
5916
|
+
cursor = next;
|
|
5917
|
+
}
|
|
5918
|
+
const hasMore = target !== undefined && rows.length > target;
|
|
5919
|
+
const trimmed = hasMore ? rows.slice(0, target) : rows;
|
|
5920
|
+
return {
|
|
5921
|
+
rows: trimmed,
|
|
5922
|
+
has_more: hasMore,
|
|
5923
|
+
next_cursor: hasMore ? (filter.offset ?? 0) + trimmed.length : null
|
|
5924
|
+
};
|
|
5925
|
+
}
|
|
5926
|
+
function countMemories(filter, db) {
|
|
5927
|
+
const d = db || getDatabase();
|
|
5928
|
+
const { conditions, params } = buildMemoryListConditions(filter);
|
|
5929
|
+
let sql = "SELECT COUNT(*) AS c FROM memories";
|
|
5930
|
+
if (conditions.length > 0) {
|
|
5931
|
+
sql += ` WHERE ${conditions.join(" AND ")}`;
|
|
5932
|
+
}
|
|
5933
|
+
const row = d.query(sql).get(...params);
|
|
5934
|
+
return row?.c ?? 0;
|
|
5791
5935
|
}
|
|
5792
5936
|
function getMemoryBriefing(opts, db) {
|
|
5793
5937
|
const limit = opts.limit ?? 20;
|
|
@@ -5849,13 +5993,17 @@ function listLowTrustMemories(opts = {}, db) {
|
|
|
5849
5993
|
const rows = d.prepare(`SELECT * FROM memories WHERE ${conditions.join(" AND ")} ORDER BY trust_score ASC LIMIT ? OFFSET ?`).all(...params);
|
|
5850
5994
|
return rows.map(parseMemoryRow);
|
|
5851
5995
|
}
|
|
5852
|
-
function
|
|
5996
|
+
function listMemoryHistoryPage(opts = {}, db) {
|
|
5853
5997
|
const limit = opts.limit ?? 20;
|
|
5854
5998
|
const offset = opts.offset ?? 0;
|
|
5855
5999
|
if (!db && isApiMode()) {
|
|
5856
6000
|
const q = toQuery({ limit, offset });
|
|
5857
6001
|
const { data } = apiJson("GET", `/memories/history${q}`);
|
|
5858
|
-
return
|
|
6002
|
+
return {
|
|
6003
|
+
rows: data?.memories ?? [],
|
|
6004
|
+
has_more: data?.has_more,
|
|
6005
|
+
next_cursor: data?.next_cursor ?? null
|
|
6006
|
+
};
|
|
5859
6007
|
}
|
|
5860
6008
|
const d = db || getDatabase();
|
|
5861
6009
|
const params = [limit];
|
|
@@ -5865,7 +6013,21 @@ function listMemoryHistory(opts = {}, db) {
|
|
|
5865
6013
|
params.push(offset);
|
|
5866
6014
|
}
|
|
5867
6015
|
const rows = d.query(sql).all(...params);
|
|
5868
|
-
|
|
6016
|
+
const parsed = rows.map(parseMemoryRow);
|
|
6017
|
+
const hasMore = parsed.length === limit;
|
|
6018
|
+
return {
|
|
6019
|
+
rows: parsed,
|
|
6020
|
+
has_more: hasMore,
|
|
6021
|
+
next_cursor: hasMore ? offset + parsed.length : null
|
|
6022
|
+
};
|
|
6023
|
+
}
|
|
6024
|
+
function listMemoryHistory(opts = {}, db) {
|
|
6025
|
+
return listMemoryHistoryPage(opts, db).rows;
|
|
6026
|
+
}
|
|
6027
|
+
function countMemoryHistory(db) {
|
|
6028
|
+
const d = db || getDatabase();
|
|
6029
|
+
const row = d.query("SELECT COUNT(*) AS c FROM memories WHERE status = 'active' AND accessed_at IS NOT NULL").get();
|
|
6030
|
+
return row?.c ?? 0;
|
|
5869
6031
|
}
|
|
5870
6032
|
function getMemoryChain(sequenceGroup, projectId, db) {
|
|
5871
6033
|
if (!db && isApiMode()) {
|
|
@@ -5962,20 +6124,29 @@ function updateMemory(id, input, db) {
|
|
|
5962
6124
|
sets.push("when_to_use = ?");
|
|
5963
6125
|
params.push(input.when_to_use ?? null);
|
|
5964
6126
|
}
|
|
6127
|
+
if (input.updated_by_agent !== undefined) {
|
|
6128
|
+
sets.push("updated_by_agent = ?");
|
|
6129
|
+
params.push(input.updated_by_agent ?? null);
|
|
6130
|
+
}
|
|
5965
6131
|
if (input.tags !== undefined) {
|
|
5966
6132
|
sets.push("tags = ?");
|
|
5967
6133
|
params.push(JSON.stringify(input.tags));
|
|
5968
|
-
d.run("DELETE FROM memory_tags WHERE memory_id = ?", [memoryId]);
|
|
5969
|
-
const insertTag = d.prepare("INSERT OR IGNORE INTO memory_tags (memory_id, tag) VALUES (?, ?)");
|
|
5970
|
-
for (const tag of input.tags) {
|
|
5971
|
-
insertTag.run(memoryId, tag);
|
|
5972
|
-
}
|
|
5973
6134
|
}
|
|
5974
6135
|
params.push(memoryId);
|
|
5975
|
-
|
|
5976
|
-
|
|
5977
|
-
|
|
5978
|
-
|
|
6136
|
+
d.transaction(() => {
|
|
6137
|
+
const res = d.run(`UPDATE memories SET ${sets.join(", ")} WHERE id = ?`, params);
|
|
6138
|
+
if (res.changes === 0) {
|
|
6139
|
+
throw new Error(`Update affected no rows for memory ${memoryId}: the record was read but not written. ` + `This is a bug in @hasna/mementos, not a bad argument \u2014 please report it.`);
|
|
6140
|
+
}
|
|
6141
|
+
if (input.tags !== undefined) {
|
|
6142
|
+
d.run("DELETE FROM memory_tags WHERE memory_id = ?", [memoryId]);
|
|
6143
|
+
const insertTag = d.prepare("INSERT OR IGNORE INTO memory_tags (memory_id, tag) VALUES (?, ?)");
|
|
6144
|
+
for (const tag of input.tags) {
|
|
6145
|
+
insertTag.run(memoryId, tag);
|
|
6146
|
+
}
|
|
6147
|
+
}
|
|
6148
|
+
return res;
|
|
6149
|
+
});
|
|
5979
6150
|
const updated = getMemory(memoryId, d);
|
|
5980
6151
|
if (input.value !== undefined) {
|
|
5981
6152
|
try {
|
|
@@ -6146,7 +6317,7 @@ async function semanticSearch(queryText, options = {}, db) {
|
|
|
6146
6317
|
scored.sort((a, b) => b.score - a.score);
|
|
6147
6318
|
return scored.slice(0, limit);
|
|
6148
6319
|
}
|
|
6149
|
-
var RECALL_PROMOTE_THRESHOLD = 3;
|
|
6320
|
+
var RESERVED_AGENT_IDS, RECALL_PROMOTE_THRESHOLD = 3;
|
|
6150
6321
|
var init_memories = __esm(() => {
|
|
6151
6322
|
init_types();
|
|
6152
6323
|
init_database();
|
|
@@ -6156,9 +6327,32 @@ var init_memories = __esm(() => {
|
|
|
6156
6327
|
init_poisoning();
|
|
6157
6328
|
init_entity_memories();
|
|
6158
6329
|
init_api_mode();
|
|
6330
|
+
RESERVED_AGENT_IDS = new Set([
|
|
6331
|
+
"agent-a",
|
|
6332
|
+
"agent-x",
|
|
6333
|
+
"agent-z",
|
|
6334
|
+
"nonexistent-agent"
|
|
6335
|
+
]);
|
|
6159
6336
|
});
|
|
6160
6337
|
|
|
6161
6338
|
// src/db/agents.ts
|
|
6339
|
+
import { homedir as homedir3 } from "os";
|
|
6340
|
+
import { join as join5 } from "path";
|
|
6341
|
+
import { existsSync as existsSync4, readFileSync as readFileSync2 } from "fs";
|
|
6342
|
+
function resolveWritingAgentName() {
|
|
6343
|
+
const envName = process.env["MEMENTOS_AGENT"]?.trim();
|
|
6344
|
+
if (envName)
|
|
6345
|
+
return envName;
|
|
6346
|
+
try {
|
|
6347
|
+
const path = join5(homedir3(), ".hasna", "conversations", "agent-id");
|
|
6348
|
+
if (existsSync4(path)) {
|
|
6349
|
+
const fileAgent = readFileSync2(path, "utf8").trim();
|
|
6350
|
+
if (fileAgent)
|
|
6351
|
+
return fileAgent;
|
|
6352
|
+
}
|
|
6353
|
+
} catch {}
|
|
6354
|
+
return null;
|
|
6355
|
+
}
|
|
6162
6356
|
function parseAgentRow(row) {
|
|
6163
6357
|
return {
|
|
6164
6358
|
id: row["id"],
|
|
@@ -6361,17 +6555,17 @@ var init_agents = __esm(() => {
|
|
|
6361
6555
|
});
|
|
6362
6556
|
|
|
6363
6557
|
// src/lib/package-version.ts
|
|
6364
|
-
import { readFileSync as
|
|
6365
|
-
import { dirname as dirname2, join as
|
|
6558
|
+
import { readFileSync as readFileSync3 } from "fs";
|
|
6559
|
+
import { dirname as dirname2, join as join6 } from "path";
|
|
6366
6560
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
6367
6561
|
function getMementosPackageVersion() {
|
|
6368
6562
|
const here = dirname2(fileURLToPath2(import.meta.url));
|
|
6369
6563
|
for (const candidate of [
|
|
6370
|
-
|
|
6371
|
-
|
|
6564
|
+
join6(here, "..", "..", "package.json"),
|
|
6565
|
+
join6(here, "..", "package.json")
|
|
6372
6566
|
]) {
|
|
6373
6567
|
try {
|
|
6374
|
-
const parsed = JSON.parse(
|
|
6568
|
+
const parsed = JSON.parse(readFileSync3(candidate, "utf8"));
|
|
6375
6569
|
if (typeof parsed.version === "string" && parsed.version.trim())
|
|
6376
6570
|
return parsed.version;
|
|
6377
6571
|
} catch {}
|
|
@@ -6391,6 +6585,92 @@ var init_types2 = __esm(() => {
|
|
|
6391
6585
|
];
|
|
6392
6586
|
});
|
|
6393
6587
|
|
|
6588
|
+
// src/project-registration/historical-receipt.ts
|
|
6589
|
+
function supportsFleetResourcesHistoricalReceiptLookup(capability) {
|
|
6590
|
+
return capability.authority_id === FLEET_RESOURCES_CURRENT_PROJECT_REGISTRATION_IDENTITY.authority_id && capability.tenant_id === FLEET_RESOURCES_CURRENT_PROJECT_REGISTRATION_IDENTITY.tenant_id && capability.corpus_id === FLEET_RESOURCES_CURRENT_PROJECT_REGISTRATION_IDENTITY.corpus_id;
|
|
6591
|
+
}
|
|
6592
|
+
var ROOT_TENANT_ID = "adfd95c7-ee8b-52cb-ae47-4ae65dae3313", FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION, FLEET_RESOURCES_HISTORICAL_RECEIPT, FLEET_RESOURCES_CURRENT_PROJECT_REGISTRATION_IDENTITY, FLEET_RESOURCES_HISTORICAL_LOOKUP_IDENTITY;
|
|
6593
|
+
var init_historical_receipt = __esm(() => {
|
|
6594
|
+
FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION = {
|
|
6595
|
+
authority: "mementos",
|
|
6596
|
+
authority_route: "mementos.project-registration.v1",
|
|
6597
|
+
package_version: "1.0.0-rc.3",
|
|
6598
|
+
authority_id: "mementos",
|
|
6599
|
+
tenant_id: "default",
|
|
6600
|
+
corpus_id: "default",
|
|
6601
|
+
operation_id: "op-cli-register-full",
|
|
6602
|
+
step_id: "mementos_project",
|
|
6603
|
+
resource_kind: "project",
|
|
6604
|
+
direction: "forward",
|
|
6605
|
+
target_selector: "wks_005285827590a93b70e5",
|
|
6606
|
+
target_id: "mm_project_f75606ef14e51fb577a15882ba0ab8ed333b2c29",
|
|
6607
|
+
idempotency_key: "prk_786cdc6babddeae1be8d5078d0f75322d1ea1010ac5d8a50",
|
|
6608
|
+
receipt_id: "mmpr_a647f9908a33bb64bf137f584202590f91b72a33",
|
|
6609
|
+
request_digest: "8eb0e3fee26fdb7edb8a444aeddaaedb79a84a5a36e742ae03616f62b19f5c22",
|
|
6610
|
+
precondition_digest: "0b6c22fcf75d835f9f27308b1a9d40e8902e48a97da370fd56df5acacfcd968e",
|
|
6611
|
+
result_revision: "2026-08-09T13:37:43.068Z",
|
|
6612
|
+
result_digest: "26fb0dd5c5e20909d3653ab0ddd8fa45e5142728e4e66d595e2419f7ed40b036",
|
|
6613
|
+
created_at: "2026-08-09T13:37:43.068Z",
|
|
6614
|
+
identity_digest: "1108dd972c90e4989036fb6ecec7dde10f54641a697bd53cfcd64017f589ace7",
|
|
6615
|
+
target_digest: "72789fcd60668eeb66ee068936d3afa96deadcb007228830c64b6de783b6dcef",
|
|
6616
|
+
operation_digest: "d7e37bfb2c0d28f8c4086c53224cd855d14694f32807b74c102b61a99963f3c0",
|
|
6617
|
+
idempotency_digest: "b56d8ec37efb818759cdd2ee3b58bc1401ac13384c8d64c1813bb5c198b1e376",
|
|
6618
|
+
receipt_digest: "52ce90c5de6817989f107d9d27e06156962a2b9c365e34e16a57aa37886501a2",
|
|
6619
|
+
response_digest: "2fa3ed508f5f192c18753b1205ced996340fdf02f735420d32db897fc239805c"
|
|
6620
|
+
};
|
|
6621
|
+
FLEET_RESOURCES_HISTORICAL_RECEIPT = {
|
|
6622
|
+
receipt_id: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.receipt_id,
|
|
6623
|
+
authority: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.authority,
|
|
6624
|
+
route: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.authority_route,
|
|
6625
|
+
package_version: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.package_version,
|
|
6626
|
+
authority_id: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.authority_id,
|
|
6627
|
+
tenant_id: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.tenant_id,
|
|
6628
|
+
corpus_id: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.corpus_id,
|
|
6629
|
+
operation_id: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.operation_id,
|
|
6630
|
+
step_id: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.step_id,
|
|
6631
|
+
resource_kind: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.resource_kind,
|
|
6632
|
+
direction: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.direction,
|
|
6633
|
+
idempotency_key: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.idempotency_key,
|
|
6634
|
+
request_digest: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.request_digest,
|
|
6635
|
+
precondition_digest: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.precondition_digest,
|
|
6636
|
+
outcome: "accepted",
|
|
6637
|
+
reason: null,
|
|
6638
|
+
target_id: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.target_id,
|
|
6639
|
+
result_revision: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.result_revision,
|
|
6640
|
+
result_digest: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.result_digest,
|
|
6641
|
+
duplicate_of_receipt_id: null,
|
|
6642
|
+
accepted_receipt_id: null,
|
|
6643
|
+
created_by_operation: true,
|
|
6644
|
+
created_at: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.created_at
|
|
6645
|
+
};
|
|
6646
|
+
FLEET_RESOURCES_CURRENT_PROJECT_REGISTRATION_IDENTITY = {
|
|
6647
|
+
authority_id: "mementos",
|
|
6648
|
+
tenant_id: ROOT_TENANT_ID,
|
|
6649
|
+
corpus_id: "mementos:postgresql"
|
|
6650
|
+
};
|
|
6651
|
+
FLEET_RESOURCES_HISTORICAL_LOOKUP_IDENTITY = {
|
|
6652
|
+
source: {
|
|
6653
|
+
authority: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.authority,
|
|
6654
|
+
authority_route: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.authority_route,
|
|
6655
|
+
package_version: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.package_version,
|
|
6656
|
+
authority_id: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.authority_id,
|
|
6657
|
+
tenant_id: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.tenant_id,
|
|
6658
|
+
corpus_id: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.corpus_id,
|
|
6659
|
+
operation_id: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.operation_id,
|
|
6660
|
+
step_id: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.step_id,
|
|
6661
|
+
resource_kind: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.resource_kind,
|
|
6662
|
+
direction: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.direction,
|
|
6663
|
+
target_selector: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.target_selector,
|
|
6664
|
+
target_id: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.target_id,
|
|
6665
|
+
idempotency_key: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.idempotency_key,
|
|
6666
|
+
receipt_id: FLEET_RESOURCES_HISTORICAL_PROJECT_REGISTRATION.receipt_id
|
|
6667
|
+
},
|
|
6668
|
+
destination: FLEET_RESOURCES_CURRENT_PROJECT_REGISTRATION_IDENTITY,
|
|
6669
|
+
lookup_only: true,
|
|
6670
|
+
immutable_receipt: true
|
|
6671
|
+
};
|
|
6672
|
+
});
|
|
6673
|
+
|
|
6394
6674
|
// src/project-registration/identity.ts
|
|
6395
6675
|
function configuredValue(override, envKey) {
|
|
6396
6676
|
return override?.trim() || process.env[envKey]?.trim() || null;
|
|
@@ -6417,12 +6697,13 @@ function resolveMementosProjectAuthorityIdentity(options = {}) {
|
|
|
6417
6697
|
}
|
|
6418
6698
|
function buildMementosProjectRegistrationCapability(options = {}) {
|
|
6419
6699
|
const identity = resolveMementosProjectAuthorityIdentity(options);
|
|
6420
|
-
|
|
6700
|
+
const capability = {
|
|
6421
6701
|
authority: "mementos",
|
|
6422
6702
|
route: MEMENTOS_PROJECT_REGISTRATION_ROUTE,
|
|
6423
6703
|
package_version: options.packageVersion ?? getMementosPackageVersion(),
|
|
6424
6704
|
...identity,
|
|
6425
6705
|
supported_resources: ["project"],
|
|
6706
|
+
supported_historical_lookup_identities: [],
|
|
6426
6707
|
conditional_create: true,
|
|
6427
6708
|
immutable_receipts: true,
|
|
6428
6709
|
exact_terminal_lookup: true,
|
|
@@ -6441,11 +6722,18 @@ function buildMementosProjectRegistrationCapability(options = {}) {
|
|
|
6441
6722
|
stable_keyset_pagination: true,
|
|
6442
6723
|
explicit_membership_only: true
|
|
6443
6724
|
};
|
|
6725
|
+
if (supportsFleetResourcesHistoricalReceiptLookup(capability)) {
|
|
6726
|
+
capability.supported_historical_lookup_identities = [
|
|
6727
|
+
FLEET_RESOURCES_HISTORICAL_LOOKUP_IDENTITY
|
|
6728
|
+
];
|
|
6729
|
+
}
|
|
6730
|
+
return capability;
|
|
6444
6731
|
}
|
|
6445
6732
|
var MEMENTOS_PROJECT_AUTHORITY_ENV, MementosProjectAuthorityIdentityError;
|
|
6446
6733
|
var init_identity = __esm(() => {
|
|
6447
6734
|
init_package_version();
|
|
6448
6735
|
init_types2();
|
|
6736
|
+
init_historical_receipt();
|
|
6449
6737
|
MEMENTOS_PROJECT_AUTHORITY_ENV = {
|
|
6450
6738
|
authorityId: "MEMENTOS_PROJECT_AUTHORITY_ID",
|
|
6451
6739
|
tenantId: "MEMENTOS_PROJECT_TENANT_ID",
|
|
@@ -7272,6 +7560,7 @@ __export(exports_helpers, {
|
|
|
7272
7560
|
colorImportance: () => colorImportance,
|
|
7273
7561
|
colorEntityType: () => colorEntityType,
|
|
7274
7562
|
colorCategory: () => colorCategory,
|
|
7563
|
+
collectPagedRows: () => collectPagedRows,
|
|
7275
7564
|
VALID_SCOPES: () => VALID_SCOPES,
|
|
7276
7565
|
VALID_CATEGORIES: () => VALID_CATEGORIES,
|
|
7277
7566
|
DEFAULT_SNIPPET_LENGTH: () => DEFAULT_SNIPPET_LENGTH,
|
|
@@ -7279,13 +7568,13 @@ __export(exports_helpers, {
|
|
|
7279
7568
|
DEFAULT_COMPACT_LIMIT: () => DEFAULT_COMPACT_LIMIT
|
|
7280
7569
|
});
|
|
7281
7570
|
import chalk from "chalk";
|
|
7282
|
-
import { readFileSync as
|
|
7283
|
-
import { dirname as dirname3, join as
|
|
7571
|
+
import { readFileSync as readFileSync4 } from "fs";
|
|
7572
|
+
import { dirname as dirname3, join as join7, resolve as resolve2 } from "path";
|
|
7284
7573
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
7285
7574
|
function getPackageVersion() {
|
|
7286
7575
|
try {
|
|
7287
|
-
const pkgPath =
|
|
7288
|
-
const pkg = JSON.parse(
|
|
7576
|
+
const pkgPath = join7(dirname3(fileURLToPath3(import.meta.url)), "..", "..", "package.json");
|
|
7577
|
+
const pkg = JSON.parse(readFileSync4(pkgPath, "utf-8"));
|
|
7289
7578
|
return pkg.version || "0.0.0";
|
|
7290
7579
|
} catch {
|
|
7291
7580
|
return "0.0.0";
|
|
@@ -7358,6 +7647,39 @@ function truncateText(value, max = DEFAULT_SNIPPET_LENGTH) {
|
|
|
7358
7647
|
return normalized.slice(0, max);
|
|
7359
7648
|
return `${normalized.slice(0, max - 3)}...`;
|
|
7360
7649
|
}
|
|
7650
|
+
function collectPagedRows(fetchPage, target, offset, opts = {}) {
|
|
7651
|
+
const pageSize = opts.pageSize ?? 1000;
|
|
7652
|
+
const maxPages = opts.maxPages ?? 1000;
|
|
7653
|
+
const want = target === undefined ? undefined : target + 1;
|
|
7654
|
+
const rows = [];
|
|
7655
|
+
const seenCursors = new Set;
|
|
7656
|
+
let cursor = offset;
|
|
7657
|
+
let pages = 0;
|
|
7658
|
+
for (;; ) {
|
|
7659
|
+
if (want !== undefined && rows.length >= want)
|
|
7660
|
+
break;
|
|
7661
|
+
if (++pages > maxPages) {
|
|
7662
|
+
throw new Error(`pagination exceeded ${maxPages} pages while collecting rows \u2014 aborting (cursor cycle?)`);
|
|
7663
|
+
}
|
|
7664
|
+
const limit = Math.min(want === undefined ? pageSize : want - rows.length, pageSize);
|
|
7665
|
+
const page = fetchPage(cursor, limit);
|
|
7666
|
+
rows.push(...page.rows);
|
|
7667
|
+
if (page.has_more === false)
|
|
7668
|
+
break;
|
|
7669
|
+
if (page.has_more === undefined && page.rows.length < limit)
|
|
7670
|
+
break;
|
|
7671
|
+
if (page.has_more === true && (page.next_cursor === null || page.next_cursor === undefined)) {
|
|
7672
|
+
throw new Error("pagination claimed more results without a next cursor \u2014 aborting");
|
|
7673
|
+
}
|
|
7674
|
+
const next = page.next_cursor ?? cursor + page.rows.length;
|
|
7675
|
+
if (seenCursors.has(next)) {
|
|
7676
|
+
throw new Error("pagination repeated a cursor \u2014 aborting");
|
|
7677
|
+
}
|
|
7678
|
+
seenCursors.add(next);
|
|
7679
|
+
cursor = next;
|
|
7680
|
+
}
|
|
7681
|
+
return { rows, hasMore: target !== undefined && rows.length > target };
|
|
7682
|
+
}
|
|
7361
7683
|
function printPageHint(opts) {
|
|
7362
7684
|
const hints = [];
|
|
7363
7685
|
const offset = opts.offset ?? 0;
|
|
@@ -7811,16 +8133,16 @@ function validateConfigKeyValue(key, value, DEFAULT_CONFIG) {
|
|
|
7811
8133
|
return null;
|
|
7812
8134
|
}
|
|
7813
8135
|
function getConfigPath() {
|
|
7814
|
-
const { homedir:
|
|
7815
|
-
return
|
|
8136
|
+
const { homedir: homedir4 } = __require("os");
|
|
8137
|
+
return join7(homedir4(), ".hasna", "mementos", "config.json");
|
|
7816
8138
|
}
|
|
7817
8139
|
function readFileConfig() {
|
|
7818
|
-
const { existsSync:
|
|
8140
|
+
const { existsSync: existsSync5 } = __require("fs");
|
|
7819
8141
|
const configPath = getConfigPath();
|
|
7820
|
-
if (!
|
|
8142
|
+
if (!existsSync5(configPath))
|
|
7821
8143
|
return {};
|
|
7822
8144
|
try {
|
|
7823
|
-
const data = JSON.parse(
|
|
8145
|
+
const data = JSON.parse(readFileSync4(configPath, "utf-8"));
|
|
7824
8146
|
if (data === null || typeof data !== "object" || Array.isArray(data)) {
|
|
7825
8147
|
throw new Error("expected a JSON object");
|
|
7826
8148
|
}
|
|
@@ -7831,10 +8153,10 @@ function readFileConfig() {
|
|
|
7831
8153
|
}
|
|
7832
8154
|
}
|
|
7833
8155
|
function writeFileConfig(data) {
|
|
7834
|
-
const { existsSync:
|
|
8156
|
+
const { existsSync: existsSync5, writeFileSync: writeFileSync3, mkdirSync: mkdirSync3 } = __require("fs");
|
|
7835
8157
|
const configPath = getConfigPath();
|
|
7836
8158
|
const dir = dirname3(configPath);
|
|
7837
|
-
if (!
|
|
8159
|
+
if (!existsSync5(dir))
|
|
7838
8160
|
mkdirSync3(dir, { recursive: true });
|
|
7839
8161
|
writeFileSync3(configPath, JSON.stringify(data, null, 2) + `
|
|
7840
8162
|
`, "utf-8");
|
|
@@ -8262,7 +8584,7 @@ function buildFilterConditions(filter) {
|
|
|
8262
8584
|
const conditions = [];
|
|
8263
8585
|
const params = [];
|
|
8264
8586
|
conditions.push("m.status = 'active'");
|
|
8265
|
-
conditions.push("(m.expires_at IS NULL OR m.expires_at >=
|
|
8587
|
+
conditions.push("(m.expires_at IS NULL OR m.expires_at >= strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))");
|
|
8266
8588
|
if (!filter)
|
|
8267
8589
|
return { conditions, params };
|
|
8268
8590
|
if (filter.scope) {
|
|
@@ -10342,7 +10664,7 @@ async function detectContradiction(newKey, newValue, options = {}, db) {
|
|
|
10342
10664
|
conditions.push("project_id = ?");
|
|
10343
10665
|
params.push(project_id);
|
|
10344
10666
|
}
|
|
10345
|
-
conditions.push("(valid_until IS NULL OR valid_until >
|
|
10667
|
+
conditions.push("(valid_until IS NULL OR valid_until > strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))");
|
|
10346
10668
|
const sql = `SELECT * FROM memories WHERE ${conditions.join(" AND ")} ORDER BY importance DESC LIMIT 10`;
|
|
10347
10669
|
const rows = d.query(sql).all(...params);
|
|
10348
10670
|
if (rows.length === 0) {
|
|
@@ -11536,10 +11858,12 @@ var init_synthesis2 = __esm(() => {
|
|
|
11536
11858
|
var exports_session_jobs = {};
|
|
11537
11859
|
__export(exports_session_jobs, {
|
|
11538
11860
|
updateSessionJob: () => updateSessionJob,
|
|
11861
|
+
recoverStaleProcessingJobs: () => recoverStaleProcessingJobs,
|
|
11539
11862
|
listSessionJobs: () => listSessionJobs,
|
|
11540
11863
|
getSessionJob: () => getSessionJob,
|
|
11541
11864
|
getNextPendingJob: () => getNextPendingJob,
|
|
11542
|
-
createSessionJob: () => createSessionJob
|
|
11865
|
+
createSessionJob: () => createSessionJob,
|
|
11866
|
+
claimSessionJob: () => claimSessionJob
|
|
11543
11867
|
});
|
|
11544
11868
|
function parseJobRow(row) {
|
|
11545
11869
|
return {
|
|
@@ -11669,6 +11993,18 @@ function getNextPendingJob(db) {
|
|
|
11669
11993
|
return null;
|
|
11670
11994
|
return parseJobRow(row);
|
|
11671
11995
|
}
|
|
11996
|
+
function claimSessionJob(id, db) {
|
|
11997
|
+
const d = db || getDatabase();
|
|
11998
|
+
const startedAt = now();
|
|
11999
|
+
const result = d.run("UPDATE session_memory_jobs SET status = 'processing', started_at = ? WHERE id = ? AND status = 'pending'", [startedAt, id]);
|
|
12000
|
+
return result.changes;
|
|
12001
|
+
}
|
|
12002
|
+
function recoverStaleProcessingJobs(maxAgeMs, db) {
|
|
12003
|
+
const d = db || getDatabase();
|
|
12004
|
+
const cutoff = new Date(Date.now() - maxAgeMs).toISOString();
|
|
12005
|
+
const result = d.run("UPDATE session_memory_jobs SET status = 'pending', started_at = NULL WHERE status = 'processing' AND started_at < ?", [cutoff]);
|
|
12006
|
+
return result.changes;
|
|
12007
|
+
}
|
|
11672
12008
|
var init_session_jobs = __esm(() => {
|
|
11673
12009
|
init_database();
|
|
11674
12010
|
init_api_mode();
|
|
@@ -12207,7 +12543,11 @@ async function processSessionJob(jobId, db) {
|
|
|
12207
12543
|
return result;
|
|
12208
12544
|
}
|
|
12209
12545
|
try {
|
|
12210
|
-
|
|
12546
|
+
const changes = claimSessionJob(jobId, db);
|
|
12547
|
+
if (changes === 0) {
|
|
12548
|
+
result.errors.push(`Job already claimed or not pending: ${jobId}`);
|
|
12549
|
+
return result;
|
|
12550
|
+
}
|
|
12211
12551
|
} catch (e) {
|
|
12212
12552
|
result.errors.push(`Failed to mark job as processing: ${String(e)}`);
|
|
12213
12553
|
return result;
|
|
@@ -12330,6 +12670,9 @@ function startSessionQueueWorker() {
|
|
|
12330
12670
|
return;
|
|
12331
12671
|
_workerStarted = true;
|
|
12332
12672
|
setInterval(() => {
|
|
12673
|
+
try {
|
|
12674
|
+
recoverStaleProcessingJobs(30 * 60 * 1000);
|
|
12675
|
+
} catch {}
|
|
12333
12676
|
_processNext();
|
|
12334
12677
|
}, 5000);
|
|
12335
12678
|
}
|
|
@@ -12383,13 +12726,13 @@ __export(exports_session_registry, {
|
|
|
12383
12726
|
closeRegistry: () => closeRegistry,
|
|
12384
12727
|
cleanStaleSessions: () => cleanStaleSessions
|
|
12385
12728
|
});
|
|
12386
|
-
import { existsSync as
|
|
12387
|
-
import { dirname as dirname6, join as
|
|
12729
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync5 } from "fs";
|
|
12730
|
+
import { dirname as dirname6, join as join10 } from "path";
|
|
12388
12731
|
function getDb() {
|
|
12389
12732
|
if (_db2)
|
|
12390
12733
|
return _db2;
|
|
12391
12734
|
const dir = dirname6(DB_PATH);
|
|
12392
|
-
if (!
|
|
12735
|
+
if (!existsSync9(dir))
|
|
12393
12736
|
mkdirSync5(dir, { recursive: true });
|
|
12394
12737
|
_db2 = new SqliteAdapter(DB_PATH);
|
|
12395
12738
|
_db2.run("PRAGMA journal_mode = WAL");
|
|
@@ -12564,7 +12907,7 @@ function closeRegistry() {
|
|
|
12564
12907
|
var DB_PATH, _db2 = null;
|
|
12565
12908
|
var init_session_registry = __esm(() => {
|
|
12566
12909
|
init_storage();
|
|
12567
|
-
DB_PATH =
|
|
12910
|
+
DB_PATH = join10(process.env["HOME"] || process.env["USERPROFILE"] || "~", ".open-sessions-registry.db");
|
|
12568
12911
|
});
|
|
12569
12912
|
|
|
12570
12913
|
// src/db/pg-migrations.ts
|
|
@@ -27040,7 +27383,7 @@ class JSONSchemaGenerator {
|
|
|
27040
27383
|
if (val === undefined) {
|
|
27041
27384
|
if (this.unrepresentable === "throw") {
|
|
27042
27385
|
throw new Error("Literal `undefined` cannot be represented in JSON Schema");
|
|
27043
|
-
}
|
|
27386
|
+
}
|
|
27044
27387
|
} else if (typeof val === "bigint") {
|
|
27045
27388
|
if (this.unrepresentable === "throw") {
|
|
27046
27389
|
throw new Error("BigInt literals cannot be represented in JSON Schema");
|
|
@@ -48690,7 +49033,7 @@ var require_tracestate_impl = __commonJS((exports) => {
|
|
|
48690
49033
|
const value = listMember.slice(i + 1, part.length);
|
|
48691
49034
|
if ((0, tracestate_validators_1.validateKey)(key) && (0, tracestate_validators_1.validateValue)(value)) {
|
|
48692
49035
|
agg.set(key, value);
|
|
48693
|
-
}
|
|
49036
|
+
}
|
|
48694
49037
|
}
|
|
48695
49038
|
return agg;
|
|
48696
49039
|
}, new Map);
|
|
@@ -62045,8 +62388,8 @@ var {
|
|
|
62045
62388
|
|
|
62046
62389
|
// src/cli/index.tsx
|
|
62047
62390
|
init_database();
|
|
62048
|
-
import { readFileSync as
|
|
62049
|
-
import { dirname as dirname8, join as
|
|
62391
|
+
import { readFileSync as readFileSync10 } from "fs";
|
|
62392
|
+
import { dirname as dirname8, join as join14 } from "path";
|
|
62050
62393
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
62051
62394
|
|
|
62052
62395
|
// src/db/machines.ts
|
|
@@ -63487,6 +63830,7 @@ import { createHash as createHash3 } from "crypto";
|
|
|
63487
63830
|
init_projects();
|
|
63488
63831
|
init_types2();
|
|
63489
63832
|
init_identity();
|
|
63833
|
+
init_historical_receipt();
|
|
63490
63834
|
function canonicalMementosProjectRegistrationJson(value) {
|
|
63491
63835
|
return JSON.stringify(canonicalize2(value));
|
|
63492
63836
|
}
|
|
@@ -64044,6 +64388,18 @@ function registerCrudCommands(program2) {
|
|
|
64044
64388
|
}
|
|
64045
64389
|
resolvedAgentId = ag.id;
|
|
64046
64390
|
}
|
|
64391
|
+
const requestedSource = opts.source;
|
|
64392
|
+
const claimsAgentAuthor = !requestedSource || requestedSource === "agent";
|
|
64393
|
+
if (!resolvedAgentId && claimsAgentAuthor) {
|
|
64394
|
+
const writingName = resolveWritingAgentName();
|
|
64395
|
+
if (writingName) {
|
|
64396
|
+
resolvedAgentId = getAgent(writingName)?.id ?? registerAgent(writingName).id;
|
|
64397
|
+
} else if (requestedSource === "agent") {
|
|
64398
|
+
throw new Error(`No agent identity: an agent-source save needs a writing agent, and none could be resolved.
|
|
64399
|
+
` + `Pass --agent <name>, set MEMENTOS_AGENT, or write the fleet identity file ` + `(~/.hasna/conversations/agent-id, produced by "conversations agents register").
|
|
64400
|
+
` + `To write without claiming an agent author, omit --source or pass ` + `--source user|system|auto|imported.`);
|
|
64401
|
+
}
|
|
64402
|
+
}
|
|
64047
64403
|
const input = {
|
|
64048
64404
|
key,
|
|
64049
64405
|
value,
|
|
@@ -64053,7 +64409,7 @@ function registerCrudCommands(program2) {
|
|
|
64053
64409
|
tags: mergedTags,
|
|
64054
64410
|
summary: opts.summary,
|
|
64055
64411
|
ttl_ms: opts.ttl ? parseDuration(opts.ttl) : undefined,
|
|
64056
|
-
source:
|
|
64412
|
+
source: requestedSource,
|
|
64057
64413
|
agent_id: resolvedAgentId,
|
|
64058
64414
|
session_id: globalOpts.session
|
|
64059
64415
|
};
|
|
@@ -64120,6 +64476,10 @@ function registerCrudCommands(program2) {
|
|
|
64120
64476
|
const updateInput = {
|
|
64121
64477
|
version: existing.version
|
|
64122
64478
|
};
|
|
64479
|
+
const writingName = resolveWritingAgentName();
|
|
64480
|
+
if (writingName) {
|
|
64481
|
+
updateInput.updated_by_agent = getAgent(writingName)?.id ?? registerAgent(writingName).id;
|
|
64482
|
+
}
|
|
64123
64483
|
if (opts.value !== undefined)
|
|
64124
64484
|
updateInput.value = opts.value;
|
|
64125
64485
|
if (opts.importance !== undefined)
|
|
@@ -64147,7 +64507,7 @@ function registerCrudCommands(program2) {
|
|
|
64147
64507
|
if (violation)
|
|
64148
64508
|
throw new Error(formatEnumViolation(violation));
|
|
64149
64509
|
}
|
|
64150
|
-
const changedFields = Object.keys(updateInput).filter((k) => k !== "version");
|
|
64510
|
+
const changedFields = Object.keys(updateInput).filter((k) => k !== "version" && k !== "updated_by_agent");
|
|
64151
64511
|
if (changedFields.length === 0) {
|
|
64152
64512
|
throw new Error(`Nothing to update: no fields were given for ${existing.key} (${existing.id.slice(0, 8)}). ` + `Pass at least one of --value, --scope, --category, --status, --importance, --tags, --summary, --pin/--unpin. ` + `Note that -s is the global --session, not --scope.`);
|
|
64153
64513
|
}
|
|
@@ -64177,8 +64537,7 @@ function registerCrudCommands(program2) {
|
|
|
64177
64537
|
}
|
|
64178
64538
|
const matches = getMemoriesByKey(keyOrId, opts.scope, opts.agent, opts.project);
|
|
64179
64539
|
if (matches.length === 0) {
|
|
64180
|
-
|
|
64181
|
-
if (isApiMode() && looksLikeId && deleteMemory(keyOrId)) {
|
|
64540
|
+
if (isApiMode() && keyOrId.length > 0 && deleteMemory(keyOrId)) {
|
|
64182
64541
|
if (globalOpts.json) {
|
|
64183
64542
|
outputJson({ deleted: keyOrId });
|
|
64184
64543
|
} else {
|
|
@@ -64750,7 +65109,7 @@ function registerRemoveCommand(program2) {
|
|
|
64750
65109
|
if (mem)
|
|
64751
65110
|
id = mem.id;
|
|
64752
65111
|
}
|
|
64753
|
-
if (!id && isApiMode() &&
|
|
65112
|
+
if (!id && isApiMode() && nameOrId.length > 0) {
|
|
64754
65113
|
id = nameOrId;
|
|
64755
65114
|
}
|
|
64756
65115
|
if (!id) {
|
|
@@ -64878,15 +65237,17 @@ function registerListCommand(program2) {
|
|
|
64878
65237
|
const fmt = getOutputFormat(program2, opts.format);
|
|
64879
65238
|
const isStructured = fmt === "json" || fmt === "csv" || fmt === "yaml";
|
|
64880
65239
|
const requestedLimit = opts.limit;
|
|
64881
|
-
const limit = positiveIntOrDefault(requestedLimit, isStructured ? 50 : DEFAULT_COMPACT_LIMIT);
|
|
64882
|
-
const offset = cursorOrOffset(opts.cursor, opts.offset);
|
|
65240
|
+
const limit = requestedLimit === undefined ? isStructured ? undefined : DEFAULT_COMPACT_LIMIT : positiveIntOrDefault(requestedLimit, isStructured ? 50 : DEFAULT_COMPACT_LIMIT);
|
|
65241
|
+
const offset = cursorOrOffset(opts.cursor, opts.offset) ?? 0;
|
|
64883
65242
|
const agentId = resolveAgentFilter(opts.agent || globalOpts.agent);
|
|
64884
65243
|
const projectPath = opts.project || globalOpts.project;
|
|
64885
65244
|
let projectId;
|
|
64886
65245
|
if (projectPath) {
|
|
64887
65246
|
const project = getProject(resolve7(projectPath));
|
|
64888
|
-
if (project)
|
|
64889
|
-
|
|
65247
|
+
if (!project) {
|
|
65248
|
+
throw new Error(`Project not found: ${projectPath}`);
|
|
65249
|
+
}
|
|
65250
|
+
projectId = project.id;
|
|
64890
65251
|
}
|
|
64891
65252
|
const filter = {
|
|
64892
65253
|
scope: opts.scope,
|
|
@@ -64896,16 +65257,24 @@ function registerListCommand(program2) {
|
|
|
64896
65257
|
pinned: opts.pinned ? true : undefined,
|
|
64897
65258
|
agent_id: agentId,
|
|
64898
65259
|
project_id: projectId,
|
|
64899
|
-
limit: isStructured ? limit : limit + 1,
|
|
64900
|
-
offset,
|
|
64901
65260
|
status: opts.status,
|
|
64902
65261
|
session_id: opts.session || globalOpts.session
|
|
64903
65262
|
};
|
|
64904
|
-
const
|
|
64905
|
-
|
|
64906
|
-
|
|
65263
|
+
const { rows: collected, hasMore } = collectPagedRows((cursor, pageLimit) => {
|
|
65264
|
+
const page = listMemoriesPage({
|
|
65265
|
+
...filter,
|
|
65266
|
+
limit: pageLimit,
|
|
65267
|
+
offset: cursor
|
|
65268
|
+
});
|
|
65269
|
+
return {
|
|
65270
|
+
rows: page.rows,
|
|
65271
|
+
has_more: page.has_more,
|
|
65272
|
+
next_cursor: page.next_cursor
|
|
65273
|
+
};
|
|
65274
|
+
}, limit, offset);
|
|
65275
|
+
const memories = hasMore && limit !== undefined ? collected.slice(0, limit) : collected;
|
|
64907
65276
|
if (fmt === "json") {
|
|
64908
|
-
outputJson(
|
|
65277
|
+
outputJson(memories);
|
|
64909
65278
|
return;
|
|
64910
65279
|
}
|
|
64911
65280
|
if (fmt === "csv") {
|
|
@@ -64933,7 +65302,7 @@ function registerListCommand(program2) {
|
|
|
64933
65302
|
}
|
|
64934
65303
|
printPageHint({
|
|
64935
65304
|
shown: memories.length,
|
|
64936
|
-
limit,
|
|
65305
|
+
limit: limit ?? memories.length,
|
|
64937
65306
|
offset,
|
|
64938
65307
|
hasMore,
|
|
64939
65308
|
command: "mementos list",
|
|
@@ -64973,7 +65342,10 @@ function getMemoryStats(db) {
|
|
|
64973
65342
|
const byCategory = d.query("SELECT category, COUNT(*) as c FROM memories WHERE status = 'active' GROUP BY category").all();
|
|
64974
65343
|
const byStatus = d.query("SELECT status, COUNT(*) as c FROM memories WHERE status = 'active' GROUP BY status").all();
|
|
64975
65344
|
const pinnedCount = d.query("SELECT COUNT(*) as c FROM memories WHERE pinned = 1 AND status = 'active'").get().c;
|
|
64976
|
-
const expiredCount = d.query("SELECT COUNT(*) as c FROM memories WHERE status = 'expired'
|
|
65345
|
+
const expiredCount = d.query("SELECT COUNT(*) as c FROM memories WHERE status = 'expired'").get().c;
|
|
65346
|
+
const expiresAtCount = d.query("SELECT COUNT(*) as c FROM memories WHERE expires_at IS NOT NULL").get().c;
|
|
65347
|
+
const nowIso = new Date().toISOString();
|
|
65348
|
+
const expiredDueCount = d.query("SELECT COUNT(*) as c FROM memories WHERE status = 'expired' OR (expires_at IS NOT NULL AND expires_at < ?)").get(nowIso).c;
|
|
64977
65349
|
const stats = {
|
|
64978
65350
|
total,
|
|
64979
65351
|
by_scope: { global: 0, shared: 0, private: 0, working: 0 },
|
|
@@ -64981,7 +65353,9 @@ function getMemoryStats(db) {
|
|
|
64981
65353
|
by_status: { active: 0, archived: 0, expired: 0 },
|
|
64982
65354
|
by_agent: {},
|
|
64983
65355
|
pinned_count: pinnedCount,
|
|
64984
|
-
expired_count: expiredCount
|
|
65356
|
+
expired_count: expiredCount,
|
|
65357
|
+
expires_at_count: expiresAtCount,
|
|
65358
|
+
expired_due_count: expiredDueCount
|
|
64985
65359
|
};
|
|
64986
65360
|
for (const row of byScope)
|
|
64987
65361
|
if (row.scope in stats.by_scope)
|
|
@@ -65015,7 +65389,9 @@ function normalizeStats(data) {
|
|
|
65015
65389
|
by_status: { active: 0, archived: 0, expired: 0, ...data?.by_status ?? {} },
|
|
65016
65390
|
by_agent: data?.by_agent ?? {},
|
|
65017
65391
|
pinned_count: data?.pinned_count ?? 0,
|
|
65018
|
-
expired_count: data?.expired_count ?? 0
|
|
65392
|
+
expired_count: data?.expired_count ?? 0,
|
|
65393
|
+
expires_at_count: data?.expires_at_count ?? 0,
|
|
65394
|
+
expired_due_count: data?.expired_due_count ?? 0
|
|
65019
65395
|
};
|
|
65020
65396
|
}
|
|
65021
65397
|
function getMemoryReport(filter = {}, db) {
|
|
@@ -65068,19 +65444,31 @@ function getMemoryReport(filter = {}, db) {
|
|
|
65068
65444
|
top_agents: topAgents
|
|
65069
65445
|
};
|
|
65070
65446
|
}
|
|
65071
|
-
function
|
|
65447
|
+
function getStaleMemoriesPage(filter = {}, db) {
|
|
65072
65448
|
const days = Math.min(filter.days || 30, 365);
|
|
65073
65449
|
const limit = filter.limit ?? 20;
|
|
65074
65450
|
const offset = filter.offset ?? 0;
|
|
65075
65451
|
if (!db && isApiMode()) {
|
|
65076
|
-
const q = toQuery({ days, project_id: filter.project_id, agent_id: filter.agent_id, limit, offset });
|
|
65452
|
+
const q = toQuery({ days, project_id: filter.project_id, agent_id: filter.agent_id, pinned: filter.pinned, limit, offset });
|
|
65077
65453
|
const { data } = apiJson("GET", `/memories/stale${q}`);
|
|
65078
|
-
|
|
65454
|
+
const rows2 = data?.memories ?? [];
|
|
65455
|
+
return {
|
|
65456
|
+
rows: rows2,
|
|
65457
|
+
total: data?.total ?? rows2.length,
|
|
65458
|
+
has_more: data?.has_more,
|
|
65459
|
+
next_cursor: data?.next_cursor ?? null
|
|
65460
|
+
};
|
|
65079
65461
|
}
|
|
65080
65462
|
const d = db || getDatabase();
|
|
65081
65463
|
const cutoffDate = new Date(Date.now() - days * 86400000).toISOString();
|
|
65082
|
-
const conds = ["status = 'active'", "(accessed_at IS NULL OR accessed_at < ?)"
|
|
65464
|
+
const conds = ["status = 'active'", "(accessed_at IS NULL OR accessed_at < ?)"];
|
|
65083
65465
|
const params = [cutoffDate];
|
|
65466
|
+
if (filter.pinned !== undefined) {
|
|
65467
|
+
conds.push("pinned = ?");
|
|
65468
|
+
params.push(filter.pinned ? 1 : 0);
|
|
65469
|
+
} else {
|
|
65470
|
+
conds.push("pinned = 0");
|
|
65471
|
+
}
|
|
65084
65472
|
if (filter.project_id) {
|
|
65085
65473
|
conds.push("project_id = ?");
|
|
65086
65474
|
params.push(filter.project_id);
|
|
@@ -65089,13 +65477,22 @@ function getStaleMemories(filter = {}, db) {
|
|
|
65089
65477
|
conds.push("agent_id = ?");
|
|
65090
65478
|
params.push(filter.agent_id);
|
|
65091
65479
|
}
|
|
65092
|
-
|
|
65480
|
+
const where = conds.join(" AND ");
|
|
65481
|
+
const countRow = d.query(`SELECT COUNT(*) AS c FROM memories WHERE ${where}`).get(...params);
|
|
65482
|
+
let sql = `SELECT id, key, value, importance, scope, category, accessed_at, access_count, created_at FROM memories WHERE ${where} ORDER BY COALESCE(accessed_at, created_at) ASC LIMIT ?`;
|
|
65093
65483
|
params.push(limit);
|
|
65094
65484
|
if (offset) {
|
|
65095
65485
|
sql += " OFFSET ?";
|
|
65096
65486
|
params.push(offset);
|
|
65097
65487
|
}
|
|
65098
|
-
|
|
65488
|
+
const rows = d.query(sql).all(...params);
|
|
65489
|
+
const hasMore = rows.length === limit;
|
|
65490
|
+
return {
|
|
65491
|
+
rows,
|
|
65492
|
+
total: countRow?.c ?? 0,
|
|
65493
|
+
has_more: hasMore,
|
|
65494
|
+
next_cursor: hasMore ? offset + rows.length : null
|
|
65495
|
+
};
|
|
65099
65496
|
}
|
|
65100
65497
|
|
|
65101
65498
|
// src/cli/commands/info-stats.ts
|
|
@@ -65248,14 +65645,14 @@ init_projects();
|
|
|
65248
65645
|
init_helpers();
|
|
65249
65646
|
function registerStaleCommand(program2) {
|
|
65250
65647
|
const handleError = makeHandleError(program2);
|
|
65251
|
-
program2.command("stale").description("Find memories not accessed recently (for cleanup/review)").option("--days <n>", "Stale threshold in days (default: 30)", parseInt).option("--project <path>", "Project filter").option("--agent <name>", "Agent filter").option("--limit <n>", "Max results (default: 20)", parseInt).option("--offset <n>", "Offset for pagination", parseInt).option("--cursor <n>", "Cursor offset for the next page", parseInt).option("--format <fmt>", "Output format: compact (default), json").option("--verbose", "Show wider memory snippets").action((opts) => {
|
|
65648
|
+
program2.command("stale").description("Find memories not accessed recently (for cleanup/review)").option("--days <n>", "Stale threshold in days (default: 30)", parseInt).option("--pinned", "Review stale PINNED memories (default view excludes pinned)").option("--project <path>", "Project filter").option("--agent <name>", "Agent filter").option("--limit <n>", "Max results (default: 20)", parseInt).option("--offset <n>", "Offset for pagination", parseInt).option("--cursor <n>", "Cursor offset for the next page", parseInt).option("--format <fmt>", "Output format: compact (default), json").option("--verbose", "Show wider memory snippets").action((opts) => {
|
|
65252
65649
|
try {
|
|
65253
65650
|
const globalOpts = program2.opts();
|
|
65254
65651
|
const days = opts.days || 30;
|
|
65255
65652
|
const fmt = getOutputFormat(program2, opts.format);
|
|
65256
65653
|
const isJson = fmt === "json";
|
|
65257
65654
|
const limit = positiveIntOrDefault(opts.limit, isJson ? 20 : DEFAULT_COMPACT_LIMIT);
|
|
65258
|
-
const offset = cursorOrOffset(opts.cursor, opts.offset);
|
|
65655
|
+
const offset = cursorOrOffset(opts.cursor, opts.offset) ?? 0;
|
|
65259
65656
|
const projectPath = opts.project || globalOpts.project;
|
|
65260
65657
|
let projectId;
|
|
65261
65658
|
if (projectPath) {
|
|
@@ -65264,17 +65661,37 @@ function registerStaleCommand(program2) {
|
|
|
65264
65661
|
projectId = project.id;
|
|
65265
65662
|
}
|
|
65266
65663
|
const agentId = resolveAgentFilter(opts.agent || globalOpts.agent);
|
|
65267
|
-
|
|
65268
|
-
|
|
65269
|
-
|
|
65270
|
-
|
|
65271
|
-
|
|
65272
|
-
|
|
65273
|
-
|
|
65274
|
-
|
|
65275
|
-
|
|
65664
|
+
let staleTotal = 0;
|
|
65665
|
+
let firstPage = true;
|
|
65666
|
+
const { rows: collected, hasMore } = collectPagedRows((cursor, pageLimit) => {
|
|
65667
|
+
const page = getStaleMemoriesPage({
|
|
65668
|
+
days,
|
|
65669
|
+
pinned: opts.pinned ? true : undefined,
|
|
65670
|
+
project_id: projectId,
|
|
65671
|
+
agent_id: agentId,
|
|
65672
|
+
limit: pageLimit,
|
|
65673
|
+
offset: cursor
|
|
65674
|
+
});
|
|
65675
|
+
if (firstPage) {
|
|
65676
|
+
staleTotal = page.total;
|
|
65677
|
+
firstPage = false;
|
|
65678
|
+
}
|
|
65679
|
+
return {
|
|
65680
|
+
rows: page.rows,
|
|
65681
|
+
has_more: page.has_more,
|
|
65682
|
+
next_cursor: page.next_cursor
|
|
65683
|
+
};
|
|
65684
|
+
}, limit, offset);
|
|
65685
|
+
const displayRows = hasMore ? collected.slice(0, limit) : collected;
|
|
65276
65686
|
if (fmt === "json") {
|
|
65277
|
-
outputJson({
|
|
65687
|
+
outputJson({
|
|
65688
|
+
stale_count: staleTotal,
|
|
65689
|
+
returned: displayRows.length,
|
|
65690
|
+
threshold_days: days,
|
|
65691
|
+
has_more: hasMore,
|
|
65692
|
+
next_cursor: hasMore ? offset + displayRows.length : null,
|
|
65693
|
+
memories: displayRows
|
|
65694
|
+
});
|
|
65278
65695
|
return;
|
|
65279
65696
|
}
|
|
65280
65697
|
if (displayRows.length === 0) {
|
|
@@ -65313,13 +65730,20 @@ function registerHistoryCommand(program2) {
|
|
|
65313
65730
|
try {
|
|
65314
65731
|
const globalOpts = program2.opts();
|
|
65315
65732
|
const isJson = Boolean(globalOpts.json);
|
|
65316
|
-
const
|
|
65317
|
-
const
|
|
65318
|
-
const
|
|
65319
|
-
const hasMore =
|
|
65320
|
-
|
|
65733
|
+
const requestedLimit = opts.limit;
|
|
65734
|
+
const limit = requestedLimit === undefined ? isJson ? undefined : DEFAULT_SEARCH_LIMIT : positiveIntOrDefault(requestedLimit, isJson ? 20 : DEFAULT_SEARCH_LIMIT);
|
|
65735
|
+
const offset = cursorOrOffset(opts.cursor, opts.offset) ?? 0;
|
|
65736
|
+
const { rows: collected, hasMore } = collectPagedRows((cursor, pageLimit) => {
|
|
65737
|
+
const page = listMemoryHistoryPage({ limit: pageLimit, offset: cursor });
|
|
65738
|
+
return {
|
|
65739
|
+
rows: page.rows,
|
|
65740
|
+
has_more: page.has_more,
|
|
65741
|
+
next_cursor: page.next_cursor
|
|
65742
|
+
};
|
|
65743
|
+
}, limit, offset);
|
|
65744
|
+
const memories = hasMore && limit !== undefined ? collected.slice(0, limit) : collected;
|
|
65321
65745
|
if (globalOpts.json) {
|
|
65322
|
-
outputJson(
|
|
65746
|
+
outputJson(memories);
|
|
65323
65747
|
return;
|
|
65324
65748
|
}
|
|
65325
65749
|
if (memories.length === 0) {
|
|
@@ -65337,7 +65761,7 @@ function registerHistoryCommand(program2) {
|
|
|
65337
65761
|
}
|
|
65338
65762
|
printPageHint({
|
|
65339
65763
|
shown: memories.length,
|
|
65340
|
-
limit,
|
|
65764
|
+
limit: limit ?? memories.length,
|
|
65341
65765
|
offset,
|
|
65342
65766
|
hasMore,
|
|
65343
65767
|
command: "mementos history",
|
|
@@ -65529,10 +65953,9 @@ function registerExportCommand(program2) {
|
|
|
65529
65953
|
scope: opts.scope,
|
|
65530
65954
|
category: opts.category,
|
|
65531
65955
|
agent_id: agentId,
|
|
65532
|
-
project_id: projectId
|
|
65533
|
-
limit: 1e4
|
|
65956
|
+
project_id: projectId
|
|
65534
65957
|
};
|
|
65535
|
-
const memories =
|
|
65958
|
+
const memories = listMemoriesBounded(filter, 1e4).rows;
|
|
65536
65959
|
outputJson(memories);
|
|
65537
65960
|
} catch (e) {
|
|
65538
65961
|
handleError(e);
|
|
@@ -65545,7 +65968,7 @@ init_memories();
|
|
|
65545
65968
|
init_helpers();
|
|
65546
65969
|
import chalk18 from "chalk";
|
|
65547
65970
|
import { resolve as resolve12 } from "path";
|
|
65548
|
-
import { readFileSync as
|
|
65971
|
+
import { readFileSync as readFileSync5 } from "fs";
|
|
65549
65972
|
function registerImportCommand(program2) {
|
|
65550
65973
|
const handleError = makeHandleError(program2);
|
|
65551
65974
|
program2.command("import [file]").description("Import memories from a JSON file or stdin (use '-' or pipe data)").option("--overwrite", "Overwrite existing memories (default: merge)").action(async (file, opts) => {
|
|
@@ -65555,7 +65978,7 @@ function registerImportCommand(program2) {
|
|
|
65555
65978
|
if (file === "-" || !file && !process.stdin.isTTY) {
|
|
65556
65979
|
raw = await Bun.stdin.text();
|
|
65557
65980
|
} else if (file) {
|
|
65558
|
-
raw =
|
|
65981
|
+
raw = readFileSync5(resolve12(file), "utf-8");
|
|
65559
65982
|
} else {
|
|
65560
65983
|
console.error(chalk18.red("No input: provide a file path, use '-' for stdin, or pipe data."));
|
|
65561
65984
|
process.exit(1);
|
|
@@ -65585,14 +66008,14 @@ function registerImportCommand(program2) {
|
|
|
65585
66008
|
import chalk19 from "chalk";
|
|
65586
66009
|
|
|
65587
66010
|
// src/lib/config.ts
|
|
65588
|
-
import { existsSync as
|
|
65589
|
-
import { homedir as
|
|
65590
|
-
import { basename, dirname as dirname4, join as
|
|
66011
|
+
import { existsSync as existsSync5, mkdirSync as mkdirSync3, readFileSync as readFileSync6, readdirSync, writeFileSync as writeFileSync3, unlinkSync as unlinkSync2, cpSync as cpSync2 } from "fs";
|
|
66012
|
+
import { homedir as homedir4 } from "os";
|
|
66013
|
+
import { basename, dirname as dirname4, join as join8, resolve as resolve13 } from "path";
|
|
65591
66014
|
function isInMemoryDb2(path) {
|
|
65592
66015
|
return path === ":memory:" || path.startsWith("file::memory:");
|
|
65593
66016
|
}
|
|
65594
66017
|
function homeDir() {
|
|
65595
|
-
return process.env["HOME"] || process.env["USERPROFILE"] ||
|
|
66018
|
+
return process.env["HOME"] || process.env["USERPROFILE"] || homedir4();
|
|
65596
66019
|
}
|
|
65597
66020
|
var DEFAULT_CONFIG = {
|
|
65598
66021
|
default_scope: "private",
|
|
@@ -65650,11 +66073,11 @@ function isValidCategory(value) {
|
|
|
65650
66073
|
return VALID_CATEGORIES2.includes(value);
|
|
65651
66074
|
}
|
|
65652
66075
|
function loadConfig() {
|
|
65653
|
-
const configPath =
|
|
66076
|
+
const configPath = join8(homeDir(), ".hasna", "mementos", "config.json");
|
|
65654
66077
|
let fileConfig = {};
|
|
65655
|
-
if (
|
|
66078
|
+
if (existsSync5(configPath)) {
|
|
65656
66079
|
try {
|
|
65657
|
-
const raw =
|
|
66080
|
+
const raw = readFileSync6(configPath, "utf-8");
|
|
65658
66081
|
fileConfig = JSON.parse(raw);
|
|
65659
66082
|
} catch {}
|
|
65660
66083
|
}
|
|
@@ -65680,8 +66103,8 @@ function findFileWalkingUp(filename) {
|
|
|
65680
66103
|
let dir = process.cwd();
|
|
65681
66104
|
const legacyHomeMementosDb = resolve13(homeDir(), ".mementos", "mementos.db");
|
|
65682
66105
|
while (true) {
|
|
65683
|
-
const candidate =
|
|
65684
|
-
if (
|
|
66106
|
+
const candidate = join8(dir, filename);
|
|
66107
|
+
if (existsSync5(candidate) && resolve13(candidate) !== legacyHomeMementosDb) {
|
|
65685
66108
|
return candidate;
|
|
65686
66109
|
}
|
|
65687
66110
|
const parent = dirname4(dir);
|
|
@@ -65694,7 +66117,7 @@ function findFileWalkingUp(filename) {
|
|
|
65694
66117
|
function findGitRoot2() {
|
|
65695
66118
|
let dir = process.cwd();
|
|
65696
66119
|
while (true) {
|
|
65697
|
-
if (
|
|
66120
|
+
if (existsSync5(join8(dir, ".git"))) {
|
|
65698
66121
|
return dir;
|
|
65699
66122
|
}
|
|
65700
66123
|
const parent = dirname4(dir);
|
|
@@ -65705,27 +66128,27 @@ function findGitRoot2() {
|
|
|
65705
66128
|
}
|
|
65706
66129
|
}
|
|
65707
66130
|
function profilesDir() {
|
|
65708
|
-
return
|
|
66131
|
+
return join8(homeDir(), ".hasna", "mementos", "profiles");
|
|
65709
66132
|
}
|
|
65710
66133
|
function globalConfigPath() {
|
|
65711
|
-
return
|
|
66134
|
+
return join8(homeDir(), ".hasna", "mementos", "config.json");
|
|
65712
66135
|
}
|
|
65713
66136
|
function readGlobalConfig() {
|
|
65714
66137
|
const p = globalConfigPath();
|
|
65715
|
-
if (!
|
|
66138
|
+
if (!existsSync5(p))
|
|
65716
66139
|
return {};
|
|
65717
66140
|
try {
|
|
65718
|
-
return JSON.parse(
|
|
66141
|
+
return JSON.parse(readFileSync6(p, "utf-8"));
|
|
65719
66142
|
} catch {
|
|
65720
66143
|
return {};
|
|
65721
66144
|
}
|
|
65722
66145
|
}
|
|
65723
66146
|
function readGlobalConfigForWrite() {
|
|
65724
66147
|
const p = globalConfigPath();
|
|
65725
|
-
if (!
|
|
66148
|
+
if (!existsSync5(p))
|
|
65726
66149
|
return {};
|
|
65727
66150
|
try {
|
|
65728
|
-
const data = JSON.parse(
|
|
66151
|
+
const data = JSON.parse(readFileSync6(p, "utf-8"));
|
|
65729
66152
|
if (data === null || typeof data !== "object" || Array.isArray(data)) {
|
|
65730
66153
|
throw new Error("expected a JSON object");
|
|
65731
66154
|
}
|
|
@@ -65758,13 +66181,13 @@ function setActiveProfile(name) {
|
|
|
65758
66181
|
}
|
|
65759
66182
|
function listProfiles() {
|
|
65760
66183
|
const dir = profilesDir();
|
|
65761
|
-
if (!
|
|
66184
|
+
if (!existsSync5(dir))
|
|
65762
66185
|
return [];
|
|
65763
66186
|
return readdirSync(dir).filter((f) => f.endsWith(".db")).map((f) => basename(f, ".db")).sort();
|
|
65764
66187
|
}
|
|
65765
66188
|
function deleteProfile(name) {
|
|
65766
|
-
const dbPath =
|
|
65767
|
-
if (!
|
|
66189
|
+
const dbPath = join8(profilesDir(), `${name}.db`);
|
|
66190
|
+
if (!existsSync5(dbPath))
|
|
65768
66191
|
return false;
|
|
65769
66192
|
unlinkSync2(dbPath);
|
|
65770
66193
|
if (getActiveProfile() === name)
|
|
@@ -65773,10 +66196,10 @@ function deleteProfile(name) {
|
|
|
65773
66196
|
}
|
|
65774
66197
|
function getDbPath2() {
|
|
65775
66198
|
const _home = homeDir();
|
|
65776
|
-
const _newDir =
|
|
65777
|
-
const _oldDir =
|
|
65778
|
-
if (!
|
|
65779
|
-
mkdirSync3(
|
|
66199
|
+
const _newDir = join8(_home, ".hasna", "mementos");
|
|
66200
|
+
const _oldDir = join8(_home, ".mementos");
|
|
66201
|
+
if (!existsSync5(_newDir) && existsSync5(_oldDir)) {
|
|
66202
|
+
mkdirSync3(join8(_home, ".hasna"), { recursive: true });
|
|
65780
66203
|
cpSync2(_oldDir, _newDir, { recursive: true });
|
|
65781
66204
|
}
|
|
65782
66205
|
const envDbPath = process.env["HASNA_MEMENTOS_DB_PATH"] ?? process.env["MEMENTOS_DB_PATH"];
|
|
@@ -65790,7 +66213,7 @@ function getDbPath2() {
|
|
|
65790
66213
|
}
|
|
65791
66214
|
const profile = getActiveProfile();
|
|
65792
66215
|
if (profile) {
|
|
65793
|
-
const profilePath =
|
|
66216
|
+
const profilePath = join8(profilesDir(), `${profile}.db`);
|
|
65794
66217
|
ensureDir2(dirname4(profilePath));
|
|
65795
66218
|
return profilePath;
|
|
65796
66219
|
}
|
|
@@ -65798,21 +66221,21 @@ function getDbPath2() {
|
|
|
65798
66221
|
if (dbScope === "project") {
|
|
65799
66222
|
const gitRoot = findGitRoot2();
|
|
65800
66223
|
if (gitRoot) {
|
|
65801
|
-
const dbPath =
|
|
66224
|
+
const dbPath = join8(gitRoot, ".mementos", "mementos.db");
|
|
65802
66225
|
ensureDir2(dirname4(dbPath));
|
|
65803
66226
|
return dbPath;
|
|
65804
66227
|
}
|
|
65805
66228
|
}
|
|
65806
|
-
const found = findFileWalkingUp(
|
|
66229
|
+
const found = findFileWalkingUp(join8(".mementos", "mementos.db"));
|
|
65807
66230
|
if (found) {
|
|
65808
66231
|
return found;
|
|
65809
66232
|
}
|
|
65810
|
-
const fallback =
|
|
66233
|
+
const fallback = join8(homeDir(), ".hasna", "mementos", "mementos.db");
|
|
65811
66234
|
ensureDir2(dirname4(fallback));
|
|
65812
66235
|
return fallback;
|
|
65813
66236
|
}
|
|
65814
66237
|
function ensureDir2(dir) {
|
|
65815
|
-
if (!
|
|
66238
|
+
if (!existsSync5(dir)) {
|
|
65816
66239
|
mkdirSync3(dir, { recursive: true });
|
|
65817
66240
|
}
|
|
65818
66241
|
}
|
|
@@ -65930,7 +66353,7 @@ init_database();
|
|
|
65930
66353
|
init_helpers();
|
|
65931
66354
|
import chalk20 from "chalk";
|
|
65932
66355
|
import { resolve as resolve14, dirname as dirname5 } from "path";
|
|
65933
|
-
import { existsSync as
|
|
66356
|
+
import { existsSync as existsSync6, statSync, copyFileSync, mkdirSync as mkdirSync4, readdirSync as readdirSync2 } from "fs";
|
|
65934
66357
|
function registerBackupCommand(program2) {
|
|
65935
66358
|
const handleError = makeHandleError(program2);
|
|
65936
66359
|
program2.command("backup [path]").description("Backup the SQLite database to a file").option("--list", "List available backups in ~/.hasna/mementos/backups/").action((targetPath, opts) => {
|
|
@@ -65939,7 +66362,7 @@ function registerBackupCommand(program2) {
|
|
|
65939
66362
|
const home = process.env["HOME"] || process.env["USERPROFILE"] || "~";
|
|
65940
66363
|
const backupsDir = resolve14(home, ".hasna", "mementos", "backups");
|
|
65941
66364
|
if (opts.list) {
|
|
65942
|
-
if (!
|
|
66365
|
+
if (!existsSync6(backupsDir)) {
|
|
65943
66366
|
if (globalOpts.json) {
|
|
65944
66367
|
outputJson({ backups: [] });
|
|
65945
66368
|
return;
|
|
@@ -65981,7 +66404,7 @@ function registerBackupCommand(program2) {
|
|
|
65981
66404
|
return;
|
|
65982
66405
|
}
|
|
65983
66406
|
const dbPath = getDbPath();
|
|
65984
|
-
if (!
|
|
66407
|
+
if (!existsSync6(dbPath)) {
|
|
65985
66408
|
console.error(chalk20.red(`Database not found at ${dbPath}`));
|
|
65986
66409
|
process.exit(1);
|
|
65987
66410
|
}
|
|
@@ -65989,7 +66412,7 @@ function registerBackupCommand(program2) {
|
|
|
65989
66412
|
if (targetPath) {
|
|
65990
66413
|
dest = resolve14(targetPath);
|
|
65991
66414
|
} else {
|
|
65992
|
-
if (!
|
|
66415
|
+
if (!existsSync6(backupsDir)) {
|
|
65993
66416
|
mkdirSync4(backupsDir, { recursive: true });
|
|
65994
66417
|
}
|
|
65995
66418
|
const now3 = new Date;
|
|
@@ -65997,7 +66420,7 @@ function registerBackupCommand(program2) {
|
|
|
65997
66420
|
dest = resolve14(backupsDir, `mementos-${ts}.db`);
|
|
65998
66421
|
}
|
|
65999
66422
|
const destDir = dirname5(dest);
|
|
66000
|
-
if (!
|
|
66423
|
+
if (!existsSync6(destDir)) {
|
|
66001
66424
|
mkdirSync4(destDir, { recursive: true });
|
|
66002
66425
|
}
|
|
66003
66426
|
copyFileSync(dbPath, dest);
|
|
@@ -66018,29 +66441,31 @@ function registerBackupCommand(program2) {
|
|
|
66018
66441
|
// src/cli/commands/io-restore.ts
|
|
66019
66442
|
init_database();
|
|
66020
66443
|
init_api_mode();
|
|
66444
|
+
init_memories();
|
|
66021
66445
|
init_helpers();
|
|
66022
66446
|
import chalk21 from "chalk";
|
|
66023
66447
|
import { resolve as resolve15 } from "path";
|
|
66024
|
-
import { existsSync as
|
|
66448
|
+
import { existsSync as existsSync7, statSync as statSync2, copyFileSync as copyFileSync2, readdirSync as readdirSync3 } from "fs";
|
|
66449
|
+
function readMemoriesFromBackup(source) {
|
|
66450
|
+
const { Database: Database3 } = __require("bun:sqlite");
|
|
66451
|
+
const backupDb = new Database3(source, { readonly: true });
|
|
66452
|
+
try {
|
|
66453
|
+
const rows = backupDb.query("SELECT * FROM memories").all();
|
|
66454
|
+
return { rows, count: rows.length };
|
|
66455
|
+
} finally {
|
|
66456
|
+
backupDb.close();
|
|
66457
|
+
}
|
|
66458
|
+
}
|
|
66025
66459
|
function registerRestoreCommand(program2) {
|
|
66026
66460
|
const handleError = makeHandleError(program2);
|
|
66027
66461
|
program2.command("restore [file]").description("Restore the database from a backup file").option("--latest", "Restore the most recent backup from ~/.hasna/mementos/backups/").option("--force", "Skip confirmation and perform the restore").action((filePath, opts) => {
|
|
66028
66462
|
try {
|
|
66029
66463
|
const globalOpts = program2.opts();
|
|
66030
|
-
if (isApiMode()) {
|
|
66031
|
-
const msg = "restore operates on the local SQLite database and is not available in API mode (the self-hosted cloud store is authoritative). Unset HASNA_MEMENTOS_API_URL / HASNA_MEMENTOS_API_KEY to restore a local db.";
|
|
66032
|
-
if (globalOpts.json) {
|
|
66033
|
-
outputJson({ error: msg });
|
|
66034
|
-
} else {
|
|
66035
|
-
console.error(chalk21.red(msg));
|
|
66036
|
-
}
|
|
66037
|
-
process.exit(1);
|
|
66038
|
-
}
|
|
66039
66464
|
const home = process.env["HOME"] || process.env["USERPROFILE"] || "~";
|
|
66040
66465
|
const backupsDir = resolve15(home, ".hasna", "mementos", "backups");
|
|
66041
66466
|
let source;
|
|
66042
66467
|
if (opts.latest) {
|
|
66043
|
-
if (!
|
|
66468
|
+
if (!existsSync7(backupsDir)) {
|
|
66044
66469
|
console.error(chalk21.red("No backups directory found."));
|
|
66045
66470
|
process.exit(1);
|
|
66046
66471
|
}
|
|
@@ -66060,16 +66485,82 @@ function registerRestoreCommand(program2) {
|
|
|
66060
66485
|
console.error(chalk21.red("Provide a backup file path or use --latest"));
|
|
66061
66486
|
process.exit(1);
|
|
66062
66487
|
}
|
|
66063
|
-
if (!
|
|
66488
|
+
if (!existsSync7(source)) {
|
|
66064
66489
|
console.error(chalk21.red(`Backup file not found: ${source}`));
|
|
66065
66490
|
process.exit(1);
|
|
66066
66491
|
}
|
|
66067
|
-
const dbPath = getDbPath();
|
|
66068
66492
|
const backupStat = statSync2(source);
|
|
66069
66493
|
const backupSizeMB = (backupStat.size / (1024 * 1024)).toFixed(1);
|
|
66070
66494
|
const backupSizeStr = backupStat.size >= 1024 * 1024 ? `${backupSizeMB} MB` : `${(backupStat.size / 1024).toFixed(1)} KB`;
|
|
66495
|
+
if (isApiMode()) {
|
|
66496
|
+
const { rows, count } = readMemoriesFromBackup(source);
|
|
66497
|
+
if (!opts.force) {
|
|
66498
|
+
if (globalOpts.json) {
|
|
66499
|
+
outputJson({
|
|
66500
|
+
action: "restore",
|
|
66501
|
+
source,
|
|
66502
|
+
target: "cloud-api",
|
|
66503
|
+
backup_size: backupStat.size,
|
|
66504
|
+
backup_memories: count,
|
|
66505
|
+
status: "dry_run",
|
|
66506
|
+
message: "Restores the backup's memories into the hosted store; existing store rows are never overwritten. Use --force to confirm."
|
|
66507
|
+
});
|
|
66508
|
+
return;
|
|
66509
|
+
}
|
|
66510
|
+
console.log(chalk21.bold("Restore preview (hosted store):"));
|
|
66511
|
+
console.log(` Source: ${chalk21.cyan(source)} (${backupSizeStr})`);
|
|
66512
|
+
console.log(` Backup memories: ${chalk21.green(String(count))}`);
|
|
66513
|
+
console.log(` Target: hosted store (cloud-api)`);
|
|
66514
|
+
console.log(` Semantics: merges the backup's memories; existing rows are never overwritten`);
|
|
66515
|
+
console.log();
|
|
66516
|
+
console.log(chalk21.yellow("Use --force to confirm restore"));
|
|
66517
|
+
return;
|
|
66518
|
+
}
|
|
66519
|
+
const result = bulkUpsertMemories(rows);
|
|
66520
|
+
if (result.rejected > 0) {
|
|
66521
|
+
const msg = `${result.rejected} of ${result.total} memories were rejected and did not persist. See errors.`;
|
|
66522
|
+
if (globalOpts.json) {
|
|
66523
|
+
outputJson({
|
|
66524
|
+
action: "restore",
|
|
66525
|
+
status: "failed",
|
|
66526
|
+
source,
|
|
66527
|
+
target: "cloud-api",
|
|
66528
|
+
inserted: result.inserted,
|
|
66529
|
+
skipped: result.skipped,
|
|
66530
|
+
rejected: result.rejected,
|
|
66531
|
+
total: result.total,
|
|
66532
|
+
error: msg
|
|
66533
|
+
});
|
|
66534
|
+
} else {
|
|
66535
|
+
console.error(chalk21.red(msg));
|
|
66536
|
+
}
|
|
66537
|
+
process.exit(1);
|
|
66538
|
+
}
|
|
66539
|
+
if (globalOpts.json) {
|
|
66540
|
+
outputJson({
|
|
66541
|
+
action: "restore",
|
|
66542
|
+
source,
|
|
66543
|
+
target: "cloud-api",
|
|
66544
|
+
backup_size: backupStat.size,
|
|
66545
|
+
backup_memories: count,
|
|
66546
|
+
restored_memories: result.inserted,
|
|
66547
|
+
inserted: result.inserted,
|
|
66548
|
+
skipped: result.skipped,
|
|
66549
|
+
rejected: result.rejected,
|
|
66550
|
+
total: result.total,
|
|
66551
|
+
status: "completed"
|
|
66552
|
+
});
|
|
66553
|
+
return;
|
|
66554
|
+
}
|
|
66555
|
+
console.log(`Restored from: ${chalk21.green(source)}`);
|
|
66556
|
+
console.log(` Restored memories: ${chalk21.green(String(result.inserted))} (inserted)`);
|
|
66557
|
+
console.log(` Skipped (already present): ${chalk21.yellow(String(result.skipped))}`);
|
|
66558
|
+
console.log(` Rejected: ${chalk21.yellow(String(result.rejected))}`);
|
|
66559
|
+
return;
|
|
66560
|
+
}
|
|
66561
|
+
const dbPath = getDbPath();
|
|
66071
66562
|
let currentCount = 0;
|
|
66072
|
-
if (
|
|
66563
|
+
if (existsSync7(dbPath)) {
|
|
66073
66564
|
try {
|
|
66074
66565
|
const db = getDatabase();
|
|
66075
66566
|
const row = db.query("SELECT COUNT(*) as count FROM memories").get();
|
|
@@ -67323,11 +67814,11 @@ init_memories();
|
|
|
67323
67814
|
init_agents();
|
|
67324
67815
|
init_projects();
|
|
67325
67816
|
import chalk27 from "chalk";
|
|
67326
|
-
import { join as
|
|
67327
|
-
import { homedir as
|
|
67817
|
+
import { join as join9 } from "path";
|
|
67818
|
+
import { homedir as homedir5 } from "os";
|
|
67328
67819
|
import {
|
|
67329
|
-
readFileSync as
|
|
67330
|
-
existsSync as
|
|
67820
|
+
readFileSync as readFileSync7,
|
|
67821
|
+
existsSync as existsSync8,
|
|
67331
67822
|
accessSync,
|
|
67332
67823
|
statSync as statSync3,
|
|
67333
67824
|
constants as fsConstants
|
|
@@ -67362,7 +67853,7 @@ function registerDoctorCommand(program2) {
|
|
|
67362
67853
|
checks.push({ name: "Version", status: "ok", detail: version });
|
|
67363
67854
|
const dbPath = getDbPath();
|
|
67364
67855
|
let db = null;
|
|
67365
|
-
if (dbPath !== ":memory:" &&
|
|
67856
|
+
if (dbPath !== ":memory:" && existsSync8(dbPath)) {
|
|
67366
67857
|
try {
|
|
67367
67858
|
accessSync(dbPath, fsConstants.R_OK | fsConstants.W_OK);
|
|
67368
67859
|
checks.push({ name: "Database file", status: "ok", detail: dbPath });
|
|
@@ -67381,7 +67872,7 @@ function registerDoctorCommand(program2) {
|
|
|
67381
67872
|
checks.push({ name: "Database connection", status: "fail", detail: e instanceof Error ? e.message : String(e) });
|
|
67382
67873
|
}
|
|
67383
67874
|
try {
|
|
67384
|
-
if (dbPath !== ":memory:" &&
|
|
67875
|
+
if (dbPath !== ":memory:" && existsSync8(dbPath)) {
|
|
67385
67876
|
const stats = statSync3(dbPath);
|
|
67386
67877
|
const sizeKb = (stats.size / 1024).toFixed(1);
|
|
67387
67878
|
const sizeMb = (stats.size / (1024 * 1024)).toFixed(2);
|
|
@@ -67514,9 +68005,9 @@ function registerDoctorCommand(program2) {
|
|
|
67514
68005
|
checks.push({ name: "MCP server", status: "warn", detail: "could not check (is claude CLI installed?)" });
|
|
67515
68006
|
}
|
|
67516
68007
|
try {
|
|
67517
|
-
const settingsFilePath =
|
|
67518
|
-
if (
|
|
67519
|
-
const settings = JSON.parse(
|
|
68008
|
+
const settingsFilePath = join9(homedir5(), ".claude", "settings.json");
|
|
68009
|
+
if (existsSync8(settingsFilePath)) {
|
|
68010
|
+
const settings = JSON.parse(readFileSync7(settingsFilePath, "utf-8"));
|
|
67520
68011
|
const hooksObj = settings["hooks"] || {};
|
|
67521
68012
|
const stopHooks = hooksObj["Stop"] || [];
|
|
67522
68013
|
const hasMementos = stopHooks.some((e) => e.hooks?.some((h) => h.command && h.command.includes("mementos")));
|
|
@@ -67532,11 +68023,11 @@ function registerDoctorCommand(program2) {
|
|
|
67532
68023
|
checks.push({ name: "Stop hook", status: "warn", detail: "could not check stop hook" });
|
|
67533
68024
|
}
|
|
67534
68025
|
if (process.platform === "darwin") {
|
|
67535
|
-
const plistFilePath =
|
|
68026
|
+
const plistFilePath = join9(homedir5(), "Library", "LaunchAgents", "com.hasna.mementos.plist");
|
|
67536
68027
|
checks.push({
|
|
67537
68028
|
name: "Auto-start",
|
|
67538
|
-
status:
|
|
67539
|
-
detail:
|
|
68029
|
+
status: existsSync8(plistFilePath) ? "ok" : "warn",
|
|
68030
|
+
detail: existsSync8(plistFilePath) ? "configured (starts on login)" : "not configured \u2192 run: mementos init"
|
|
67540
68031
|
});
|
|
67541
68032
|
} else {
|
|
67542
68033
|
checks.push({ name: "Auto-start", status: "ok", detail: `n/a on ${process.platform}` });
|
|
@@ -67615,9 +68106,9 @@ async function runCloudDoctor(globalOpts, checks) {
|
|
|
67615
68106
|
checks.push({ name: "MCP server", status: "warn", detail: "could not check (is claude CLI installed?)" });
|
|
67616
68107
|
}
|
|
67617
68108
|
try {
|
|
67618
|
-
const settingsFilePath =
|
|
67619
|
-
if (
|
|
67620
|
-
const settings = JSON.parse(
|
|
68109
|
+
const settingsFilePath = join9(homedir5(), ".claude", "settings.json");
|
|
68110
|
+
if (existsSync8(settingsFilePath)) {
|
|
68111
|
+
const settings = JSON.parse(readFileSync7(settingsFilePath, "utf-8"));
|
|
67621
68112
|
const hooksObj = settings["hooks"] || {};
|
|
67622
68113
|
const stopHooks = hooksObj["Stop"] || [];
|
|
67623
68114
|
const hasMementos = stopHooks.some((e) => e.hooks?.some((h) => h.command && h.command.includes("mementos")));
|
|
@@ -67633,11 +68124,11 @@ async function runCloudDoctor(globalOpts, checks) {
|
|
|
67633
68124
|
checks.push({ name: "Stop hook", status: "warn", detail: "could not check stop hook" });
|
|
67634
68125
|
}
|
|
67635
68126
|
if (process.platform === "darwin") {
|
|
67636
|
-
const plistFilePath =
|
|
68127
|
+
const plistFilePath = join9(homedir5(), "Library", "LaunchAgents", "com.hasna.mementos.plist");
|
|
67637
68128
|
checks.push({
|
|
67638
68129
|
name: "Auto-start",
|
|
67639
|
-
status:
|
|
67640
|
-
detail:
|
|
68130
|
+
status: existsSync8(plistFilePath) ? "ok" : "warn",
|
|
68131
|
+
detail: existsSync8(plistFilePath) ? "configured (starts on login)" : "not configured \u2192 run: mementos init"
|
|
67641
68132
|
});
|
|
67642
68133
|
} else {
|
|
67643
68134
|
checks.push({ name: "Auto-start", status: "ok", detail: `n/a on ${process.platform}` });
|
|
@@ -69163,6 +69654,7 @@ function syncMemoriesTable(source, target, local, direction, currentMachineId) {
|
|
|
69163
69654
|
const countResult = source.get(`SELECT COUNT(*) as cnt FROM "${MEMORY_TABLE}"`);
|
|
69164
69655
|
stat.total_rows = countResult?.cnt ?? 0;
|
|
69165
69656
|
const rows = since ? source.all(`SELECT * FROM "${MEMORY_TABLE}" WHERE updated_at > ?`, since) : source.all(`SELECT * FROM "${MEMORY_TABLE}"`);
|
|
69657
|
+
const erroredRowIds = new Set;
|
|
69166
69658
|
for (const row of rows) {
|
|
69167
69659
|
try {
|
|
69168
69660
|
const sourceMachine = sourceMachineRef(row, currentMachineId);
|
|
@@ -69221,18 +69713,34 @@ function syncMemoriesTable(source, target, local, direction, currentMachineId) {
|
|
|
69221
69713
|
clearMemoryEmbedding(winnerDb, String(winner["id"]));
|
|
69222
69714
|
stat.synced_rows++;
|
|
69223
69715
|
} catch (error) {
|
|
69716
|
+
erroredRowIds.add(String(row["id"] ?? "unknown"));
|
|
69224
69717
|
stat.errors.push(`Memory ${String(row["id"] ?? "unknown")}: ${error instanceof Error ? error.message : String(error)}`);
|
|
69225
69718
|
}
|
|
69226
69719
|
}
|
|
69227
69720
|
if (rows.length === 0) {
|
|
69228
69721
|
stat.skipped_rows = stat.total_rows;
|
|
69229
69722
|
}
|
|
69230
|
-
|
|
69231
|
-
|
|
69232
|
-
|
|
69233
|
-
|
|
69234
|
-
|
|
69235
|
-
|
|
69723
|
+
if (rows.length > 0 && stat.errors.length === 0) {
|
|
69724
|
+
let maxSyncedAt = null;
|
|
69725
|
+
for (const row of rows) {
|
|
69726
|
+
if (erroredRowIds.has(String(row["id"] ?? "unknown"))) {
|
|
69727
|
+
continue;
|
|
69728
|
+
}
|
|
69729
|
+
const value = row["updated_at"];
|
|
69730
|
+
if (typeof value === "string" && (maxSyncedAt === null || value > maxSyncedAt)) {
|
|
69731
|
+
maxSyncedAt = value;
|
|
69732
|
+
}
|
|
69733
|
+
}
|
|
69734
|
+
const nextCursor = maxSyncedAt ?? syncMeta?.last_synced_at ?? null;
|
|
69735
|
+
if (nextCursor !== null) {
|
|
69736
|
+
upsertMemorySyncMeta(local, {
|
|
69737
|
+
table_name: MEMORY_TABLE,
|
|
69738
|
+
direction,
|
|
69739
|
+
last_synced_at: nextCursor,
|
|
69740
|
+
last_synced_row_count: stat.synced_rows
|
|
69741
|
+
});
|
|
69742
|
+
}
|
|
69743
|
+
}
|
|
69236
69744
|
} catch (error) {
|
|
69237
69745
|
stat.errors.push(error instanceof Error ? error.message : String(error));
|
|
69238
69746
|
}
|
|
@@ -69622,19 +70130,19 @@ function registerStorageCommands(program2) {
|
|
|
69622
70130
|
// src/cli/commands/init.ts
|
|
69623
70131
|
import chalk41 from "chalk";
|
|
69624
70132
|
import {
|
|
69625
|
-
readFileSync as
|
|
70133
|
+
readFileSync as readFileSync8,
|
|
69626
70134
|
writeFileSync as writeFileSync4,
|
|
69627
|
-
existsSync as
|
|
70135
|
+
existsSync as existsSync10,
|
|
69628
70136
|
copyFileSync as copyFileSync3,
|
|
69629
70137
|
mkdirSync as mkdirSync6
|
|
69630
70138
|
} from "fs";
|
|
69631
|
-
import { dirname as dirname7, join as
|
|
69632
|
-
import { homedir as
|
|
70139
|
+
import { dirname as dirname7, join as join11 } from "path";
|
|
70140
|
+
import { homedir as homedir6 } from "os";
|
|
69633
70141
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
69634
70142
|
function registerInitCommand(program2) {
|
|
69635
70143
|
program2.command("init").description("One-command setup: register MCP, install stop hook, configure auto-start").action(async () => {
|
|
69636
70144
|
const { platform: platform2 } = process;
|
|
69637
|
-
const home =
|
|
70145
|
+
const home = homedir6();
|
|
69638
70146
|
const isMac = platform2 === "darwin";
|
|
69639
70147
|
console.log("");
|
|
69640
70148
|
console.log(chalk41.bold(" mementos \u2014 setting up your memory layer"));
|
|
@@ -69689,17 +70197,17 @@ function registerInitCommand(program2) {
|
|
|
69689
70197
|
} else {
|
|
69690
70198
|
console.log(chalk41.green(" \u2713 MCP server registered with Claude Code"));
|
|
69691
70199
|
}
|
|
69692
|
-
const hooksDir =
|
|
69693
|
-
const hookDest =
|
|
69694
|
-
const settingsPath =
|
|
70200
|
+
const hooksDir = join11(home, ".claude", "hooks");
|
|
70201
|
+
const hookDest = join11(hooksDir, "mementos-stop-hook.ts");
|
|
70202
|
+
const settingsPath = join11(home, ".claude", "settings.json");
|
|
69695
70203
|
const hookCommand = `bun ${hookDest}`;
|
|
69696
70204
|
let hookAlreadyInstalled = false;
|
|
69697
70205
|
let hookError = null;
|
|
69698
70206
|
try {
|
|
69699
70207
|
let settings = {};
|
|
69700
|
-
if (
|
|
70208
|
+
if (existsSync10(settingsPath)) {
|
|
69701
70209
|
try {
|
|
69702
|
-
settings = JSON.parse(
|
|
70210
|
+
settings = JSON.parse(readFileSync8(settingsPath, "utf-8"));
|
|
69703
70211
|
} catch {
|
|
69704
70212
|
settings = {};
|
|
69705
70213
|
}
|
|
@@ -69710,19 +70218,19 @@ function registerInitCommand(program2) {
|
|
|
69710
70218
|
if (alreadyHasMementos) {
|
|
69711
70219
|
hookAlreadyInstalled = true;
|
|
69712
70220
|
} else {
|
|
69713
|
-
if (!
|
|
70221
|
+
if (!existsSync10(hooksDir)) {
|
|
69714
70222
|
mkdirSync6(hooksDir, { recursive: true });
|
|
69715
70223
|
}
|
|
69716
|
-
if (!
|
|
70224
|
+
if (!existsSync10(hookDest)) {
|
|
69717
70225
|
const packageDir = dirname7(dirname7(fileURLToPath4(import.meta.url)));
|
|
69718
70226
|
const candidatePaths = [
|
|
69719
|
-
|
|
69720
|
-
|
|
69721
|
-
|
|
70227
|
+
join11(packageDir, "scripts", "hooks", "claude-stop-hook.ts"),
|
|
70228
|
+
join11(packageDir, "..", "scripts", "hooks", "claude-stop-hook.ts"),
|
|
70229
|
+
join11(home, ".bun", "install", "global", "node_modules", "@hasna", "mementos", "scripts", "hooks", "claude-stop-hook.ts")
|
|
69722
70230
|
];
|
|
69723
70231
|
let hookSourceFound = false;
|
|
69724
70232
|
for (const src of candidatePaths) {
|
|
69725
|
-
if (
|
|
70233
|
+
if (existsSync10(src)) {
|
|
69726
70234
|
copyFileSync3(src, hookDest);
|
|
69727
70235
|
hookSourceFound = true;
|
|
69728
70236
|
break;
|
|
@@ -69788,7 +70296,7 @@ main().catch(() => {});
|
|
|
69788
70296
|
if (!isMac) {
|
|
69789
70297
|
console.log(chalk41.dim(` \xB7 Auto-start skipped (not macOS \u2014 platform: ${platform2})`));
|
|
69790
70298
|
} else {
|
|
69791
|
-
const plistPath =
|
|
70299
|
+
const plistPath = join11(home, "Library", "LaunchAgents", "com.hasna.mementos.plist");
|
|
69792
70300
|
const plistContent = `<?xml version="1.0" encoding="UTF-8"?>
|
|
69793
70301
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
69794
70302
|
<plist version="1.0">
|
|
@@ -69813,11 +70321,11 @@ main().catch(() => {});
|
|
|
69813
70321
|
</plist>
|
|
69814
70322
|
`;
|
|
69815
70323
|
try {
|
|
69816
|
-
if (
|
|
70324
|
+
if (existsSync10(plistPath)) {
|
|
69817
70325
|
autoStartAlreadyInstalled = true;
|
|
69818
70326
|
} else {
|
|
69819
|
-
const launchAgentsDir =
|
|
69820
|
-
if (!
|
|
70327
|
+
const launchAgentsDir = join11(home, "Library", "LaunchAgents");
|
|
70328
|
+
if (!existsSync10(launchAgentsDir)) {
|
|
69821
70329
|
mkdirSync6(launchAgentsDir, { recursive: true });
|
|
69822
70330
|
}
|
|
69823
70331
|
writeFileSync4(plistPath, plistContent, "utf-8");
|
|
@@ -69833,7 +70341,7 @@ main().catch(() => {});
|
|
|
69833
70341
|
console.log(chalk41.green(" \u2713 Auto-start configured (starts on login)"));
|
|
69834
70342
|
}
|
|
69835
70343
|
if (!autoStartAlreadyInstalled && !autoStartError) {
|
|
69836
|
-
const plistPath2 =
|
|
70344
|
+
const plistPath2 = join11(home, "Library", "LaunchAgents", "com.hasna.mementos.plist");
|
|
69837
70345
|
const loadResult = await run(["launchctl", "load", plistPath2]);
|
|
69838
70346
|
if (!loadResult.ok) {
|
|
69839
70347
|
console.log(chalk41.dim(` \xB7 launchctl load: ${loadResult.output || "already loaded"}`));
|
|
@@ -70947,13 +71455,13 @@ function lessonTagForCli(kind) {
|
|
|
70947
71455
|
|
|
70948
71456
|
// src/cli/brains.ts
|
|
70949
71457
|
import {
|
|
70950
|
-
existsSync as
|
|
71458
|
+
existsSync as existsSync12,
|
|
70951
71459
|
mkdirSync as mkdirSync8,
|
|
70952
71460
|
writeFileSync as writeFileSync6,
|
|
70953
71461
|
readdirSync as readdirSync4
|
|
70954
71462
|
} from "fs";
|
|
70955
|
-
import { homedir as
|
|
70956
|
-
import { join as
|
|
71463
|
+
import { homedir as homedir8 } from "os";
|
|
71464
|
+
import { join as join13 } from "path";
|
|
70957
71465
|
import chalk43 from "chalk";
|
|
70958
71466
|
|
|
70959
71467
|
// src/lib/gatherer.ts
|
|
@@ -71008,7 +71516,7 @@ ${matched.map((m) => `- ${m.key}: ${m.value.slice(0, 120)}${m.value.length > 120
|
|
|
71008
71516
|
};
|
|
71009
71517
|
}
|
|
71010
71518
|
var gatherTrainingData = async (options = {}) => {
|
|
71011
|
-
const allMemories =
|
|
71519
|
+
const allMemories = listMemoriesBounded({ status: "active" }, undefined).rows;
|
|
71012
71520
|
const filtered = options.since ? allMemories.filter((m) => new Date(m.created_at) >= options.since) : allMemories;
|
|
71013
71521
|
const sorted = filtered.slice().sort((a, b) => b.importance - a.importance);
|
|
71014
71522
|
const fetchSet = options.limit ? sorted.slice(0, options.limit * 3) : sorted;
|
|
@@ -71030,24 +71538,24 @@ var gatherTrainingData = async (options = {}) => {
|
|
|
71030
71538
|
};
|
|
71031
71539
|
|
|
71032
71540
|
// src/lib/model-config.ts
|
|
71033
|
-
import { existsSync as
|
|
71034
|
-
import { homedir as
|
|
71035
|
-
import { join as
|
|
71541
|
+
import { existsSync as existsSync11, mkdirSync as mkdirSync7, readFileSync as readFileSync9, writeFileSync as writeFileSync5 } from "fs";
|
|
71542
|
+
import { homedir as homedir7 } from "os";
|
|
71543
|
+
import { join as join12 } from "path";
|
|
71036
71544
|
var DEFAULT_MODEL = "gpt-4o-mini";
|
|
71037
|
-
var CONFIG_DIR =
|
|
71038
|
-
var CONFIG_PATH =
|
|
71545
|
+
var CONFIG_DIR = join12(homedir7(), ".hasna", "mementos");
|
|
71546
|
+
var CONFIG_PATH = join12(CONFIG_DIR, "config.json");
|
|
71039
71547
|
function readConfig() {
|
|
71040
|
-
if (!
|
|
71548
|
+
if (!existsSync11(CONFIG_PATH))
|
|
71041
71549
|
return {};
|
|
71042
71550
|
try {
|
|
71043
|
-
const raw =
|
|
71551
|
+
const raw = readFileSync9(CONFIG_PATH, "utf-8");
|
|
71044
71552
|
return JSON.parse(raw);
|
|
71045
71553
|
} catch {
|
|
71046
71554
|
return {};
|
|
71047
71555
|
}
|
|
71048
71556
|
}
|
|
71049
71557
|
function writeConfig(config2) {
|
|
71050
|
-
if (!
|
|
71558
|
+
if (!existsSync11(CONFIG_DIR)) {
|
|
71051
71559
|
mkdirSync7(CONFIG_DIR, { recursive: true });
|
|
71052
71560
|
}
|
|
71053
71561
|
writeFileSync5(CONFIG_PATH, JSON.stringify(config2, null, 2) + `
|
|
@@ -71095,12 +71603,12 @@ function makeBrainsCommand() {
|
|
|
71095
71603
|
limit: opts.limit,
|
|
71096
71604
|
since
|
|
71097
71605
|
});
|
|
71098
|
-
const outputDir = opts.output ??
|
|
71099
|
-
if (!
|
|
71606
|
+
const outputDir = opts.output ?? join13(homedir8(), ".hasna", "mementos", "training");
|
|
71607
|
+
if (!existsSync12(outputDir)) {
|
|
71100
71608
|
mkdirSync8(outputDir, { recursive: true });
|
|
71101
71609
|
}
|
|
71102
71610
|
const timestamp2 = new Date().toISOString().replace(/[:.]/g, "-").slice(0, 19);
|
|
71103
|
-
const outputPath =
|
|
71611
|
+
const outputPath = join13(outputDir, `mementos-training-${timestamp2}.jsonl`);
|
|
71104
71612
|
const jsonl = result.examples.map((ex) => JSON.stringify(ex)).join(`
|
|
71105
71613
|
`);
|
|
71106
71614
|
writeFileSync6(outputPath, jsonl + `
|
|
@@ -71124,8 +71632,8 @@ function makeBrainsCommand() {
|
|
|
71124
71632
|
try {
|
|
71125
71633
|
let datasetPath = opts.dataset;
|
|
71126
71634
|
if (!datasetPath) {
|
|
71127
|
-
const trainingDir =
|
|
71128
|
-
if (!
|
|
71635
|
+
const trainingDir = join13(homedir8(), ".hasna", "mementos", "training");
|
|
71636
|
+
if (!existsSync12(trainingDir)) {
|
|
71129
71637
|
printError("No training data found. Run `mementos brains gather` first.");
|
|
71130
71638
|
process.exit(1);
|
|
71131
71639
|
}
|
|
@@ -71135,9 +71643,9 @@ function makeBrainsCommand() {
|
|
|
71135
71643
|
printError("No JSONL training files found. Run `mementos brains gather` first.");
|
|
71136
71644
|
process.exit(1);
|
|
71137
71645
|
}
|
|
71138
|
-
datasetPath =
|
|
71646
|
+
datasetPath = join13(trainingDir, latestFile);
|
|
71139
71647
|
}
|
|
71140
|
-
if (!datasetPath || !
|
|
71648
|
+
if (!datasetPath || !existsSync12(datasetPath)) {
|
|
71141
71649
|
printError(`Dataset file not found: ${datasetPath ?? "(unresolved)"}`);
|
|
71142
71650
|
process.exit(1);
|
|
71143
71651
|
}
|
|
@@ -71263,8 +71771,8 @@ function registerAllCommands(program2) {
|
|
|
71263
71771
|
// src/cli/index.tsx
|
|
71264
71772
|
function getPackageVersion2() {
|
|
71265
71773
|
try {
|
|
71266
|
-
const pkgPath =
|
|
71267
|
-
const pkg = JSON.parse(
|
|
71774
|
+
const pkgPath = join14(dirname8(fileURLToPath5(import.meta.url)), "..", "..", "package.json");
|
|
71775
|
+
const pkg = JSON.parse(readFileSync10(pkgPath, "utf-8"));
|
|
71268
71776
|
return pkg.version || "0.0.0";
|
|
71269
71777
|
} catch {
|
|
71270
71778
|
return "0.0.0";
|