@hasna/mementos 0.14.85 → 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 +419 -188
- package/dist/diagnostics/historical-project-registration-receipt.js +36 -17
- package/dist/index.js +139 -50
- package/dist/mcp/index.js +181 -60
- package/dist/pg-sync-worker.js +7 -5
- package/dist/project-registration.js +108 -36
- package/dist/sdk/index.js +1 -0
- package/dist/server/index.js +384 -280
- package/dist/storage.js +63 -26
- package/hasna.contract.json +5 -4
- package/package.json +4 -3
- 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 -150
- 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 -120
- 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 -193
- 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/diagnostics/historical-project-registration-receipt.d.ts +0 -39
- package/dist/diagnostics/historical-project-registration-receipt.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/historical-receipt.d.ts +0 -38
- package/dist/project-registration/historical-receipt.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 -319
- 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 -978
- 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/memories-page-stub-server.d.ts +0 -2
- package/dist/test-support/memories-page-stub-server.d.ts.map +0 -1
- package/dist/test-support/memories-page-stub.d.ts +0 -28
- package/dist/test-support/memories-page-stub.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
|
@@ -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)
|
|
@@ -5267,6 +5304,7 @@ __export(exports_memories, {
|
|
|
5267
5304
|
updateMemory: () => updateMemory,
|
|
5268
5305
|
touchMemory: () => touchMemory,
|
|
5269
5306
|
semanticSearch: () => semanticSearch,
|
|
5307
|
+
reservedAgentIdViolation: () => reservedAgentIdViolation,
|
|
5270
5308
|
parseMemoryRow: () => parseMemoryRow,
|
|
5271
5309
|
listMemoryHistoryPage: () => listMemoryHistoryPage,
|
|
5272
5310
|
listMemoryHistory: () => listMemoryHistory,
|
|
@@ -5338,7 +5376,20 @@ function parseMemoryRow(row) {
|
|
|
5338
5376
|
accessed_at: row["accessed_at"] || null
|
|
5339
5377
|
};
|
|
5340
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
|
+
}
|
|
5341
5388
|
function createMemory(input, dedupeMode = "merge", db) {
|
|
5389
|
+
const reservedViolation = reservedAgentIdViolation(input.agent_id);
|
|
5390
|
+
if (reservedViolation) {
|
|
5391
|
+
throw new Error(reservedViolation);
|
|
5392
|
+
}
|
|
5342
5393
|
if (!db && isApiMode()) {
|
|
5343
5394
|
const { status, data } = apiJson("POST", "/memories", { ...input, dedupe: dedupeMode });
|
|
5344
5395
|
if (!data || !data.id) {
|
|
@@ -5388,7 +5439,8 @@ function createMemory(input, dedupeMode = "merge", db) {
|
|
|
5388
5439
|
importance = ?, metadata = ?, expires_at = ?,
|
|
5389
5440
|
when_to_use = ?,
|
|
5390
5441
|
pinned = COALESCE(pinned, 0),
|
|
5391
|
-
version = version + 1, updated_at =
|
|
5442
|
+
version = version + 1, updated_at = ?,
|
|
5443
|
+
updated_by_agent = ?
|
|
5392
5444
|
WHERE id = ?`, [
|
|
5393
5445
|
safeValue,
|
|
5394
5446
|
input.category || "knowledge",
|
|
@@ -5399,6 +5451,7 @@ function createMemory(input, dedupeMode = "merge", db) {
|
|
|
5399
5451
|
expiresAt,
|
|
5400
5452
|
input.when_to_use || null,
|
|
5401
5453
|
timestamp,
|
|
5454
|
+
input.agent_id || null,
|
|
5402
5455
|
existing.id
|
|
5403
5456
|
]);
|
|
5404
5457
|
d.run("DELETE FROM memory_tags WHERE memory_id = ?", [existing.id]);
|
|
@@ -5503,6 +5556,12 @@ function bulkUpsertMemories(memories, db) {
|
|
|
5503
5556
|
errors.push(`Rejected "${key}": ${formatEnumViolation(violation)}`);
|
|
5504
5557
|
continue;
|
|
5505
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
|
+
}
|
|
5506
5565
|
const timestamp = now();
|
|
5507
5566
|
let tags = [];
|
|
5508
5567
|
const rawTags = mem["tags"];
|
|
@@ -5781,6 +5840,11 @@ function listMemoriesPage(filter, db) {
|
|
|
5781
5840
|
agent_id: f.agent_id,
|
|
5782
5841
|
project_id: f.project_id,
|
|
5783
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,
|
|
5784
5848
|
namespace: f.namespace,
|
|
5785
5849
|
as_of: f.as_of,
|
|
5786
5850
|
limit: f.limit,
|
|
@@ -6060,20 +6124,29 @@ function updateMemory(id, input, db) {
|
|
|
6060
6124
|
sets.push("when_to_use = ?");
|
|
6061
6125
|
params.push(input.when_to_use ?? null);
|
|
6062
6126
|
}
|
|
6127
|
+
if (input.updated_by_agent !== undefined) {
|
|
6128
|
+
sets.push("updated_by_agent = ?");
|
|
6129
|
+
params.push(input.updated_by_agent ?? null);
|
|
6130
|
+
}
|
|
6063
6131
|
if (input.tags !== undefined) {
|
|
6064
6132
|
sets.push("tags = ?");
|
|
6065
6133
|
params.push(JSON.stringify(input.tags));
|
|
6066
|
-
d.run("DELETE FROM memory_tags WHERE memory_id = ?", [memoryId]);
|
|
6067
|
-
const insertTag = d.prepare("INSERT OR IGNORE INTO memory_tags (memory_id, tag) VALUES (?, ?)");
|
|
6068
|
-
for (const tag of input.tags) {
|
|
6069
|
-
insertTag.run(memoryId, tag);
|
|
6070
|
-
}
|
|
6071
6134
|
}
|
|
6072
6135
|
params.push(memoryId);
|
|
6073
|
-
|
|
6074
|
-
|
|
6075
|
-
|
|
6076
|
-
|
|
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
|
+
});
|
|
6077
6150
|
const updated = getMemory(memoryId, d);
|
|
6078
6151
|
if (input.value !== undefined) {
|
|
6079
6152
|
try {
|
|
@@ -6244,7 +6317,7 @@ async function semanticSearch(queryText, options = {}, db) {
|
|
|
6244
6317
|
scored.sort((a, b) => b.score - a.score);
|
|
6245
6318
|
return scored.slice(0, limit);
|
|
6246
6319
|
}
|
|
6247
|
-
var RECALL_PROMOTE_THRESHOLD = 3;
|
|
6320
|
+
var RESERVED_AGENT_IDS, RECALL_PROMOTE_THRESHOLD = 3;
|
|
6248
6321
|
var init_memories = __esm(() => {
|
|
6249
6322
|
init_types();
|
|
6250
6323
|
init_database();
|
|
@@ -6254,9 +6327,32 @@ var init_memories = __esm(() => {
|
|
|
6254
6327
|
init_poisoning();
|
|
6255
6328
|
init_entity_memories();
|
|
6256
6329
|
init_api_mode();
|
|
6330
|
+
RESERVED_AGENT_IDS = new Set([
|
|
6331
|
+
"agent-a",
|
|
6332
|
+
"agent-x",
|
|
6333
|
+
"agent-z",
|
|
6334
|
+
"nonexistent-agent"
|
|
6335
|
+
]);
|
|
6257
6336
|
});
|
|
6258
6337
|
|
|
6259
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
|
+
}
|
|
6260
6356
|
function parseAgentRow(row) {
|
|
6261
6357
|
return {
|
|
6262
6358
|
id: row["id"],
|
|
@@ -6459,17 +6555,17 @@ var init_agents = __esm(() => {
|
|
|
6459
6555
|
});
|
|
6460
6556
|
|
|
6461
6557
|
// src/lib/package-version.ts
|
|
6462
|
-
import { readFileSync as
|
|
6463
|
-
import { dirname as dirname2, join as
|
|
6558
|
+
import { readFileSync as readFileSync3 } from "fs";
|
|
6559
|
+
import { dirname as dirname2, join as join6 } from "path";
|
|
6464
6560
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
6465
6561
|
function getMementosPackageVersion() {
|
|
6466
6562
|
const here = dirname2(fileURLToPath2(import.meta.url));
|
|
6467
6563
|
for (const candidate of [
|
|
6468
|
-
|
|
6469
|
-
|
|
6564
|
+
join6(here, "..", "..", "package.json"),
|
|
6565
|
+
join6(here, "..", "package.json")
|
|
6470
6566
|
]) {
|
|
6471
6567
|
try {
|
|
6472
|
-
const parsed = JSON.parse(
|
|
6568
|
+
const parsed = JSON.parse(readFileSync3(candidate, "utf8"));
|
|
6473
6569
|
if (typeof parsed.version === "string" && parsed.version.trim())
|
|
6474
6570
|
return parsed.version;
|
|
6475
6571
|
} catch {}
|
|
@@ -7472,13 +7568,13 @@ __export(exports_helpers, {
|
|
|
7472
7568
|
DEFAULT_COMPACT_LIMIT: () => DEFAULT_COMPACT_LIMIT
|
|
7473
7569
|
});
|
|
7474
7570
|
import chalk from "chalk";
|
|
7475
|
-
import { readFileSync as
|
|
7476
|
-
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";
|
|
7477
7573
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
7478
7574
|
function getPackageVersion() {
|
|
7479
7575
|
try {
|
|
7480
|
-
const pkgPath =
|
|
7481
|
-
const pkg = JSON.parse(
|
|
7576
|
+
const pkgPath = join7(dirname3(fileURLToPath3(import.meta.url)), "..", "..", "package.json");
|
|
7577
|
+
const pkg = JSON.parse(readFileSync4(pkgPath, "utf-8"));
|
|
7482
7578
|
return pkg.version || "0.0.0";
|
|
7483
7579
|
} catch {
|
|
7484
7580
|
return "0.0.0";
|
|
@@ -8037,16 +8133,16 @@ function validateConfigKeyValue(key, value, DEFAULT_CONFIG) {
|
|
|
8037
8133
|
return null;
|
|
8038
8134
|
}
|
|
8039
8135
|
function getConfigPath() {
|
|
8040
|
-
const { homedir:
|
|
8041
|
-
return
|
|
8136
|
+
const { homedir: homedir4 } = __require("os");
|
|
8137
|
+
return join7(homedir4(), ".hasna", "mementos", "config.json");
|
|
8042
8138
|
}
|
|
8043
8139
|
function readFileConfig() {
|
|
8044
|
-
const { existsSync:
|
|
8140
|
+
const { existsSync: existsSync5 } = __require("fs");
|
|
8045
8141
|
const configPath = getConfigPath();
|
|
8046
|
-
if (!
|
|
8142
|
+
if (!existsSync5(configPath))
|
|
8047
8143
|
return {};
|
|
8048
8144
|
try {
|
|
8049
|
-
const data = JSON.parse(
|
|
8145
|
+
const data = JSON.parse(readFileSync4(configPath, "utf-8"));
|
|
8050
8146
|
if (data === null || typeof data !== "object" || Array.isArray(data)) {
|
|
8051
8147
|
throw new Error("expected a JSON object");
|
|
8052
8148
|
}
|
|
@@ -8057,10 +8153,10 @@ function readFileConfig() {
|
|
|
8057
8153
|
}
|
|
8058
8154
|
}
|
|
8059
8155
|
function writeFileConfig(data) {
|
|
8060
|
-
const { existsSync:
|
|
8156
|
+
const { existsSync: existsSync5, writeFileSync: writeFileSync3, mkdirSync: mkdirSync3 } = __require("fs");
|
|
8061
8157
|
const configPath = getConfigPath();
|
|
8062
8158
|
const dir = dirname3(configPath);
|
|
8063
|
-
if (!
|
|
8159
|
+
if (!existsSync5(dir))
|
|
8064
8160
|
mkdirSync3(dir, { recursive: true });
|
|
8065
8161
|
writeFileSync3(configPath, JSON.stringify(data, null, 2) + `
|
|
8066
8162
|
`, "utf-8");
|
|
@@ -8488,7 +8584,7 @@ function buildFilterConditions(filter) {
|
|
|
8488
8584
|
const conditions = [];
|
|
8489
8585
|
const params = [];
|
|
8490
8586
|
conditions.push("m.status = 'active'");
|
|
8491
|
-
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'))");
|
|
8492
8588
|
if (!filter)
|
|
8493
8589
|
return { conditions, params };
|
|
8494
8590
|
if (filter.scope) {
|
|
@@ -10568,7 +10664,7 @@ async function detectContradiction(newKey, newValue, options = {}, db) {
|
|
|
10568
10664
|
conditions.push("project_id = ?");
|
|
10569
10665
|
params.push(project_id);
|
|
10570
10666
|
}
|
|
10571
|
-
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'))");
|
|
10572
10668
|
const sql = `SELECT * FROM memories WHERE ${conditions.join(" AND ")} ORDER BY importance DESC LIMIT 10`;
|
|
10573
10669
|
const rows = d.query(sql).all(...params);
|
|
10574
10670
|
if (rows.length === 0) {
|
|
@@ -11762,10 +11858,12 @@ var init_synthesis2 = __esm(() => {
|
|
|
11762
11858
|
var exports_session_jobs = {};
|
|
11763
11859
|
__export(exports_session_jobs, {
|
|
11764
11860
|
updateSessionJob: () => updateSessionJob,
|
|
11861
|
+
recoverStaleProcessingJobs: () => recoverStaleProcessingJobs,
|
|
11765
11862
|
listSessionJobs: () => listSessionJobs,
|
|
11766
11863
|
getSessionJob: () => getSessionJob,
|
|
11767
11864
|
getNextPendingJob: () => getNextPendingJob,
|
|
11768
|
-
createSessionJob: () => createSessionJob
|
|
11865
|
+
createSessionJob: () => createSessionJob,
|
|
11866
|
+
claimSessionJob: () => claimSessionJob
|
|
11769
11867
|
});
|
|
11770
11868
|
function parseJobRow(row) {
|
|
11771
11869
|
return {
|
|
@@ -11895,6 +11993,18 @@ function getNextPendingJob(db) {
|
|
|
11895
11993
|
return null;
|
|
11896
11994
|
return parseJobRow(row);
|
|
11897
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
|
+
}
|
|
11898
12008
|
var init_session_jobs = __esm(() => {
|
|
11899
12009
|
init_database();
|
|
11900
12010
|
init_api_mode();
|
|
@@ -12433,7 +12543,11 @@ async function processSessionJob(jobId, db) {
|
|
|
12433
12543
|
return result;
|
|
12434
12544
|
}
|
|
12435
12545
|
try {
|
|
12436
|
-
|
|
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
|
+
}
|
|
12437
12551
|
} catch (e) {
|
|
12438
12552
|
result.errors.push(`Failed to mark job as processing: ${String(e)}`);
|
|
12439
12553
|
return result;
|
|
@@ -12556,6 +12670,9 @@ function startSessionQueueWorker() {
|
|
|
12556
12670
|
return;
|
|
12557
12671
|
_workerStarted = true;
|
|
12558
12672
|
setInterval(() => {
|
|
12673
|
+
try {
|
|
12674
|
+
recoverStaleProcessingJobs(30 * 60 * 1000);
|
|
12675
|
+
} catch {}
|
|
12559
12676
|
_processNext();
|
|
12560
12677
|
}, 5000);
|
|
12561
12678
|
}
|
|
@@ -12609,13 +12726,13 @@ __export(exports_session_registry, {
|
|
|
12609
12726
|
closeRegistry: () => closeRegistry,
|
|
12610
12727
|
cleanStaleSessions: () => cleanStaleSessions
|
|
12611
12728
|
});
|
|
12612
|
-
import { existsSync as
|
|
12613
|
-
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";
|
|
12614
12731
|
function getDb() {
|
|
12615
12732
|
if (_db2)
|
|
12616
12733
|
return _db2;
|
|
12617
12734
|
const dir = dirname6(DB_PATH);
|
|
12618
|
-
if (!
|
|
12735
|
+
if (!existsSync9(dir))
|
|
12619
12736
|
mkdirSync5(dir, { recursive: true });
|
|
12620
12737
|
_db2 = new SqliteAdapter(DB_PATH);
|
|
12621
12738
|
_db2.run("PRAGMA journal_mode = WAL");
|
|
@@ -12790,7 +12907,7 @@ function closeRegistry() {
|
|
|
12790
12907
|
var DB_PATH, _db2 = null;
|
|
12791
12908
|
var init_session_registry = __esm(() => {
|
|
12792
12909
|
init_storage();
|
|
12793
|
-
DB_PATH =
|
|
12910
|
+
DB_PATH = join10(process.env["HOME"] || process.env["USERPROFILE"] || "~", ".open-sessions-registry.db");
|
|
12794
12911
|
});
|
|
12795
12912
|
|
|
12796
12913
|
// src/db/pg-migrations.ts
|
|
@@ -62271,8 +62388,8 @@ var {
|
|
|
62271
62388
|
|
|
62272
62389
|
// src/cli/index.tsx
|
|
62273
62390
|
init_database();
|
|
62274
|
-
import { readFileSync as
|
|
62275
|
-
import { dirname as dirname8, join as
|
|
62391
|
+
import { readFileSync as readFileSync10 } from "fs";
|
|
62392
|
+
import { dirname as dirname8, join as join14 } from "path";
|
|
62276
62393
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
62277
62394
|
|
|
62278
62395
|
// src/db/machines.ts
|
|
@@ -64271,6 +64388,18 @@ function registerCrudCommands(program2) {
|
|
|
64271
64388
|
}
|
|
64272
64389
|
resolvedAgentId = ag.id;
|
|
64273
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
|
+
}
|
|
64274
64403
|
const input = {
|
|
64275
64404
|
key,
|
|
64276
64405
|
value,
|
|
@@ -64280,7 +64409,7 @@ function registerCrudCommands(program2) {
|
|
|
64280
64409
|
tags: mergedTags,
|
|
64281
64410
|
summary: opts.summary,
|
|
64282
64411
|
ttl_ms: opts.ttl ? parseDuration(opts.ttl) : undefined,
|
|
64283
|
-
source:
|
|
64412
|
+
source: requestedSource,
|
|
64284
64413
|
agent_id: resolvedAgentId,
|
|
64285
64414
|
session_id: globalOpts.session
|
|
64286
64415
|
};
|
|
@@ -64347,6 +64476,10 @@ function registerCrudCommands(program2) {
|
|
|
64347
64476
|
const updateInput = {
|
|
64348
64477
|
version: existing.version
|
|
64349
64478
|
};
|
|
64479
|
+
const writingName = resolveWritingAgentName();
|
|
64480
|
+
if (writingName) {
|
|
64481
|
+
updateInput.updated_by_agent = getAgent(writingName)?.id ?? registerAgent(writingName).id;
|
|
64482
|
+
}
|
|
64350
64483
|
if (opts.value !== undefined)
|
|
64351
64484
|
updateInput.value = opts.value;
|
|
64352
64485
|
if (opts.importance !== undefined)
|
|
@@ -64374,7 +64507,7 @@ function registerCrudCommands(program2) {
|
|
|
64374
64507
|
if (violation)
|
|
64375
64508
|
throw new Error(formatEnumViolation(violation));
|
|
64376
64509
|
}
|
|
64377
|
-
const changedFields = Object.keys(updateInput).filter((k) => k !== "version");
|
|
64510
|
+
const changedFields = Object.keys(updateInput).filter((k) => k !== "version" && k !== "updated_by_agent");
|
|
64378
64511
|
if (changedFields.length === 0) {
|
|
64379
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.`);
|
|
64380
64513
|
}
|
|
@@ -64404,8 +64537,7 @@ function registerCrudCommands(program2) {
|
|
|
64404
64537
|
}
|
|
64405
64538
|
const matches = getMemoriesByKey(keyOrId, opts.scope, opts.agent, opts.project);
|
|
64406
64539
|
if (matches.length === 0) {
|
|
64407
|
-
|
|
64408
|
-
if (isApiMode() && looksLikeId && deleteMemory(keyOrId)) {
|
|
64540
|
+
if (isApiMode() && keyOrId.length > 0 && deleteMemory(keyOrId)) {
|
|
64409
64541
|
if (globalOpts.json) {
|
|
64410
64542
|
outputJson({ deleted: keyOrId });
|
|
64411
64543
|
} else {
|
|
@@ -64977,7 +65109,7 @@ function registerRemoveCommand(program2) {
|
|
|
64977
65109
|
if (mem)
|
|
64978
65110
|
id = mem.id;
|
|
64979
65111
|
}
|
|
64980
|
-
if (!id && isApiMode() &&
|
|
65112
|
+
if (!id && isApiMode() && nameOrId.length > 0) {
|
|
64981
65113
|
id = nameOrId;
|
|
64982
65114
|
}
|
|
64983
65115
|
if (!id) {
|
|
@@ -65210,7 +65342,10 @@ function getMemoryStats(db) {
|
|
|
65210
65342
|
const byCategory = d.query("SELECT category, COUNT(*) as c FROM memories WHERE status = 'active' GROUP BY category").all();
|
|
65211
65343
|
const byStatus = d.query("SELECT status, COUNT(*) as c FROM memories WHERE status = 'active' GROUP BY status").all();
|
|
65212
65344
|
const pinnedCount = d.query("SELECT COUNT(*) as c FROM memories WHERE pinned = 1 AND status = 'active'").get().c;
|
|
65213
|
-
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;
|
|
65214
65349
|
const stats = {
|
|
65215
65350
|
total,
|
|
65216
65351
|
by_scope: { global: 0, shared: 0, private: 0, working: 0 },
|
|
@@ -65218,7 +65353,9 @@ function getMemoryStats(db) {
|
|
|
65218
65353
|
by_status: { active: 0, archived: 0, expired: 0 },
|
|
65219
65354
|
by_agent: {},
|
|
65220
65355
|
pinned_count: pinnedCount,
|
|
65221
|
-
expired_count: expiredCount
|
|
65356
|
+
expired_count: expiredCount,
|
|
65357
|
+
expires_at_count: expiresAtCount,
|
|
65358
|
+
expired_due_count: expiredDueCount
|
|
65222
65359
|
};
|
|
65223
65360
|
for (const row of byScope)
|
|
65224
65361
|
if (row.scope in stats.by_scope)
|
|
@@ -65252,7 +65389,9 @@ function normalizeStats(data) {
|
|
|
65252
65389
|
by_status: { active: 0, archived: 0, expired: 0, ...data?.by_status ?? {} },
|
|
65253
65390
|
by_agent: data?.by_agent ?? {},
|
|
65254
65391
|
pinned_count: data?.pinned_count ?? 0,
|
|
65255
|
-
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
|
|
65256
65395
|
};
|
|
65257
65396
|
}
|
|
65258
65397
|
function getMemoryReport(filter = {}, db) {
|
|
@@ -65310,7 +65449,7 @@ function getStaleMemoriesPage(filter = {}, db) {
|
|
|
65310
65449
|
const limit = filter.limit ?? 20;
|
|
65311
65450
|
const offset = filter.offset ?? 0;
|
|
65312
65451
|
if (!db && isApiMode()) {
|
|
65313
|
-
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 });
|
|
65314
65453
|
const { data } = apiJson("GET", `/memories/stale${q}`);
|
|
65315
65454
|
const rows2 = data?.memories ?? [];
|
|
65316
65455
|
return {
|
|
@@ -65322,8 +65461,14 @@ function getStaleMemoriesPage(filter = {}, db) {
|
|
|
65322
65461
|
}
|
|
65323
65462
|
const d = db || getDatabase();
|
|
65324
65463
|
const cutoffDate = new Date(Date.now() - days * 86400000).toISOString();
|
|
65325
|
-
const conds = ["status = 'active'", "(accessed_at IS NULL OR accessed_at < ?)"
|
|
65464
|
+
const conds = ["status = 'active'", "(accessed_at IS NULL OR accessed_at < ?)"];
|
|
65326
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
|
+
}
|
|
65327
65472
|
if (filter.project_id) {
|
|
65328
65473
|
conds.push("project_id = ?");
|
|
65329
65474
|
params.push(filter.project_id);
|
|
@@ -65500,7 +65645,7 @@ init_projects();
|
|
|
65500
65645
|
init_helpers();
|
|
65501
65646
|
function registerStaleCommand(program2) {
|
|
65502
65647
|
const handleError = makeHandleError(program2);
|
|
65503
|
-
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) => {
|
|
65504
65649
|
try {
|
|
65505
65650
|
const globalOpts = program2.opts();
|
|
65506
65651
|
const days = opts.days || 30;
|
|
@@ -65521,6 +65666,7 @@ function registerStaleCommand(program2) {
|
|
|
65521
65666
|
const { rows: collected, hasMore } = collectPagedRows((cursor, pageLimit) => {
|
|
65522
65667
|
const page = getStaleMemoriesPage({
|
|
65523
65668
|
days,
|
|
65669
|
+
pinned: opts.pinned ? true : undefined,
|
|
65524
65670
|
project_id: projectId,
|
|
65525
65671
|
agent_id: agentId,
|
|
65526
65672
|
limit: pageLimit,
|
|
@@ -65822,7 +65968,7 @@ init_memories();
|
|
|
65822
65968
|
init_helpers();
|
|
65823
65969
|
import chalk18 from "chalk";
|
|
65824
65970
|
import { resolve as resolve12 } from "path";
|
|
65825
|
-
import { readFileSync as
|
|
65971
|
+
import { readFileSync as readFileSync5 } from "fs";
|
|
65826
65972
|
function registerImportCommand(program2) {
|
|
65827
65973
|
const handleError = makeHandleError(program2);
|
|
65828
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) => {
|
|
@@ -65832,7 +65978,7 @@ function registerImportCommand(program2) {
|
|
|
65832
65978
|
if (file === "-" || !file && !process.stdin.isTTY) {
|
|
65833
65979
|
raw = await Bun.stdin.text();
|
|
65834
65980
|
} else if (file) {
|
|
65835
|
-
raw =
|
|
65981
|
+
raw = readFileSync5(resolve12(file), "utf-8");
|
|
65836
65982
|
} else {
|
|
65837
65983
|
console.error(chalk18.red("No input: provide a file path, use '-' for stdin, or pipe data."));
|
|
65838
65984
|
process.exit(1);
|
|
@@ -65862,14 +66008,14 @@ function registerImportCommand(program2) {
|
|
|
65862
66008
|
import chalk19 from "chalk";
|
|
65863
66009
|
|
|
65864
66010
|
// src/lib/config.ts
|
|
65865
|
-
import { existsSync as
|
|
65866
|
-
import { homedir as
|
|
65867
|
-
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";
|
|
65868
66014
|
function isInMemoryDb2(path) {
|
|
65869
66015
|
return path === ":memory:" || path.startsWith("file::memory:");
|
|
65870
66016
|
}
|
|
65871
66017
|
function homeDir() {
|
|
65872
|
-
return process.env["HOME"] || process.env["USERPROFILE"] ||
|
|
66018
|
+
return process.env["HOME"] || process.env["USERPROFILE"] || homedir4();
|
|
65873
66019
|
}
|
|
65874
66020
|
var DEFAULT_CONFIG = {
|
|
65875
66021
|
default_scope: "private",
|
|
@@ -65927,11 +66073,11 @@ function isValidCategory(value) {
|
|
|
65927
66073
|
return VALID_CATEGORIES2.includes(value);
|
|
65928
66074
|
}
|
|
65929
66075
|
function loadConfig() {
|
|
65930
|
-
const configPath =
|
|
66076
|
+
const configPath = join8(homeDir(), ".hasna", "mementos", "config.json");
|
|
65931
66077
|
let fileConfig = {};
|
|
65932
|
-
if (
|
|
66078
|
+
if (existsSync5(configPath)) {
|
|
65933
66079
|
try {
|
|
65934
|
-
const raw =
|
|
66080
|
+
const raw = readFileSync6(configPath, "utf-8");
|
|
65935
66081
|
fileConfig = JSON.parse(raw);
|
|
65936
66082
|
} catch {}
|
|
65937
66083
|
}
|
|
@@ -65957,8 +66103,8 @@ function findFileWalkingUp(filename) {
|
|
|
65957
66103
|
let dir = process.cwd();
|
|
65958
66104
|
const legacyHomeMementosDb = resolve13(homeDir(), ".mementos", "mementos.db");
|
|
65959
66105
|
while (true) {
|
|
65960
|
-
const candidate =
|
|
65961
|
-
if (
|
|
66106
|
+
const candidate = join8(dir, filename);
|
|
66107
|
+
if (existsSync5(candidate) && resolve13(candidate) !== legacyHomeMementosDb) {
|
|
65962
66108
|
return candidate;
|
|
65963
66109
|
}
|
|
65964
66110
|
const parent = dirname4(dir);
|
|
@@ -65971,7 +66117,7 @@ function findFileWalkingUp(filename) {
|
|
|
65971
66117
|
function findGitRoot2() {
|
|
65972
66118
|
let dir = process.cwd();
|
|
65973
66119
|
while (true) {
|
|
65974
|
-
if (
|
|
66120
|
+
if (existsSync5(join8(dir, ".git"))) {
|
|
65975
66121
|
return dir;
|
|
65976
66122
|
}
|
|
65977
66123
|
const parent = dirname4(dir);
|
|
@@ -65982,27 +66128,27 @@ function findGitRoot2() {
|
|
|
65982
66128
|
}
|
|
65983
66129
|
}
|
|
65984
66130
|
function profilesDir() {
|
|
65985
|
-
return
|
|
66131
|
+
return join8(homeDir(), ".hasna", "mementos", "profiles");
|
|
65986
66132
|
}
|
|
65987
66133
|
function globalConfigPath() {
|
|
65988
|
-
return
|
|
66134
|
+
return join8(homeDir(), ".hasna", "mementos", "config.json");
|
|
65989
66135
|
}
|
|
65990
66136
|
function readGlobalConfig() {
|
|
65991
66137
|
const p = globalConfigPath();
|
|
65992
|
-
if (!
|
|
66138
|
+
if (!existsSync5(p))
|
|
65993
66139
|
return {};
|
|
65994
66140
|
try {
|
|
65995
|
-
return JSON.parse(
|
|
66141
|
+
return JSON.parse(readFileSync6(p, "utf-8"));
|
|
65996
66142
|
} catch {
|
|
65997
66143
|
return {};
|
|
65998
66144
|
}
|
|
65999
66145
|
}
|
|
66000
66146
|
function readGlobalConfigForWrite() {
|
|
66001
66147
|
const p = globalConfigPath();
|
|
66002
|
-
if (!
|
|
66148
|
+
if (!existsSync5(p))
|
|
66003
66149
|
return {};
|
|
66004
66150
|
try {
|
|
66005
|
-
const data = JSON.parse(
|
|
66151
|
+
const data = JSON.parse(readFileSync6(p, "utf-8"));
|
|
66006
66152
|
if (data === null || typeof data !== "object" || Array.isArray(data)) {
|
|
66007
66153
|
throw new Error("expected a JSON object");
|
|
66008
66154
|
}
|
|
@@ -66035,13 +66181,13 @@ function setActiveProfile(name) {
|
|
|
66035
66181
|
}
|
|
66036
66182
|
function listProfiles() {
|
|
66037
66183
|
const dir = profilesDir();
|
|
66038
|
-
if (!
|
|
66184
|
+
if (!existsSync5(dir))
|
|
66039
66185
|
return [];
|
|
66040
66186
|
return readdirSync(dir).filter((f) => f.endsWith(".db")).map((f) => basename(f, ".db")).sort();
|
|
66041
66187
|
}
|
|
66042
66188
|
function deleteProfile(name) {
|
|
66043
|
-
const dbPath =
|
|
66044
|
-
if (!
|
|
66189
|
+
const dbPath = join8(profilesDir(), `${name}.db`);
|
|
66190
|
+
if (!existsSync5(dbPath))
|
|
66045
66191
|
return false;
|
|
66046
66192
|
unlinkSync2(dbPath);
|
|
66047
66193
|
if (getActiveProfile() === name)
|
|
@@ -66050,10 +66196,10 @@ function deleteProfile(name) {
|
|
|
66050
66196
|
}
|
|
66051
66197
|
function getDbPath2() {
|
|
66052
66198
|
const _home = homeDir();
|
|
66053
|
-
const _newDir =
|
|
66054
|
-
const _oldDir =
|
|
66055
|
-
if (!
|
|
66056
|
-
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 });
|
|
66057
66203
|
cpSync2(_oldDir, _newDir, { recursive: true });
|
|
66058
66204
|
}
|
|
66059
66205
|
const envDbPath = process.env["HASNA_MEMENTOS_DB_PATH"] ?? process.env["MEMENTOS_DB_PATH"];
|
|
@@ -66067,7 +66213,7 @@ function getDbPath2() {
|
|
|
66067
66213
|
}
|
|
66068
66214
|
const profile = getActiveProfile();
|
|
66069
66215
|
if (profile) {
|
|
66070
|
-
const profilePath =
|
|
66216
|
+
const profilePath = join8(profilesDir(), `${profile}.db`);
|
|
66071
66217
|
ensureDir2(dirname4(profilePath));
|
|
66072
66218
|
return profilePath;
|
|
66073
66219
|
}
|
|
@@ -66075,21 +66221,21 @@ function getDbPath2() {
|
|
|
66075
66221
|
if (dbScope === "project") {
|
|
66076
66222
|
const gitRoot = findGitRoot2();
|
|
66077
66223
|
if (gitRoot) {
|
|
66078
|
-
const dbPath =
|
|
66224
|
+
const dbPath = join8(gitRoot, ".mementos", "mementos.db");
|
|
66079
66225
|
ensureDir2(dirname4(dbPath));
|
|
66080
66226
|
return dbPath;
|
|
66081
66227
|
}
|
|
66082
66228
|
}
|
|
66083
|
-
const found = findFileWalkingUp(
|
|
66229
|
+
const found = findFileWalkingUp(join8(".mementos", "mementos.db"));
|
|
66084
66230
|
if (found) {
|
|
66085
66231
|
return found;
|
|
66086
66232
|
}
|
|
66087
|
-
const fallback =
|
|
66233
|
+
const fallback = join8(homeDir(), ".hasna", "mementos", "mementos.db");
|
|
66088
66234
|
ensureDir2(dirname4(fallback));
|
|
66089
66235
|
return fallback;
|
|
66090
66236
|
}
|
|
66091
66237
|
function ensureDir2(dir) {
|
|
66092
|
-
if (!
|
|
66238
|
+
if (!existsSync5(dir)) {
|
|
66093
66239
|
mkdirSync3(dir, { recursive: true });
|
|
66094
66240
|
}
|
|
66095
66241
|
}
|
|
@@ -66207,7 +66353,7 @@ init_database();
|
|
|
66207
66353
|
init_helpers();
|
|
66208
66354
|
import chalk20 from "chalk";
|
|
66209
66355
|
import { resolve as resolve14, dirname as dirname5 } from "path";
|
|
66210
|
-
import { existsSync as
|
|
66356
|
+
import { existsSync as existsSync6, statSync, copyFileSync, mkdirSync as mkdirSync4, readdirSync as readdirSync2 } from "fs";
|
|
66211
66357
|
function registerBackupCommand(program2) {
|
|
66212
66358
|
const handleError = makeHandleError(program2);
|
|
66213
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) => {
|
|
@@ -66216,7 +66362,7 @@ function registerBackupCommand(program2) {
|
|
|
66216
66362
|
const home = process.env["HOME"] || process.env["USERPROFILE"] || "~";
|
|
66217
66363
|
const backupsDir = resolve14(home, ".hasna", "mementos", "backups");
|
|
66218
66364
|
if (opts.list) {
|
|
66219
|
-
if (!
|
|
66365
|
+
if (!existsSync6(backupsDir)) {
|
|
66220
66366
|
if (globalOpts.json) {
|
|
66221
66367
|
outputJson({ backups: [] });
|
|
66222
66368
|
return;
|
|
@@ -66258,7 +66404,7 @@ function registerBackupCommand(program2) {
|
|
|
66258
66404
|
return;
|
|
66259
66405
|
}
|
|
66260
66406
|
const dbPath = getDbPath();
|
|
66261
|
-
if (!
|
|
66407
|
+
if (!existsSync6(dbPath)) {
|
|
66262
66408
|
console.error(chalk20.red(`Database not found at ${dbPath}`));
|
|
66263
66409
|
process.exit(1);
|
|
66264
66410
|
}
|
|
@@ -66266,7 +66412,7 @@ function registerBackupCommand(program2) {
|
|
|
66266
66412
|
if (targetPath) {
|
|
66267
66413
|
dest = resolve14(targetPath);
|
|
66268
66414
|
} else {
|
|
66269
|
-
if (!
|
|
66415
|
+
if (!existsSync6(backupsDir)) {
|
|
66270
66416
|
mkdirSync4(backupsDir, { recursive: true });
|
|
66271
66417
|
}
|
|
66272
66418
|
const now3 = new Date;
|
|
@@ -66274,7 +66420,7 @@ function registerBackupCommand(program2) {
|
|
|
66274
66420
|
dest = resolve14(backupsDir, `mementos-${ts}.db`);
|
|
66275
66421
|
}
|
|
66276
66422
|
const destDir = dirname5(dest);
|
|
66277
|
-
if (!
|
|
66423
|
+
if (!existsSync6(destDir)) {
|
|
66278
66424
|
mkdirSync4(destDir, { recursive: true });
|
|
66279
66425
|
}
|
|
66280
66426
|
copyFileSync(dbPath, dest);
|
|
@@ -66295,29 +66441,31 @@ function registerBackupCommand(program2) {
|
|
|
66295
66441
|
// src/cli/commands/io-restore.ts
|
|
66296
66442
|
init_database();
|
|
66297
66443
|
init_api_mode();
|
|
66444
|
+
init_memories();
|
|
66298
66445
|
init_helpers();
|
|
66299
66446
|
import chalk21 from "chalk";
|
|
66300
66447
|
import { resolve as resolve15 } from "path";
|
|
66301
|
-
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
|
+
}
|
|
66302
66459
|
function registerRestoreCommand(program2) {
|
|
66303
66460
|
const handleError = makeHandleError(program2);
|
|
66304
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) => {
|
|
66305
66462
|
try {
|
|
66306
66463
|
const globalOpts = program2.opts();
|
|
66307
|
-
if (isApiMode()) {
|
|
66308
|
-
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.";
|
|
66309
|
-
if (globalOpts.json) {
|
|
66310
|
-
outputJson({ error: msg });
|
|
66311
|
-
} else {
|
|
66312
|
-
console.error(chalk21.red(msg));
|
|
66313
|
-
}
|
|
66314
|
-
process.exit(1);
|
|
66315
|
-
}
|
|
66316
66464
|
const home = process.env["HOME"] || process.env["USERPROFILE"] || "~";
|
|
66317
66465
|
const backupsDir = resolve15(home, ".hasna", "mementos", "backups");
|
|
66318
66466
|
let source;
|
|
66319
66467
|
if (opts.latest) {
|
|
66320
|
-
if (!
|
|
66468
|
+
if (!existsSync7(backupsDir)) {
|
|
66321
66469
|
console.error(chalk21.red("No backups directory found."));
|
|
66322
66470
|
process.exit(1);
|
|
66323
66471
|
}
|
|
@@ -66337,16 +66485,82 @@ function registerRestoreCommand(program2) {
|
|
|
66337
66485
|
console.error(chalk21.red("Provide a backup file path or use --latest"));
|
|
66338
66486
|
process.exit(1);
|
|
66339
66487
|
}
|
|
66340
|
-
if (!
|
|
66488
|
+
if (!existsSync7(source)) {
|
|
66341
66489
|
console.error(chalk21.red(`Backup file not found: ${source}`));
|
|
66342
66490
|
process.exit(1);
|
|
66343
66491
|
}
|
|
66344
|
-
const dbPath = getDbPath();
|
|
66345
66492
|
const backupStat = statSync2(source);
|
|
66346
66493
|
const backupSizeMB = (backupStat.size / (1024 * 1024)).toFixed(1);
|
|
66347
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();
|
|
66348
66562
|
let currentCount = 0;
|
|
66349
|
-
if (
|
|
66563
|
+
if (existsSync7(dbPath)) {
|
|
66350
66564
|
try {
|
|
66351
66565
|
const db = getDatabase();
|
|
66352
66566
|
const row = db.query("SELECT COUNT(*) as count FROM memories").get();
|
|
@@ -67600,11 +67814,11 @@ init_memories();
|
|
|
67600
67814
|
init_agents();
|
|
67601
67815
|
init_projects();
|
|
67602
67816
|
import chalk27 from "chalk";
|
|
67603
|
-
import { join as
|
|
67604
|
-
import { homedir as
|
|
67817
|
+
import { join as join9 } from "path";
|
|
67818
|
+
import { homedir as homedir5 } from "os";
|
|
67605
67819
|
import {
|
|
67606
|
-
readFileSync as
|
|
67607
|
-
existsSync as
|
|
67820
|
+
readFileSync as readFileSync7,
|
|
67821
|
+
existsSync as existsSync8,
|
|
67608
67822
|
accessSync,
|
|
67609
67823
|
statSync as statSync3,
|
|
67610
67824
|
constants as fsConstants
|
|
@@ -67639,7 +67853,7 @@ function registerDoctorCommand(program2) {
|
|
|
67639
67853
|
checks.push({ name: "Version", status: "ok", detail: version });
|
|
67640
67854
|
const dbPath = getDbPath();
|
|
67641
67855
|
let db = null;
|
|
67642
|
-
if (dbPath !== ":memory:" &&
|
|
67856
|
+
if (dbPath !== ":memory:" && existsSync8(dbPath)) {
|
|
67643
67857
|
try {
|
|
67644
67858
|
accessSync(dbPath, fsConstants.R_OK | fsConstants.W_OK);
|
|
67645
67859
|
checks.push({ name: "Database file", status: "ok", detail: dbPath });
|
|
@@ -67658,7 +67872,7 @@ function registerDoctorCommand(program2) {
|
|
|
67658
67872
|
checks.push({ name: "Database connection", status: "fail", detail: e instanceof Error ? e.message : String(e) });
|
|
67659
67873
|
}
|
|
67660
67874
|
try {
|
|
67661
|
-
if (dbPath !== ":memory:" &&
|
|
67875
|
+
if (dbPath !== ":memory:" && existsSync8(dbPath)) {
|
|
67662
67876
|
const stats = statSync3(dbPath);
|
|
67663
67877
|
const sizeKb = (stats.size / 1024).toFixed(1);
|
|
67664
67878
|
const sizeMb = (stats.size / (1024 * 1024)).toFixed(2);
|
|
@@ -67791,9 +68005,9 @@ function registerDoctorCommand(program2) {
|
|
|
67791
68005
|
checks.push({ name: "MCP server", status: "warn", detail: "could not check (is claude CLI installed?)" });
|
|
67792
68006
|
}
|
|
67793
68007
|
try {
|
|
67794
|
-
const settingsFilePath =
|
|
67795
|
-
if (
|
|
67796
|
-
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"));
|
|
67797
68011
|
const hooksObj = settings["hooks"] || {};
|
|
67798
68012
|
const stopHooks = hooksObj["Stop"] || [];
|
|
67799
68013
|
const hasMementos = stopHooks.some((e) => e.hooks?.some((h) => h.command && h.command.includes("mementos")));
|
|
@@ -67809,11 +68023,11 @@ function registerDoctorCommand(program2) {
|
|
|
67809
68023
|
checks.push({ name: "Stop hook", status: "warn", detail: "could not check stop hook" });
|
|
67810
68024
|
}
|
|
67811
68025
|
if (process.platform === "darwin") {
|
|
67812
|
-
const plistFilePath =
|
|
68026
|
+
const plistFilePath = join9(homedir5(), "Library", "LaunchAgents", "com.hasna.mementos.plist");
|
|
67813
68027
|
checks.push({
|
|
67814
68028
|
name: "Auto-start",
|
|
67815
|
-
status:
|
|
67816
|
-
detail:
|
|
68029
|
+
status: existsSync8(plistFilePath) ? "ok" : "warn",
|
|
68030
|
+
detail: existsSync8(plistFilePath) ? "configured (starts on login)" : "not configured \u2192 run: mementos init"
|
|
67817
68031
|
});
|
|
67818
68032
|
} else {
|
|
67819
68033
|
checks.push({ name: "Auto-start", status: "ok", detail: `n/a on ${process.platform}` });
|
|
@@ -67892,9 +68106,9 @@ async function runCloudDoctor(globalOpts, checks) {
|
|
|
67892
68106
|
checks.push({ name: "MCP server", status: "warn", detail: "could not check (is claude CLI installed?)" });
|
|
67893
68107
|
}
|
|
67894
68108
|
try {
|
|
67895
|
-
const settingsFilePath =
|
|
67896
|
-
if (
|
|
67897
|
-
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"));
|
|
67898
68112
|
const hooksObj = settings["hooks"] || {};
|
|
67899
68113
|
const stopHooks = hooksObj["Stop"] || [];
|
|
67900
68114
|
const hasMementos = stopHooks.some((e) => e.hooks?.some((h) => h.command && h.command.includes("mementos")));
|
|
@@ -67910,11 +68124,11 @@ async function runCloudDoctor(globalOpts, checks) {
|
|
|
67910
68124
|
checks.push({ name: "Stop hook", status: "warn", detail: "could not check stop hook" });
|
|
67911
68125
|
}
|
|
67912
68126
|
if (process.platform === "darwin") {
|
|
67913
|
-
const plistFilePath =
|
|
68127
|
+
const plistFilePath = join9(homedir5(), "Library", "LaunchAgents", "com.hasna.mementos.plist");
|
|
67914
68128
|
checks.push({
|
|
67915
68129
|
name: "Auto-start",
|
|
67916
|
-
status:
|
|
67917
|
-
detail:
|
|
68130
|
+
status: existsSync8(plistFilePath) ? "ok" : "warn",
|
|
68131
|
+
detail: existsSync8(plistFilePath) ? "configured (starts on login)" : "not configured \u2192 run: mementos init"
|
|
67918
68132
|
});
|
|
67919
68133
|
} else {
|
|
67920
68134
|
checks.push({ name: "Auto-start", status: "ok", detail: `n/a on ${process.platform}` });
|
|
@@ -69440,6 +69654,7 @@ function syncMemoriesTable(source, target, local, direction, currentMachineId) {
|
|
|
69440
69654
|
const countResult = source.get(`SELECT COUNT(*) as cnt FROM "${MEMORY_TABLE}"`);
|
|
69441
69655
|
stat.total_rows = countResult?.cnt ?? 0;
|
|
69442
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;
|
|
69443
69658
|
for (const row of rows) {
|
|
69444
69659
|
try {
|
|
69445
69660
|
const sourceMachine = sourceMachineRef(row, currentMachineId);
|
|
@@ -69498,18 +69713,34 @@ function syncMemoriesTable(source, target, local, direction, currentMachineId) {
|
|
|
69498
69713
|
clearMemoryEmbedding(winnerDb, String(winner["id"]));
|
|
69499
69714
|
stat.synced_rows++;
|
|
69500
69715
|
} catch (error) {
|
|
69716
|
+
erroredRowIds.add(String(row["id"] ?? "unknown"));
|
|
69501
69717
|
stat.errors.push(`Memory ${String(row["id"] ?? "unknown")}: ${error instanceof Error ? error.message : String(error)}`);
|
|
69502
69718
|
}
|
|
69503
69719
|
}
|
|
69504
69720
|
if (rows.length === 0) {
|
|
69505
69721
|
stat.skipped_rows = stat.total_rows;
|
|
69506
69722
|
}
|
|
69507
|
-
|
|
69508
|
-
|
|
69509
|
-
|
|
69510
|
-
|
|
69511
|
-
|
|
69512
|
-
|
|
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
|
+
}
|
|
69513
69744
|
} catch (error) {
|
|
69514
69745
|
stat.errors.push(error instanceof Error ? error.message : String(error));
|
|
69515
69746
|
}
|
|
@@ -69899,19 +70130,19 @@ function registerStorageCommands(program2) {
|
|
|
69899
70130
|
// src/cli/commands/init.ts
|
|
69900
70131
|
import chalk41 from "chalk";
|
|
69901
70132
|
import {
|
|
69902
|
-
readFileSync as
|
|
70133
|
+
readFileSync as readFileSync8,
|
|
69903
70134
|
writeFileSync as writeFileSync4,
|
|
69904
|
-
existsSync as
|
|
70135
|
+
existsSync as existsSync10,
|
|
69905
70136
|
copyFileSync as copyFileSync3,
|
|
69906
70137
|
mkdirSync as mkdirSync6
|
|
69907
70138
|
} from "fs";
|
|
69908
|
-
import { dirname as dirname7, join as
|
|
69909
|
-
import { homedir as
|
|
70139
|
+
import { dirname as dirname7, join as join11 } from "path";
|
|
70140
|
+
import { homedir as homedir6 } from "os";
|
|
69910
70141
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
69911
70142
|
function registerInitCommand(program2) {
|
|
69912
70143
|
program2.command("init").description("One-command setup: register MCP, install stop hook, configure auto-start").action(async () => {
|
|
69913
70144
|
const { platform: platform2 } = process;
|
|
69914
|
-
const home =
|
|
70145
|
+
const home = homedir6();
|
|
69915
70146
|
const isMac = platform2 === "darwin";
|
|
69916
70147
|
console.log("");
|
|
69917
70148
|
console.log(chalk41.bold(" mementos \u2014 setting up your memory layer"));
|
|
@@ -69966,17 +70197,17 @@ function registerInitCommand(program2) {
|
|
|
69966
70197
|
} else {
|
|
69967
70198
|
console.log(chalk41.green(" \u2713 MCP server registered with Claude Code"));
|
|
69968
70199
|
}
|
|
69969
|
-
const hooksDir =
|
|
69970
|
-
const hookDest =
|
|
69971
|
-
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");
|
|
69972
70203
|
const hookCommand = `bun ${hookDest}`;
|
|
69973
70204
|
let hookAlreadyInstalled = false;
|
|
69974
70205
|
let hookError = null;
|
|
69975
70206
|
try {
|
|
69976
70207
|
let settings = {};
|
|
69977
|
-
if (
|
|
70208
|
+
if (existsSync10(settingsPath)) {
|
|
69978
70209
|
try {
|
|
69979
|
-
settings = JSON.parse(
|
|
70210
|
+
settings = JSON.parse(readFileSync8(settingsPath, "utf-8"));
|
|
69980
70211
|
} catch {
|
|
69981
70212
|
settings = {};
|
|
69982
70213
|
}
|
|
@@ -69987,19 +70218,19 @@ function registerInitCommand(program2) {
|
|
|
69987
70218
|
if (alreadyHasMementos) {
|
|
69988
70219
|
hookAlreadyInstalled = true;
|
|
69989
70220
|
} else {
|
|
69990
|
-
if (!
|
|
70221
|
+
if (!existsSync10(hooksDir)) {
|
|
69991
70222
|
mkdirSync6(hooksDir, { recursive: true });
|
|
69992
70223
|
}
|
|
69993
|
-
if (!
|
|
70224
|
+
if (!existsSync10(hookDest)) {
|
|
69994
70225
|
const packageDir = dirname7(dirname7(fileURLToPath4(import.meta.url)));
|
|
69995
70226
|
const candidatePaths = [
|
|
69996
|
-
|
|
69997
|
-
|
|
69998
|
-
|
|
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")
|
|
69999
70230
|
];
|
|
70000
70231
|
let hookSourceFound = false;
|
|
70001
70232
|
for (const src of candidatePaths) {
|
|
70002
|
-
if (
|
|
70233
|
+
if (existsSync10(src)) {
|
|
70003
70234
|
copyFileSync3(src, hookDest);
|
|
70004
70235
|
hookSourceFound = true;
|
|
70005
70236
|
break;
|
|
@@ -70065,7 +70296,7 @@ main().catch(() => {});
|
|
|
70065
70296
|
if (!isMac) {
|
|
70066
70297
|
console.log(chalk41.dim(` \xB7 Auto-start skipped (not macOS \u2014 platform: ${platform2})`));
|
|
70067
70298
|
} else {
|
|
70068
|
-
const plistPath =
|
|
70299
|
+
const plistPath = join11(home, "Library", "LaunchAgents", "com.hasna.mementos.plist");
|
|
70069
70300
|
const plistContent = `<?xml version="1.0" encoding="UTF-8"?>
|
|
70070
70301
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
70071
70302
|
<plist version="1.0">
|
|
@@ -70090,11 +70321,11 @@ main().catch(() => {});
|
|
|
70090
70321
|
</plist>
|
|
70091
70322
|
`;
|
|
70092
70323
|
try {
|
|
70093
|
-
if (
|
|
70324
|
+
if (existsSync10(plistPath)) {
|
|
70094
70325
|
autoStartAlreadyInstalled = true;
|
|
70095
70326
|
} else {
|
|
70096
|
-
const launchAgentsDir =
|
|
70097
|
-
if (!
|
|
70327
|
+
const launchAgentsDir = join11(home, "Library", "LaunchAgents");
|
|
70328
|
+
if (!existsSync10(launchAgentsDir)) {
|
|
70098
70329
|
mkdirSync6(launchAgentsDir, { recursive: true });
|
|
70099
70330
|
}
|
|
70100
70331
|
writeFileSync4(plistPath, plistContent, "utf-8");
|
|
@@ -70110,7 +70341,7 @@ main().catch(() => {});
|
|
|
70110
70341
|
console.log(chalk41.green(" \u2713 Auto-start configured (starts on login)"));
|
|
70111
70342
|
}
|
|
70112
70343
|
if (!autoStartAlreadyInstalled && !autoStartError) {
|
|
70113
|
-
const plistPath2 =
|
|
70344
|
+
const plistPath2 = join11(home, "Library", "LaunchAgents", "com.hasna.mementos.plist");
|
|
70114
70345
|
const loadResult = await run(["launchctl", "load", plistPath2]);
|
|
70115
70346
|
if (!loadResult.ok) {
|
|
70116
70347
|
console.log(chalk41.dim(` \xB7 launchctl load: ${loadResult.output || "already loaded"}`));
|
|
@@ -71224,13 +71455,13 @@ function lessonTagForCli(kind) {
|
|
|
71224
71455
|
|
|
71225
71456
|
// src/cli/brains.ts
|
|
71226
71457
|
import {
|
|
71227
|
-
existsSync as
|
|
71458
|
+
existsSync as existsSync12,
|
|
71228
71459
|
mkdirSync as mkdirSync8,
|
|
71229
71460
|
writeFileSync as writeFileSync6,
|
|
71230
71461
|
readdirSync as readdirSync4
|
|
71231
71462
|
} from "fs";
|
|
71232
|
-
import { homedir as
|
|
71233
|
-
import { join as
|
|
71463
|
+
import { homedir as homedir8 } from "os";
|
|
71464
|
+
import { join as join13 } from "path";
|
|
71234
71465
|
import chalk43 from "chalk";
|
|
71235
71466
|
|
|
71236
71467
|
// src/lib/gatherer.ts
|
|
@@ -71307,24 +71538,24 @@ var gatherTrainingData = async (options = {}) => {
|
|
|
71307
71538
|
};
|
|
71308
71539
|
|
|
71309
71540
|
// src/lib/model-config.ts
|
|
71310
|
-
import { existsSync as
|
|
71311
|
-
import { homedir as
|
|
71312
|
-
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";
|
|
71313
71544
|
var DEFAULT_MODEL = "gpt-4o-mini";
|
|
71314
|
-
var CONFIG_DIR =
|
|
71315
|
-
var CONFIG_PATH =
|
|
71545
|
+
var CONFIG_DIR = join12(homedir7(), ".hasna", "mementos");
|
|
71546
|
+
var CONFIG_PATH = join12(CONFIG_DIR, "config.json");
|
|
71316
71547
|
function readConfig() {
|
|
71317
|
-
if (!
|
|
71548
|
+
if (!existsSync11(CONFIG_PATH))
|
|
71318
71549
|
return {};
|
|
71319
71550
|
try {
|
|
71320
|
-
const raw =
|
|
71551
|
+
const raw = readFileSync9(CONFIG_PATH, "utf-8");
|
|
71321
71552
|
return JSON.parse(raw);
|
|
71322
71553
|
} catch {
|
|
71323
71554
|
return {};
|
|
71324
71555
|
}
|
|
71325
71556
|
}
|
|
71326
71557
|
function writeConfig(config2) {
|
|
71327
|
-
if (!
|
|
71558
|
+
if (!existsSync11(CONFIG_DIR)) {
|
|
71328
71559
|
mkdirSync7(CONFIG_DIR, { recursive: true });
|
|
71329
71560
|
}
|
|
71330
71561
|
writeFileSync5(CONFIG_PATH, JSON.stringify(config2, null, 2) + `
|
|
@@ -71372,12 +71603,12 @@ function makeBrainsCommand() {
|
|
|
71372
71603
|
limit: opts.limit,
|
|
71373
71604
|
since
|
|
71374
71605
|
});
|
|
71375
|
-
const outputDir = opts.output ??
|
|
71376
|
-
if (!
|
|
71606
|
+
const outputDir = opts.output ?? join13(homedir8(), ".hasna", "mementos", "training");
|
|
71607
|
+
if (!existsSync12(outputDir)) {
|
|
71377
71608
|
mkdirSync8(outputDir, { recursive: true });
|
|
71378
71609
|
}
|
|
71379
71610
|
const timestamp2 = new Date().toISOString().replace(/[:.]/g, "-").slice(0, 19);
|
|
71380
|
-
const outputPath =
|
|
71611
|
+
const outputPath = join13(outputDir, `mementos-training-${timestamp2}.jsonl`);
|
|
71381
71612
|
const jsonl = result.examples.map((ex) => JSON.stringify(ex)).join(`
|
|
71382
71613
|
`);
|
|
71383
71614
|
writeFileSync6(outputPath, jsonl + `
|
|
@@ -71401,8 +71632,8 @@ function makeBrainsCommand() {
|
|
|
71401
71632
|
try {
|
|
71402
71633
|
let datasetPath = opts.dataset;
|
|
71403
71634
|
if (!datasetPath) {
|
|
71404
|
-
const trainingDir =
|
|
71405
|
-
if (!
|
|
71635
|
+
const trainingDir = join13(homedir8(), ".hasna", "mementos", "training");
|
|
71636
|
+
if (!existsSync12(trainingDir)) {
|
|
71406
71637
|
printError("No training data found. Run `mementos brains gather` first.");
|
|
71407
71638
|
process.exit(1);
|
|
71408
71639
|
}
|
|
@@ -71412,9 +71643,9 @@ function makeBrainsCommand() {
|
|
|
71412
71643
|
printError("No JSONL training files found. Run `mementos brains gather` first.");
|
|
71413
71644
|
process.exit(1);
|
|
71414
71645
|
}
|
|
71415
|
-
datasetPath =
|
|
71646
|
+
datasetPath = join13(trainingDir, latestFile);
|
|
71416
71647
|
}
|
|
71417
|
-
if (!datasetPath || !
|
|
71648
|
+
if (!datasetPath || !existsSync12(datasetPath)) {
|
|
71418
71649
|
printError(`Dataset file not found: ${datasetPath ?? "(unresolved)"}`);
|
|
71419
71650
|
process.exit(1);
|
|
71420
71651
|
}
|
|
@@ -71540,8 +71771,8 @@ function registerAllCommands(program2) {
|
|
|
71540
71771
|
// src/cli/index.tsx
|
|
71541
71772
|
function getPackageVersion2() {
|
|
71542
71773
|
try {
|
|
71543
|
-
const pkgPath =
|
|
71544
|
-
const pkg = JSON.parse(
|
|
71774
|
+
const pkgPath = join14(dirname8(fileURLToPath5(import.meta.url)), "..", "..", "package.json");
|
|
71775
|
+
const pkg = JSON.parse(readFileSync10(pkgPath, "utf-8"));
|
|
71545
71776
|
return pkg.version || "0.0.0";
|
|
71546
71777
|
} catch {
|
|
71547
71778
|
return "0.0.0";
|