@andre.li/memoark 0.3.1
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/LICENSE +191 -0
- package/README.en.md +606 -0
- package/README.md +560 -0
- package/bin/memoark.mjs +36 -0
- package/dist/adapters/file.d.ts +19 -0
- package/dist/adapters/file.d.ts.map +1 -0
- package/dist/adapters/file.js +61 -0
- package/dist/adapters/file.js.map +1 -0
- package/dist/adapters/gbrain.d.ts +29 -0
- package/dist/adapters/gbrain.d.ts.map +1 -0
- package/dist/adapters/gbrain.js +622 -0
- package/dist/adapters/gbrain.js.map +1 -0
- package/dist/adapters/index.d.ts +6 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +5 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/registry.d.ts +18 -0
- package/dist/adapters/registry.d.ts.map +1 -0
- package/dist/adapters/registry.js +18 -0
- package/dist/adapters/registry.js.map +1 -0
- package/dist/adapters/stdout.d.ts +12 -0
- package/dist/adapters/stdout.d.ts.map +1 -0
- package/dist/adapters/stdout.js +29 -0
- package/dist/adapters/stdout.js.map +1 -0
- package/dist/adapters/store.d.ts +47 -0
- package/dist/adapters/store.d.ts.map +1 -0
- package/dist/adapters/store.js +641 -0
- package/dist/adapters/store.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +694 -0
- package/dist/cli.js.map +1 -0
- package/dist/collectors/agent/claude-code.d.ts +12 -0
- package/dist/collectors/agent/claude-code.d.ts.map +1 -0
- package/dist/collectors/agent/claude-code.js +94 -0
- package/dist/collectors/agent/claude-code.js.map +1 -0
- package/dist/collectors/agent/codex.d.ts +16 -0
- package/dist/collectors/agent/codex.d.ts.map +1 -0
- package/dist/collectors/agent/codex.js +149 -0
- package/dist/collectors/agent/codex.js.map +1 -0
- package/dist/collectors/agent/collector.d.ts +20 -0
- package/dist/collectors/agent/collector.d.ts.map +1 -0
- package/dist/collectors/agent/collector.js +108 -0
- package/dist/collectors/agent/collector.js.map +1 -0
- package/dist/collectors/agent/hermes.d.ts +13 -0
- package/dist/collectors/agent/hermes.d.ts.map +1 -0
- package/dist/collectors/agent/hermes.js +90 -0
- package/dist/collectors/agent/hermes.js.map +1 -0
- package/dist/collectors/agent/index.d.ts +6 -0
- package/dist/collectors/agent/index.d.ts.map +1 -0
- package/dist/collectors/agent/index.js +5 -0
- package/dist/collectors/agent/index.js.map +1 -0
- package/dist/collectors/agent/types.d.ts +61 -0
- package/dist/collectors/agent/types.d.ts.map +1 -0
- package/dist/collectors/agent/types.js +6 -0
- package/dist/collectors/agent/types.js.map +1 -0
- package/dist/collectors/feishu/auth.d.ts +13 -0
- package/dist/collectors/feishu/auth.d.ts.map +1 -0
- package/dist/collectors/feishu/auth.js +72 -0
- package/dist/collectors/feishu/auth.js.map +1 -0
- package/dist/collectors/feishu/collector.d.ts +23 -0
- package/dist/collectors/feishu/collector.d.ts.map +1 -0
- package/dist/collectors/feishu/collector.js +113 -0
- package/dist/collectors/feishu/collector.js.map +1 -0
- package/dist/collectors/feishu/cursor-staging.d.ts +11 -0
- package/dist/collectors/feishu/cursor-staging.d.ts.map +1 -0
- package/dist/collectors/feishu/cursor-staging.js +37 -0
- package/dist/collectors/feishu/cursor-staging.js.map +1 -0
- package/dist/collectors/feishu/http-client.d.ts +26 -0
- package/dist/collectors/feishu/http-client.d.ts.map +1 -0
- package/dist/collectors/feishu/http-client.js +94 -0
- package/dist/collectors/feishu/http-client.js.map +1 -0
- package/dist/collectors/feishu/index.d.ts +3 -0
- package/dist/collectors/feishu/index.d.ts.map +1 -0
- package/dist/collectors/feishu/index.js +2 -0
- package/dist/collectors/feishu/index.js.map +1 -0
- package/dist/collectors/feishu/lark-cli-client.d.ts +16 -0
- package/dist/collectors/feishu/lark-cli-client.d.ts.map +1 -0
- package/dist/collectors/feishu/lark-cli-client.js +69 -0
- package/dist/collectors/feishu/lark-cli-client.js.map +1 -0
- package/dist/collectors/feishu/rate-limiter.d.ts +10 -0
- package/dist/collectors/feishu/rate-limiter.d.ts.map +1 -0
- package/dist/collectors/feishu/rate-limiter.js +33 -0
- package/dist/collectors/feishu/rate-limiter.js.map +1 -0
- package/dist/collectors/feishu/sources/base.d.ts +9 -0
- package/dist/collectors/feishu/sources/base.d.ts.map +1 -0
- package/dist/collectors/feishu/sources/base.js +2 -0
- package/dist/collectors/feishu/sources/base.js.map +1 -0
- package/dist/collectors/feishu/sources/calendar.d.ts +16 -0
- package/dist/collectors/feishu/sources/calendar.d.ts.map +1 -0
- package/dist/collectors/feishu/sources/calendar.js +93 -0
- package/dist/collectors/feishu/sources/calendar.js.map +1 -0
- package/dist/collectors/feishu/sources/dm.d.ts +28 -0
- package/dist/collectors/feishu/sources/dm.d.ts.map +1 -0
- package/dist/collectors/feishu/sources/dm.js +152 -0
- package/dist/collectors/feishu/sources/dm.js.map +1 -0
- package/dist/collectors/feishu/sources/docs.d.ts +23 -0
- package/dist/collectors/feishu/sources/docs.d.ts.map +1 -0
- package/dist/collectors/feishu/sources/docs.js +154 -0
- package/dist/collectors/feishu/sources/docs.js.map +1 -0
- package/dist/collectors/feishu/sources/mail.d.ts +27 -0
- package/dist/collectors/feishu/sources/mail.d.ts.map +1 -0
- package/dist/collectors/feishu/sources/mail.js +136 -0
- package/dist/collectors/feishu/sources/mail.js.map +1 -0
- package/dist/collectors/feishu/sources/message-search.d.ts +37 -0
- package/dist/collectors/feishu/sources/message-search.d.ts.map +1 -0
- package/dist/collectors/feishu/sources/message-search.js +140 -0
- package/dist/collectors/feishu/sources/message-search.js.map +1 -0
- package/dist/collectors/feishu/sources/messages.d.ts +26 -0
- package/dist/collectors/feishu/sources/messages.d.ts.map +1 -0
- package/dist/collectors/feishu/sources/messages.js +148 -0
- package/dist/collectors/feishu/sources/messages.js.map +1 -0
- package/dist/collectors/feishu/sources/tasks.d.ts +15 -0
- package/dist/collectors/feishu/sources/tasks.d.ts.map +1 -0
- package/dist/collectors/feishu/sources/tasks.js +74 -0
- package/dist/collectors/feishu/sources/tasks.js.map +1 -0
- package/dist/collectors/feishu/types.d.ts +224 -0
- package/dist/collectors/feishu/types.d.ts.map +1 -0
- package/dist/collectors/feishu/types.js +17 -0
- package/dist/collectors/feishu/types.js.map +1 -0
- package/dist/collectors/index.d.ts +10 -0
- package/dist/collectors/index.d.ts.map +1 -0
- package/dist/collectors/index.js +18 -0
- package/dist/collectors/index.js.map +1 -0
- package/dist/config-center/connection-checks.d.ts +28 -0
- package/dist/config-center/connection-checks.d.ts.map +1 -0
- package/dist/config-center/connection-checks.js +114 -0
- package/dist/config-center/connection-checks.js.map +1 -0
- package/dist/config-center/document.d.ts +21 -0
- package/dist/config-center/document.d.ts.map +1 -0
- package/dist/config-center/document.js +93 -0
- package/dist/config-center/document.js.map +1 -0
- package/dist/config-center/index.d.ts +9 -0
- package/dist/config-center/index.d.ts.map +1 -0
- package/dist/config-center/index.js +29 -0
- package/dist/config-center/index.js.map +1 -0
- package/dist/config-center/recommendations.d.ts +16 -0
- package/dist/config-center/recommendations.d.ts.map +1 -0
- package/dist/config-center/recommendations.js +50 -0
- package/dist/config-center/recommendations.js.map +1 -0
- package/dist/config-center/reducer.d.ts +57 -0
- package/dist/config-center/reducer.d.ts.map +1 -0
- package/dist/config-center/reducer.js +192 -0
- package/dist/config-center/reducer.js.map +1 -0
- package/dist/config-center/schema.d.ts +31 -0
- package/dist/config-center/schema.d.ts.map +1 -0
- package/dist/config-center/schema.js +365 -0
- package/dist/config-center/schema.js.map +1 -0
- package/dist/config-center/secrets.d.ts +4 -0
- package/dist/config-center/secrets.d.ts.map +1 -0
- package/dist/config-center/secrets.js +27 -0
- package/dist/config-center/secrets.js.map +1 -0
- package/dist/config-center/source-dirs.d.ts +16 -0
- package/dist/config-center/source-dirs.d.ts.map +1 -0
- package/dist/config-center/source-dirs.js +81 -0
- package/dist/config-center/source-dirs.js.map +1 -0
- package/dist/config-center/tui/app.d.ts +22 -0
- package/dist/config-center/tui/app.d.ts.map +1 -0
- package/dist/config-center/tui/app.js +142 -0
- package/dist/config-center/tui/app.js.map +1 -0
- package/dist/config-center/tui/render.d.ts +20 -0
- package/dist/config-center/tui/render.d.ts.map +1 -0
- package/dist/config-center/tui/render.js +166 -0
- package/dist/config-center/tui/render.js.map +1 -0
- package/dist/config-center/validation.d.ts +9 -0
- package/dist/config-center/validation.d.ts.map +1 -0
- package/dist/config-center/validation.js +59 -0
- package/dist/config-center/validation.js.map +1 -0
- package/dist/consolidator/consolidator.d.ts +31 -0
- package/dist/consolidator/consolidator.d.ts.map +1 -0
- package/dist/consolidator/consolidator.js +57 -0
- package/dist/consolidator/consolidator.js.map +1 -0
- package/dist/consolidator/dead-link.d.ts +7 -0
- package/dist/consolidator/dead-link.d.ts.map +1 -0
- package/dist/consolidator/dead-link.js +57 -0
- package/dist/consolidator/dead-link.js.map +1 -0
- package/dist/consolidator/hot-warm.d.ts +9 -0
- package/dist/consolidator/hot-warm.d.ts.map +1 -0
- package/dist/consolidator/hot-warm.js +88 -0
- package/dist/consolidator/hot-warm.js.map +1 -0
- package/dist/consolidator/infer-preferences.d.ts +14 -0
- package/dist/consolidator/infer-preferences.d.ts.map +1 -0
- package/dist/consolidator/infer-preferences.js +73 -0
- package/dist/consolidator/infer-preferences.js.map +1 -0
- package/dist/consolidator/rules.d.ts +5 -0
- package/dist/consolidator/rules.d.ts.map +1 -0
- package/dist/consolidator/rules.js +53 -0
- package/dist/consolidator/rules.js.map +1 -0
- package/dist/consolidator/warm-cold.d.ts +13 -0
- package/dist/consolidator/warm-cold.d.ts.map +1 -0
- package/dist/consolidator/warm-cold.js +91 -0
- package/dist/consolidator/warm-cold.js.map +1 -0
- package/dist/core/block-builder.d.ts +15 -0
- package/dist/core/block-builder.d.ts.map +1 -0
- package/dist/core/block-builder.js +185 -0
- package/dist/core/block-builder.js.map +1 -0
- package/dist/core/canonicalize.d.ts +3 -0
- package/dist/core/canonicalize.d.ts.map +1 -0
- package/dist/core/canonicalize.js +137 -0
- package/dist/core/canonicalize.js.map +1 -0
- package/dist/core/concurrency.d.ts +2 -0
- package/dist/core/concurrency.d.ts.map +1 -0
- package/dist/core/concurrency.js +14 -0
- package/dist/core/concurrency.js.map +1 -0
- package/dist/core/config.d.ts +184 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +136 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/cursors.d.ts +36 -0
- package/dist/core/cursors.d.ts.map +1 -0
- package/dist/core/cursors.js +90 -0
- package/dist/core/cursors.js.map +1 -0
- package/dist/core/dedup.d.ts +45 -0
- package/dist/core/dedup.d.ts.map +1 -0
- package/dist/core/dedup.js +111 -0
- package/dist/core/dedup.js.map +1 -0
- package/dist/core/entity-extract.d.ts +3 -0
- package/dist/core/entity-extract.d.ts.map +1 -0
- package/dist/core/entity-extract.js +54 -0
- package/dist/core/entity-extract.js.map +1 -0
- package/dist/core/helpers.d.ts +3 -0
- package/dist/core/helpers.d.ts.map +1 -0
- package/dist/core/helpers.js +10 -0
- package/dist/core/helpers.js.map +1 -0
- package/dist/core/identity-resolver.d.ts +21 -0
- package/dist/core/identity-resolver.d.ts.map +1 -0
- package/dist/core/identity-resolver.js +62 -0
- package/dist/core/identity-resolver.js.map +1 -0
- package/dist/core/pipeline-factory.d.ts +13 -0
- package/dist/core/pipeline-factory.d.ts.map +1 -0
- package/dist/core/pipeline-factory.js +32 -0
- package/dist/core/pipeline-factory.js.map +1 -0
- package/dist/core/pipeline.d.ts +61 -0
- package/dist/core/pipeline.d.ts.map +1 -0
- package/dist/core/pipeline.js +261 -0
- package/dist/core/pipeline.js.map +1 -0
- package/dist/core/schemas.d.ts +2470 -0
- package/dist/core/schemas.d.ts.map +1 -0
- package/dist/core/schemas.js +229 -0
- package/dist/core/schemas.js.map +1 -0
- package/dist/core/signal-scoring.d.ts +3 -0
- package/dist/core/signal-scoring.d.ts.map +1 -0
- package/dist/core/signal-scoring.js +124 -0
- package/dist/core/signal-scoring.js.map +1 -0
- package/dist/core/state.d.ts +22 -0
- package/dist/core/state.d.ts.map +1 -0
- package/dist/core/state.js +32 -0
- package/dist/core/state.js.map +1 -0
- package/dist/core/types.d.ts +231 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +6 -0
- package/dist/core/types.js.map +1 -0
- package/dist/daemon/alerts.d.ts +12 -0
- package/dist/daemon/alerts.d.ts.map +1 -0
- package/dist/daemon/alerts.js +34 -0
- package/dist/daemon/alerts.js.map +1 -0
- package/dist/daemon/index.d.ts +6 -0
- package/dist/daemon/index.d.ts.map +1 -0
- package/dist/daemon/index.js +6 -0
- package/dist/daemon/index.js.map +1 -0
- package/dist/daemon/logger.d.ts +8 -0
- package/dist/daemon/logger.d.ts.map +1 -0
- package/dist/daemon/logger.js +35 -0
- package/dist/daemon/logger.js.map +1 -0
- package/dist/daemon/run-history.d.ts +29 -0
- package/dist/daemon/run-history.d.ts.map +1 -0
- package/dist/daemon/run-history.js +54 -0
- package/dist/daemon/run-history.js.map +1 -0
- package/dist/daemon/scheduler.d.ts +37 -0
- package/dist/daemon/scheduler.d.ts.map +1 -0
- package/dist/daemon/scheduler.js +142 -0
- package/dist/daemon/scheduler.js.map +1 -0
- package/dist/daemon/source-schedule.d.ts +25 -0
- package/dist/daemon/source-schedule.d.ts.map +1 -0
- package/dist/daemon/source-schedule.js +87 -0
- package/dist/daemon/source-schedule.js.map +1 -0
- package/dist/embedded-assets.generated.d.ts +4 -0
- package/dist/embedded-assets.generated.d.ts.map +1 -0
- package/dist/embedded-assets.generated.js +12 -0
- package/dist/embedded-assets.generated.js.map +1 -0
- package/dist/extractors/noise-filter.d.ts +30 -0
- package/dist/extractors/noise-filter.d.ts.map +1 -0
- package/dist/extractors/noise-filter.js +185 -0
- package/dist/extractors/noise-filter.js.map +1 -0
- package/dist/extractors/providers/anthropic.d.ts +13 -0
- package/dist/extractors/providers/anthropic.d.ts.map +1 -0
- package/dist/extractors/providers/anthropic.js +67 -0
- package/dist/extractors/providers/anthropic.js.map +1 -0
- package/dist/extractors/providers/index.d.ts +12 -0
- package/dist/extractors/providers/index.d.ts.map +1 -0
- package/dist/extractors/providers/index.js +41 -0
- package/dist/extractors/providers/index.js.map +1 -0
- package/dist/extractors/providers/mock.d.ts +14 -0
- package/dist/extractors/providers/mock.d.ts.map +1 -0
- package/dist/extractors/providers/mock.js +37 -0
- package/dist/extractors/providers/mock.js.map +1 -0
- package/dist/extractors/providers/openai.d.ts +15 -0
- package/dist/extractors/providers/openai.d.ts.map +1 -0
- package/dist/extractors/providers/openai.js +109 -0
- package/dist/extractors/providers/openai.js.map +1 -0
- package/dist/extractors/providers/types.d.ts +27 -0
- package/dist/extractors/providers/types.d.ts.map +1 -0
- package/dist/extractors/providers/types.js +6 -0
- package/dist/extractors/providers/types.js.map +1 -0
- package/dist/extractors/signal-extractor.d.ts +29 -0
- package/dist/extractors/signal-extractor.d.ts.map +1 -0
- package/dist/extractors/signal-extractor.js +279 -0
- package/dist/extractors/signal-extractor.js.map +1 -0
- package/dist/formatters/index.d.ts +3 -0
- package/dist/formatters/index.d.ts.map +1 -0
- package/dist/formatters/index.js +3 -0
- package/dist/formatters/index.js.map +1 -0
- package/dist/formatters/json.d.ts +6 -0
- package/dist/formatters/json.d.ts.map +1 -0
- package/dist/formatters/json.js +16 -0
- package/dist/formatters/json.js.map +1 -0
- package/dist/formatters/markdown.d.ts +6 -0
- package/dist/formatters/markdown.d.ts.map +1 -0
- package/dist/formatters/markdown.js +198 -0
- package/dist/formatters/markdown.js.map +1 -0
- package/dist/processors/privacy.d.ts +98 -0
- package/dist/processors/privacy.d.ts.map +1 -0
- package/dist/processors/privacy.js +271 -0
- package/dist/processors/privacy.js.map +1 -0
- package/dist/server/api.d.ts +35 -0
- package/dist/server/api.d.ts.map +1 -0
- package/dist/server/api.js +453 -0
- package/dist/server/api.js.map +1 -0
- package/dist/server/backfill-job.d.ts +36 -0
- package/dist/server/backfill-job.d.ts.map +1 -0
- package/dist/server/backfill-job.js +88 -0
- package/dist/server/backfill-job.js.map +1 -0
- package/dist/server/backfill-routes.d.ts +7 -0
- package/dist/server/backfill-routes.d.ts.map +1 -0
- package/dist/server/backfill-routes.js +123 -0
- package/dist/server/backfill-routes.js.map +1 -0
- package/dist/server/config-routes.d.ts +8 -0
- package/dist/server/config-routes.d.ts.map +1 -0
- package/dist/server/config-routes.js +114 -0
- package/dist/server/config-routes.js.map +1 -0
- package/dist/server/context.d.ts +13 -0
- package/dist/server/context.d.ts.map +1 -0
- package/dist/server/context.js +47 -0
- package/dist/server/context.js.map +1 -0
- package/dist/server/entity.d.ts +25 -0
- package/dist/server/entity.d.ts.map +1 -0
- package/dist/server/entity.js +34 -0
- package/dist/server/entity.js.map +1 -0
- package/dist/server/event-bus.d.ts +35 -0
- package/dist/server/event-bus.d.ts.map +1 -0
- package/dist/server/event-bus.js +4 -0
- package/dist/server/event-bus.js.map +1 -0
- package/dist/server/mcp.d.ts +126 -0
- package/dist/server/mcp.d.ts.map +1 -0
- package/dist/server/mcp.js +103 -0
- package/dist/server/mcp.js.map +1 -0
- package/dist/server/setup-server.d.ts +7 -0
- package/dist/server/setup-server.d.ts.map +1 -0
- package/dist/server/setup-server.js +52 -0
- package/dist/server/setup-server.js.map +1 -0
- package/dist/setup/assess-hardware.d.ts +34 -0
- package/dist/setup/assess-hardware.d.ts.map +1 -0
- package/dist/setup/assess-hardware.js +179 -0
- package/dist/setup/assess-hardware.js.map +1 -0
- package/dist/setup/connection-tests.d.ts +17 -0
- package/dist/setup/connection-tests.d.ts.map +1 -0
- package/dist/setup/connection-tests.js +67 -0
- package/dist/setup/connection-tests.js.map +1 -0
- package/dist/setup/detect-api-keys.d.ts +13 -0
- package/dist/setup/detect-api-keys.d.ts.map +1 -0
- package/dist/setup/detect-api-keys.js +41 -0
- package/dist/setup/detect-api-keys.js.map +1 -0
- package/dist/setup/detect-runtime.d.ts +14 -0
- package/dist/setup/detect-runtime.d.ts.map +1 -0
- package/dist/setup/detect-runtime.js +43 -0
- package/dist/setup/detect-runtime.js.map +1 -0
- package/dist/setup/detect-sources.d.ts +14 -0
- package/dist/setup/detect-sources.d.ts.map +1 -0
- package/dist/setup/detect-sources.js +75 -0
- package/dist/setup/detect-sources.js.map +1 -0
- package/dist/setup/generate-config.d.ts +5 -0
- package/dist/setup/generate-config.d.ts.map +1 -0
- package/dist/setup/generate-config.js +103 -0
- package/dist/setup/generate-config.js.map +1 -0
- package/dist/setup/index.d.ts +9 -0
- package/dist/setup/index.d.ts.map +1 -0
- package/dist/setup/index.js +9 -0
- package/dist/setup/index.js.map +1 -0
- package/dist/setup/init-wizard.d.ts +19 -0
- package/dist/setup/init-wizard.d.ts.map +1 -0
- package/dist/setup/init-wizard.js +501 -0
- package/dist/setup/init-wizard.js.map +1 -0
- package/dist/setup/terminal.d.ts +28 -0
- package/dist/setup/terminal.d.ts.map +1 -0
- package/dist/setup/terminal.js +258 -0
- package/dist/setup/terminal.js.map +1 -0
- package/dist/setup/validate-config.d.ts +26 -0
- package/dist/setup/validate-config.d.ts.map +1 -0
- package/dist/setup/validate-config.js +27 -0
- package/dist/setup/validate-config.js.map +1 -0
- package/dist/store/chunks.d.ts +19 -0
- package/dist/store/chunks.d.ts.map +1 -0
- package/dist/store/chunks.js +70 -0
- package/dist/store/chunks.js.map +1 -0
- package/dist/store/database.d.ts +24 -0
- package/dist/store/database.d.ts.map +1 -0
- package/dist/store/database.js +62 -0
- package/dist/store/database.js.map +1 -0
- package/dist/store/embedding.d.ts +23 -0
- package/dist/store/embedding.d.ts.map +1 -0
- package/dist/store/embedding.js +62 -0
- package/dist/store/embedding.js.map +1 -0
- package/dist/store/graph.d.ts +53 -0
- package/dist/store/graph.d.ts.map +1 -0
- package/dist/store/graph.js +186 -0
- package/dist/store/graph.js.map +1 -0
- package/dist/store/migrations/index.d.ts +9 -0
- package/dist/store/migrations/index.d.ts.map +1 -0
- package/dist/store/migrations/index.js +68 -0
- package/dist/store/migrations/index.js.map +1 -0
- package/dist/store/pages.d.ts +39 -0
- package/dist/store/pages.d.ts.map +1 -0
- package/dist/store/pages.js +150 -0
- package/dist/store/pages.js.map +1 -0
- package/dist/store/search.d.ts +37 -0
- package/dist/store/search.d.ts.map +1 -0
- package/dist/store/search.js +200 -0
- package/dist/store/search.js.map +1 -0
- package/dist/store/tags.d.ts +10 -0
- package/dist/store/tags.d.ts.map +1 -0
- package/dist/store/tags.js +31 -0
- package/dist/store/tags.js.map +1 -0
- package/dist/store/timeline.d.ts +26 -0
- package/dist/store/timeline.d.ts.map +1 -0
- package/dist/store/timeline.js +43 -0
- package/dist/store/timeline.js.map +1 -0
- package/dist/sync/obsidian.d.ts +136 -0
- package/dist/sync/obsidian.d.ts.map +1 -0
- package/dist/sync/obsidian.js +539 -0
- package/dist/sync/obsidian.js.map +1 -0
- package/package.json +84 -0
package/dist/cli.js
ADDED
|
@@ -0,0 +1,694 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { existsSync, mkdirSync } from "node:fs";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { resolve } from "node:path";
|
|
5
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
6
|
+
import { Command } from "commander";
|
|
7
|
+
import { createClaudeCodeCollector, createCodexCollector, createFeishuCollector, createHermesCollector, getAllCollectors, getCollector, registerCollector, resetRegistry, } from "./collectors/index.js";
|
|
8
|
+
import { Consolidator } from "./consolidator/consolidator.js";
|
|
9
|
+
import { loadConfig } from "./core/config.js";
|
|
10
|
+
import { runPipeline } from "./core/pipeline.js";
|
|
11
|
+
import { ensureStateDir, statePath } from "./core/state.js";
|
|
12
|
+
import { Scheduler } from "./daemon/scheduler.js";
|
|
13
|
+
import { VERSION } from "./embedded-assets.generated.js";
|
|
14
|
+
import { createLLMProvider, createMockProvider } from "./extractors/providers/index.js";
|
|
15
|
+
import { createApiApp } from "./server/api.js";
|
|
16
|
+
import { createMcpServer } from "./server/mcp.js";
|
|
17
|
+
import { ChunkStore } from "./store/chunks.js";
|
|
18
|
+
import { Database } from "./store/database.js";
|
|
19
|
+
import { EmbeddingService } from "./store/embedding.js";
|
|
20
|
+
import { GraphStore } from "./store/graph.js";
|
|
21
|
+
import { PageStore } from "./store/pages.js";
|
|
22
|
+
import { SearchEngine } from "./store/search.js";
|
|
23
|
+
import { TagStore } from "./store/tags.js";
|
|
24
|
+
import { TimelineStore } from "./store/timeline.js";
|
|
25
|
+
function bootstrapCollectors(sources) {
|
|
26
|
+
resetRegistry();
|
|
27
|
+
const agentConfigs = {
|
|
28
|
+
"claude-code": { factory: createClaudeCodeCollector, config: sources["claude-code"] },
|
|
29
|
+
codex: { factory: createCodexCollector, config: sources.codex },
|
|
30
|
+
hermes: { factory: createHermesCollector, config: sources.hermes },
|
|
31
|
+
};
|
|
32
|
+
for (const [_id, { factory, config }] of Object.entries(agentConfigs)) {
|
|
33
|
+
if (config?.enabled !== false) {
|
|
34
|
+
registerCollector(factory(config?.base_dir));
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (sources.feishu?.enabled !== false && sources.feishu?.app_id) {
|
|
38
|
+
registerCollector(createFeishuCollector(sources.feishu));
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function expandDataDir(dir) {
|
|
42
|
+
if (dir.startsWith("~/"))
|
|
43
|
+
return resolve(homedir(), dir.slice(2));
|
|
44
|
+
if (dir === "~")
|
|
45
|
+
return homedir();
|
|
46
|
+
return dir;
|
|
47
|
+
}
|
|
48
|
+
async function createStores(config) {
|
|
49
|
+
const dataDir = expandDataDir(config.store.data_dir);
|
|
50
|
+
mkdirSync(dataDir, { recursive: true });
|
|
51
|
+
const db = await Database.create(dataDir, {
|
|
52
|
+
embeddingDimensions: config.embedding.dimensions,
|
|
53
|
+
});
|
|
54
|
+
const pages = new PageStore(db.pg);
|
|
55
|
+
const chunks = new ChunkStore(db.pg);
|
|
56
|
+
const embedding = new EmbeddingService(db.pg, {
|
|
57
|
+
provider: config.embedding.provider,
|
|
58
|
+
model: config.embedding.model,
|
|
59
|
+
dimensions: config.embedding.dimensions,
|
|
60
|
+
apiKey: config.embedding.api_key ?? process.env.OPENAI_API_KEY,
|
|
61
|
+
baseUrl: config.embedding.base_url,
|
|
62
|
+
});
|
|
63
|
+
const search = new SearchEngine(db.pg, { embedText: (q) => embedding.embedText(q) });
|
|
64
|
+
return {
|
|
65
|
+
db,
|
|
66
|
+
pages,
|
|
67
|
+
chunks,
|
|
68
|
+
search,
|
|
69
|
+
graph: new GraphStore(db.pg),
|
|
70
|
+
tags: new TagStore(db.pg),
|
|
71
|
+
timeline: new TimelineStore(db.pg),
|
|
72
|
+
embedding,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
const program = new Command();
|
|
76
|
+
program
|
|
77
|
+
.name("memoark")
|
|
78
|
+
.description("Local-first personal memory extraction and storage")
|
|
79
|
+
.version(VERSION);
|
|
80
|
+
program
|
|
81
|
+
.command("init")
|
|
82
|
+
.description("Interactive setup wizard - generates memoark.yaml")
|
|
83
|
+
.option("--auto", "Automatic mode, no prompts")
|
|
84
|
+
.option("--force", "Overwrite existing configuration")
|
|
85
|
+
.option("-c, --config <path>", "Path to output config file (default: memoark.yaml)")
|
|
86
|
+
.option("--no-tui", "Use non-TUI fallback")
|
|
87
|
+
.option("--web", "Launch browser-based setup UI")
|
|
88
|
+
.action(async (options) => {
|
|
89
|
+
if (options.web) {
|
|
90
|
+
const { startSetupServer } = await import("./server/setup-server.js");
|
|
91
|
+
await startSetupServer({ configPath: options.config });
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
try {
|
|
95
|
+
const { runInit } = await import("./setup/index.js");
|
|
96
|
+
await runInit({
|
|
97
|
+
auto: options.auto,
|
|
98
|
+
force: options.force,
|
|
99
|
+
configPath: options.config,
|
|
100
|
+
tui: options.tui,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
105
|
+
process.exit(1);
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
/**
|
|
109
|
+
* Extract command - main pipeline execution
|
|
110
|
+
*/
|
|
111
|
+
program
|
|
112
|
+
.command("extract")
|
|
113
|
+
.description("Extract signals from a platform or source")
|
|
114
|
+
.option("-s, --source <name>", "Source/collector name (e.g., claude-code, codex, hermes, feishu, or 'all' for all enabled sources)", "claude-code")
|
|
115
|
+
.option("-c, --config <path>", "Path to config file (default: memoark.yaml)")
|
|
116
|
+
.option("-f, --format <type>", "Output format (json|markdown)", "json")
|
|
117
|
+
.option("-a, --adapter <type>", "Output adapter (store|file|gbrain|stdout)", "store")
|
|
118
|
+
.option("-o, --output <dir>", "Output directory for file adapter")
|
|
119
|
+
.option("--since <date>", "Only process messages since date (ISO 8601 or relative: 1d, 2h, 30m)")
|
|
120
|
+
.option("--limit <n>", "Limit number of messages to process", undefined)
|
|
121
|
+
.option("--dry-run", "Do not write outputs, only test pipeline")
|
|
122
|
+
.action(async (options) => {
|
|
123
|
+
try {
|
|
124
|
+
// Load configuration
|
|
125
|
+
const config = loadConfig(options.config);
|
|
126
|
+
// Ensure state directory exists
|
|
127
|
+
ensureStateDir();
|
|
128
|
+
// Bootstrap collectors from config
|
|
129
|
+
bootstrapCollectors(config.sources);
|
|
130
|
+
// Determine which sources to process
|
|
131
|
+
let sourceIds;
|
|
132
|
+
if (options.source === "all") {
|
|
133
|
+
sourceIds = getAllCollectors().map((c) => c.id);
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
sourceIds = [options.source];
|
|
137
|
+
}
|
|
138
|
+
// Create LLM provider based on config (shared across all sources)
|
|
139
|
+
let provider;
|
|
140
|
+
if (!options.dryRun) {
|
|
141
|
+
const llmConfig = config.llm;
|
|
142
|
+
const envKey = llmConfig.provider === "anthropic"
|
|
143
|
+
? process.env.ANTHROPIC_API_KEY
|
|
144
|
+
: process.env.OPENAI_API_KEY;
|
|
145
|
+
if (!llmConfig.api_key && !envKey) {
|
|
146
|
+
const envVarName = llmConfig.provider === "anthropic" ? "ANTHROPIC_API_KEY" : "OPENAI_API_KEY";
|
|
147
|
+
console.error(`Error: No API key configured. Set api_key in memoark.yaml or ${envVarName} env var.`);
|
|
148
|
+
process.exit(1);
|
|
149
|
+
}
|
|
150
|
+
if (!llmConfig.api_key) {
|
|
151
|
+
llmConfig.api_key = envKey;
|
|
152
|
+
}
|
|
153
|
+
provider = createLLMProvider(llmConfig);
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
provider = createMockProvider(new Map());
|
|
157
|
+
}
|
|
158
|
+
// Build pipeline configuration
|
|
159
|
+
const pipelineConfig = {
|
|
160
|
+
dedup_checkpoint: statePath("dedup.jsonl"),
|
|
161
|
+
cursor_checkpoint: statePath("cursors.yaml"),
|
|
162
|
+
block_gap_minutes: config.block_builder.block_gap_minutes,
|
|
163
|
+
max_block_tokens: config.block_builder.max_block_tokens,
|
|
164
|
+
max_block_messages: config.block_builder.max_block_messages,
|
|
165
|
+
privacy: config.privacy,
|
|
166
|
+
output_dir: options.output || process.cwd(),
|
|
167
|
+
block_concurrency: config.pipeline?.block_concurrency,
|
|
168
|
+
};
|
|
169
|
+
// Parse options
|
|
170
|
+
const format = ["json", "markdown"].includes(options.format) ? options.format : "json";
|
|
171
|
+
const adapter = ["store", "file", "gbrain", "stdout"].includes(options.adapter)
|
|
172
|
+
? options.adapter
|
|
173
|
+
: "store";
|
|
174
|
+
const limit = options.limit ? parseInt(options.limit, 10) : undefined;
|
|
175
|
+
// Create stores if using store adapter
|
|
176
|
+
let stores;
|
|
177
|
+
if (adapter === "store") {
|
|
178
|
+
stores = await createStores(config);
|
|
179
|
+
}
|
|
180
|
+
// Parse relative since values
|
|
181
|
+
let sinceValue = options.since;
|
|
182
|
+
if (sinceValue) {
|
|
183
|
+
const relMatch = sinceValue.match(/^(\d+)([dhm])$/);
|
|
184
|
+
if (relMatch) {
|
|
185
|
+
const amount = parseInt(relMatch[1], 10);
|
|
186
|
+
const unit = relMatch[2];
|
|
187
|
+
const ms = unit === "d" ? amount * 86400000 : unit === "h" ? amount * 3600000 : amount * 60000;
|
|
188
|
+
sinceValue = new Date(Date.now() - ms).toISOString();
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
let anyFailed = false;
|
|
192
|
+
// Process each source
|
|
193
|
+
for (const sourceId of sourceIds) {
|
|
194
|
+
const collector = getCollector(sourceId);
|
|
195
|
+
if (!collector) {
|
|
196
|
+
console.error(`Error: Unknown source '${sourceId}'`);
|
|
197
|
+
anyFailed = true;
|
|
198
|
+
continue;
|
|
199
|
+
}
|
|
200
|
+
// Health check
|
|
201
|
+
const health = await collector.healthCheck();
|
|
202
|
+
if (!health.ok) {
|
|
203
|
+
if (options.source === "all") {
|
|
204
|
+
console.warn(`Warning: ${sourceId} not available — ${health.message}. Skipping.`);
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
console.error(`Error: ${sourceId} health check failed — ${health.message}`);
|
|
208
|
+
process.exit(1);
|
|
209
|
+
}
|
|
210
|
+
// Run pipeline for this source
|
|
211
|
+
console.log(`\n--- Extracting from: ${sourceId} ---`);
|
|
212
|
+
console.log(`Format: ${format}, Adapter: ${adapter}`);
|
|
213
|
+
if (options.dryRun)
|
|
214
|
+
console.log("DRY-RUN mode enabled");
|
|
215
|
+
if (sinceValue)
|
|
216
|
+
console.log(`Since: ${sinceValue}`);
|
|
217
|
+
if (limit)
|
|
218
|
+
console.log(`Limit: ${limit} messages`);
|
|
219
|
+
console.log("");
|
|
220
|
+
try {
|
|
221
|
+
const result = await runPipeline(pipelineConfig, {
|
|
222
|
+
source: collector,
|
|
223
|
+
provider,
|
|
224
|
+
format: format,
|
|
225
|
+
adapter: adapter,
|
|
226
|
+
stores,
|
|
227
|
+
dryRun: options.dryRun || false,
|
|
228
|
+
since: sinceValue,
|
|
229
|
+
limit,
|
|
230
|
+
});
|
|
231
|
+
// Report results
|
|
232
|
+
console.log("Pipeline execution complete:");
|
|
233
|
+
console.log(` Total messages: ${result.totalMessages}`);
|
|
234
|
+
console.log(` Total blocks: ${result.totalBlocks}`);
|
|
235
|
+
console.log(` OK blocks: ${result.okBlocks}`);
|
|
236
|
+
console.log(` Skipped blocks: ${result.skippedBlocks}`);
|
|
237
|
+
console.log(` Failed blocks: ${result.failedBlocks}`);
|
|
238
|
+
if (result.warnings.length > 0) {
|
|
239
|
+
console.log("\nWarnings:");
|
|
240
|
+
for (const warning of result.warnings) {
|
|
241
|
+
console.log(` - ${warning}`);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
if (result.fatal) {
|
|
245
|
+
console.error(`\nFatal error: ${result.error}`);
|
|
246
|
+
anyFailed = true;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
catch (error) {
|
|
250
|
+
console.error(`\nPipeline failed for ${sourceId}:`, error instanceof Error ? error.message : String(error));
|
|
251
|
+
anyFailed = true;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
// Close stores if they were created
|
|
255
|
+
if (stores) {
|
|
256
|
+
await stores.db.close();
|
|
257
|
+
}
|
|
258
|
+
if (anyFailed) {
|
|
259
|
+
process.exit(1);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
catch (error) {
|
|
263
|
+
console.error("Extract failed:", error instanceof Error ? error.message : String(error));
|
|
264
|
+
process.exit(1);
|
|
265
|
+
}
|
|
266
|
+
});
|
|
267
|
+
/**
|
|
268
|
+
* Doctor command - diagnose configuration and setup
|
|
269
|
+
*/
|
|
270
|
+
program
|
|
271
|
+
.command("doctor")
|
|
272
|
+
.description("Diagnose configuration and connectivity")
|
|
273
|
+
.option("-c, --config <path>", "Path to config file (default: memoark.yaml)")
|
|
274
|
+
.action(async (options) => {
|
|
275
|
+
const issues = [];
|
|
276
|
+
const warnings = [];
|
|
277
|
+
const ok = [];
|
|
278
|
+
// Check config file
|
|
279
|
+
const configPath = options.config || resolve(process.cwd(), "memoark.yaml");
|
|
280
|
+
let config = null;
|
|
281
|
+
if (existsSync(configPath)) {
|
|
282
|
+
ok.push(`Configuration file found: ${configPath}`);
|
|
283
|
+
try {
|
|
284
|
+
config = loadConfig(options.config);
|
|
285
|
+
ok.push("Configuration loaded successfully");
|
|
286
|
+
}
|
|
287
|
+
catch (error) {
|
|
288
|
+
issues.push(`Configuration loading failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
else {
|
|
292
|
+
warnings.push(`Configuration file not found: ${configPath}`);
|
|
293
|
+
warnings.push("Create one with: memoark init");
|
|
294
|
+
}
|
|
295
|
+
// Check state directory
|
|
296
|
+
const stateDir = resolve(process.cwd(), ".memoark");
|
|
297
|
+
if (existsSync(stateDir)) {
|
|
298
|
+
ok.push(`State directory exists: ${stateDir}`);
|
|
299
|
+
}
|
|
300
|
+
else {
|
|
301
|
+
warnings.push(`State directory does not exist: ${stateDir}`);
|
|
302
|
+
warnings.push("It will be created automatically on first extract");
|
|
303
|
+
}
|
|
304
|
+
// Check LLM configuration
|
|
305
|
+
if (config) {
|
|
306
|
+
if (config.llm?.provider && config.llm?.model) {
|
|
307
|
+
ok.push(`LLM provider configured: ${config.llm.provider} / ${config.llm.model}`);
|
|
308
|
+
const envKey = config.llm.provider === "anthropic" ? "ANTHROPIC_API_KEY" : "OPENAI_API_KEY";
|
|
309
|
+
if (process.env[envKey] || config.llm.api_key) {
|
|
310
|
+
ok.push(`${config.llm.provider} API key configured`);
|
|
311
|
+
}
|
|
312
|
+
else {
|
|
313
|
+
warnings.push(`${envKey} environment variable not set and no api_key in config`);
|
|
314
|
+
warnings.push(`Set ${envKey} or add api_key to llm config`);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
else {
|
|
318
|
+
issues.push("LLM provider or model not configured");
|
|
319
|
+
}
|
|
320
|
+
// Check sources
|
|
321
|
+
bootstrapCollectors(config.sources);
|
|
322
|
+
for (const collector of getAllCollectors()) {
|
|
323
|
+
const health = await collector.healthCheck();
|
|
324
|
+
if (health.ok) {
|
|
325
|
+
ok.push(`Source ${collector.id}: ${health.message}`);
|
|
326
|
+
}
|
|
327
|
+
else {
|
|
328
|
+
warnings.push(`Source ${collector.id}: ${health.message}`);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
// Report results
|
|
333
|
+
console.log("=== Memoark Diagnostic Report ===\n");
|
|
334
|
+
if (ok.length > 0) {
|
|
335
|
+
console.log("✓ OK:");
|
|
336
|
+
for (const msg of ok) {
|
|
337
|
+
console.log(` ${msg}`);
|
|
338
|
+
}
|
|
339
|
+
console.log("");
|
|
340
|
+
}
|
|
341
|
+
if (warnings.length > 0) {
|
|
342
|
+
console.log("⚠ Warnings:");
|
|
343
|
+
for (const msg of warnings) {
|
|
344
|
+
console.log(` ${msg}`);
|
|
345
|
+
}
|
|
346
|
+
console.log("");
|
|
347
|
+
}
|
|
348
|
+
if (issues.length > 0) {
|
|
349
|
+
console.log("✗ Issues:");
|
|
350
|
+
for (const msg of issues) {
|
|
351
|
+
console.log(` ${msg}`);
|
|
352
|
+
}
|
|
353
|
+
console.log("");
|
|
354
|
+
process.exit(1);
|
|
355
|
+
}
|
|
356
|
+
console.log("No critical issues found.");
|
|
357
|
+
});
|
|
358
|
+
/**
|
|
359
|
+
* Config subcommand group
|
|
360
|
+
*/
|
|
361
|
+
const configCmd = program.command("config").description("Manage configuration");
|
|
362
|
+
configCmd
|
|
363
|
+
.command("init")
|
|
364
|
+
.description("Generate memoark.yaml (alias for 'memoark init')")
|
|
365
|
+
.option("--auto", "Automatic mode, no prompts")
|
|
366
|
+
.option("--force", "Overwrite existing configuration")
|
|
367
|
+
.option("-c, --config <path>", "Path to output config file (default: memoark.yaml)")
|
|
368
|
+
.option("--no-tui", "Use non-TUI fallback")
|
|
369
|
+
.action(async (options) => {
|
|
370
|
+
try {
|
|
371
|
+
const { runInit } = await import("./setup/index.js");
|
|
372
|
+
await runInit({
|
|
373
|
+
auto: options.auto,
|
|
374
|
+
force: options.force,
|
|
375
|
+
configPath: options.config,
|
|
376
|
+
tui: options.tui,
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
catch (error) {
|
|
380
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
381
|
+
process.exit(1);
|
|
382
|
+
}
|
|
383
|
+
});
|
|
384
|
+
configCmd
|
|
385
|
+
.command("edit")
|
|
386
|
+
.description("Edit configuration in browser UI")
|
|
387
|
+
.option("--web", "Launch browser-based settings UI (default behavior)")
|
|
388
|
+
.action(async () => {
|
|
389
|
+
const { startSetupServer } = await import("./server/setup-server.js");
|
|
390
|
+
await startSetupServer();
|
|
391
|
+
});
|
|
392
|
+
/**
|
|
393
|
+
* Sources subcommand group
|
|
394
|
+
*/
|
|
395
|
+
const sourcesCmd = program.command("sources").description("Manage data sources");
|
|
396
|
+
sourcesCmd
|
|
397
|
+
.command("list")
|
|
398
|
+
.description("List available sources")
|
|
399
|
+
.option("-c, --config <path>", "Path to config file")
|
|
400
|
+
.action((options) => {
|
|
401
|
+
const config = loadConfig(options.config);
|
|
402
|
+
bootstrapCollectors(config.sources);
|
|
403
|
+
const collectors = getAllCollectors();
|
|
404
|
+
console.log("Available sources:\n");
|
|
405
|
+
for (const c of collectors) {
|
|
406
|
+
console.log(` ${c.id} ✓ enabled`);
|
|
407
|
+
console.log(` ${c.description}`);
|
|
408
|
+
console.log("");
|
|
409
|
+
}
|
|
410
|
+
});
|
|
411
|
+
sourcesCmd
|
|
412
|
+
.command("test <name>")
|
|
413
|
+
.description("Test source connectivity and health")
|
|
414
|
+
.option("-c, --config <path>", "Path to config file")
|
|
415
|
+
.action(async (name, options) => {
|
|
416
|
+
try {
|
|
417
|
+
const config = loadConfig(options.config);
|
|
418
|
+
bootstrapCollectors(config.sources);
|
|
419
|
+
const collector = getCollector(name);
|
|
420
|
+
if (!collector) {
|
|
421
|
+
console.error(`Error: Unknown source '${name}'`);
|
|
422
|
+
process.exit(1);
|
|
423
|
+
}
|
|
424
|
+
console.log(`Testing source: ${name}\n`);
|
|
425
|
+
const health = await collector.healthCheck();
|
|
426
|
+
if (health.ok) {
|
|
427
|
+
console.log(`✓ ${health.message}`);
|
|
428
|
+
}
|
|
429
|
+
else {
|
|
430
|
+
console.log(`✗ ${health.message}`);
|
|
431
|
+
process.exit(1);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
catch (error) {
|
|
435
|
+
console.error("Test failed:", error instanceof Error ? error.message : String(error));
|
|
436
|
+
process.exit(1);
|
|
437
|
+
}
|
|
438
|
+
});
|
|
439
|
+
program
|
|
440
|
+
.command("serve")
|
|
441
|
+
.description("Start Memoark HTTP API or MCP stdio server")
|
|
442
|
+
.option("-c, --config <path>", "Path to config file")
|
|
443
|
+
.option("--mcp", "Run MCP stdio transport instead of HTTP")
|
|
444
|
+
.action(async (options) => {
|
|
445
|
+
const serveConfigPath = options.config ?? resolve(process.cwd(), "memoark.yaml");
|
|
446
|
+
if (!existsSync(serveConfigPath)) {
|
|
447
|
+
console.error("No configuration file found.\nRun `memoark init` (TUI) or `memoark init --web` (browser) to set up Memoark.");
|
|
448
|
+
process.exit(1);
|
|
449
|
+
}
|
|
450
|
+
const config = loadConfig(options.config);
|
|
451
|
+
const stateDir = ensureStateDir();
|
|
452
|
+
const stores = await createStores(config);
|
|
453
|
+
let scheduler;
|
|
454
|
+
if (config.scheduler?.enabled) {
|
|
455
|
+
bootstrapCollectors(config.sources);
|
|
456
|
+
const llmConfig = config.llm;
|
|
457
|
+
const envKey = llmConfig.provider === "anthropic"
|
|
458
|
+
? process.env.ANTHROPIC_API_KEY
|
|
459
|
+
: process.env.OPENAI_API_KEY;
|
|
460
|
+
if (!llmConfig.api_key && envKey)
|
|
461
|
+
llmConfig.api_key = envKey;
|
|
462
|
+
const provider = llmConfig.api_key
|
|
463
|
+
? createLLMProvider(llmConfig)
|
|
464
|
+
: createMockProvider(new Map());
|
|
465
|
+
const pipelineConfig = {
|
|
466
|
+
dedup_checkpoint: statePath("dedup.jsonl"),
|
|
467
|
+
cursor_checkpoint: statePath("cursors.yaml"),
|
|
468
|
+
block_gap_minutes: config.block_builder.block_gap_minutes,
|
|
469
|
+
max_block_tokens: config.block_builder.max_block_tokens,
|
|
470
|
+
max_block_messages: config.block_builder.max_block_messages,
|
|
471
|
+
privacy: config.privacy,
|
|
472
|
+
output_dir: process.cwd(),
|
|
473
|
+
block_concurrency: config.pipeline?.block_concurrency,
|
|
474
|
+
};
|
|
475
|
+
scheduler = new Scheduler(config.scheduler, stateDir);
|
|
476
|
+
scheduler.setRunSource(async (sourceId) => {
|
|
477
|
+
const collector = getCollector(sourceId);
|
|
478
|
+
if (!collector)
|
|
479
|
+
throw new Error(`Unknown source: ${sourceId}`);
|
|
480
|
+
return runPipeline(pipelineConfig, {
|
|
481
|
+
source: collector,
|
|
482
|
+
provider,
|
|
483
|
+
format: "json",
|
|
484
|
+
adapter: "store",
|
|
485
|
+
stores,
|
|
486
|
+
dryRun: false,
|
|
487
|
+
});
|
|
488
|
+
});
|
|
489
|
+
scheduler.setOnTick((sourceId, result, duration_ms) => {
|
|
490
|
+
const status = result.fatal ? "failed" : "ok";
|
|
491
|
+
console.log(`[scheduler] ${sourceId}: ${status} (${duration_ms}ms)`);
|
|
492
|
+
});
|
|
493
|
+
await scheduler.start();
|
|
494
|
+
}
|
|
495
|
+
const getDaemonStatus = scheduler
|
|
496
|
+
? () => {
|
|
497
|
+
const hb = scheduler?.getHeartbeat();
|
|
498
|
+
const now = Date.now();
|
|
499
|
+
let lastRunAt = null;
|
|
500
|
+
let nextAt = null;
|
|
501
|
+
for (const id of scheduler?.getSourceIds() ?? []) {
|
|
502
|
+
const s = scheduler?.getSourceState(id);
|
|
503
|
+
if (!s)
|
|
504
|
+
continue;
|
|
505
|
+
if (s.last_run_at !== null && (lastRunAt === null || s.last_run_at > lastRunAt)) {
|
|
506
|
+
lastRunAt = s.last_run_at;
|
|
507
|
+
}
|
|
508
|
+
const next = s.last_run_at !== null ? s.last_run_at + s.interval_secs * 1000 : now;
|
|
509
|
+
if (nextAt === null || next < nextAt)
|
|
510
|
+
nextAt = next;
|
|
511
|
+
}
|
|
512
|
+
return {
|
|
513
|
+
running: true,
|
|
514
|
+
uptime_seconds: Math.floor((now - (hb?.daemon_started_at ?? now)) / 1000),
|
|
515
|
+
last_run: lastRunAt ? new Date(lastRunAt).toISOString() : null,
|
|
516
|
+
next_scheduled: nextAt !== null ? new Date(nextAt).toISOString() : null,
|
|
517
|
+
};
|
|
518
|
+
}
|
|
519
|
+
: undefined;
|
|
520
|
+
const storesWithDaemon = { ...stores, getDaemonStatus };
|
|
521
|
+
const shutdown = () => {
|
|
522
|
+
scheduler?.stop();
|
|
523
|
+
};
|
|
524
|
+
process.on("SIGTERM", shutdown);
|
|
525
|
+
process.on("SIGINT", shutdown);
|
|
526
|
+
if (options.mcp) {
|
|
527
|
+
const server = createMcpServer(storesWithDaemon);
|
|
528
|
+
await server.connect(new StdioServerTransport());
|
|
529
|
+
return;
|
|
530
|
+
}
|
|
531
|
+
const app = createApiApp(storesWithDaemon);
|
|
532
|
+
const server = Bun.serve({ port: config.server.http_port, fetch: app.fetch });
|
|
533
|
+
console.log(`Memoark HTTP API listening on http://localhost:${server.port}`);
|
|
534
|
+
if (scheduler) {
|
|
535
|
+
console.log(`Scheduler running — tick every ${config.scheduler?.tick_interval_secs}s, sources: ${scheduler.getSourceIds().join(", ")}`);
|
|
536
|
+
}
|
|
537
|
+
});
|
|
538
|
+
program
|
|
539
|
+
.command("search <query>")
|
|
540
|
+
.description("Search Memoark memory")
|
|
541
|
+
.option("-c, --config <path>", "Path to config file")
|
|
542
|
+
.option("--mode <mode>", "Search mode (hybrid|fts)", "hybrid")
|
|
543
|
+
.option("--limit <n>", "Limit results", "20")
|
|
544
|
+
.action(async (query, options) => {
|
|
545
|
+
const stores = await createStores(loadConfig(options.config));
|
|
546
|
+
const limit = Number(options.limit);
|
|
547
|
+
const results = options.mode === "fts"
|
|
548
|
+
? await stores.search.search(query, { limit })
|
|
549
|
+
: await stores.search.query(query, { limit });
|
|
550
|
+
for (const result of results) {
|
|
551
|
+
console.log(`${result.slug}\t${result.score.toFixed(4)}\t${result.snippet.slice(0, 200)}`);
|
|
552
|
+
}
|
|
553
|
+
await stores.db.close();
|
|
554
|
+
});
|
|
555
|
+
program
|
|
556
|
+
.command("embed")
|
|
557
|
+
.description("Embed stale Memoark chunks")
|
|
558
|
+
.option("-c, --config <path>", "Path to config file")
|
|
559
|
+
.option("--limit <n>", "Limit chunks")
|
|
560
|
+
.action(async (options) => {
|
|
561
|
+
const stores = await createStores(loadConfig(options.config));
|
|
562
|
+
const result = await stores.embedding.embedStale({
|
|
563
|
+
limit: options.limit ? Number(options.limit) : undefined,
|
|
564
|
+
});
|
|
565
|
+
console.log(`Embedded ${result.embedded} chunks, errors ${result.errors}`);
|
|
566
|
+
await stores.db.close();
|
|
567
|
+
});
|
|
568
|
+
/**
|
|
569
|
+
* Obsidian sync — bidirectional export/import between PGLite and a vault.
|
|
570
|
+
* See docs/specs/memoark-2026-06-04-obsidian-sync.md
|
|
571
|
+
*/
|
|
572
|
+
program
|
|
573
|
+
.command("export")
|
|
574
|
+
.description("Export Memoark pages to an Obsidian vault (Markdown)")
|
|
575
|
+
.requiredOption("--vault <path>", "Obsidian vault directory")
|
|
576
|
+
.option("--force", "Ignore hash comparison, overwrite all files")
|
|
577
|
+
.option("--dry-run", "Print intended actions without writing")
|
|
578
|
+
.option("-c, --config <path>", "Path to config file")
|
|
579
|
+
.action(async (options) => {
|
|
580
|
+
const { exportToVault } = await import("./sync/obsidian.js");
|
|
581
|
+
const stores = await createStores(loadConfig(options.config));
|
|
582
|
+
try {
|
|
583
|
+
const result = await exportToVault(stores, options.vault, {
|
|
584
|
+
force: options.force,
|
|
585
|
+
dryRun: options.dryRun,
|
|
586
|
+
});
|
|
587
|
+
console.log(`Exported: ${result.written} written, ${result.skipped} skipped, ${result.errors.length} errors`);
|
|
588
|
+
for (const err of result.errors) {
|
|
589
|
+
console.error(` error: ${err.slug}: ${err.reason}`);
|
|
590
|
+
}
|
|
591
|
+
if (options.dryRun)
|
|
592
|
+
console.log("(dry-run: no files written)");
|
|
593
|
+
}
|
|
594
|
+
finally {
|
|
595
|
+
await stores.db.close();
|
|
596
|
+
}
|
|
597
|
+
});
|
|
598
|
+
program
|
|
599
|
+
.command("import")
|
|
600
|
+
.description("Import an Obsidian vault back into Memoark")
|
|
601
|
+
.requiredOption("--vault <path>", "Obsidian vault directory")
|
|
602
|
+
.option("--force", "Ignore hash comparison, import all files")
|
|
603
|
+
.option("--dry-run", "Print intended actions without writing")
|
|
604
|
+
.option("--strict-conflict", "Skip files where DB has changed since last sync instead of overwriting")
|
|
605
|
+
.option("-c, --config <path>", "Path to config file")
|
|
606
|
+
.action(async (options) => {
|
|
607
|
+
const { importFromVault } = await import("./sync/obsidian.js");
|
|
608
|
+
const stores = await createStores(loadConfig(options.config));
|
|
609
|
+
try {
|
|
610
|
+
const result = await importFromVault(stores, options.vault, {
|
|
611
|
+
force: options.force,
|
|
612
|
+
dryRun: options.dryRun,
|
|
613
|
+
strictConflict: options.strictConflict,
|
|
614
|
+
});
|
|
615
|
+
console.log(`Imported: ${result.imported} imported, ${result.skipped} skipped, ${result.errors.length} errors`);
|
|
616
|
+
for (const w of result.warnings) {
|
|
617
|
+
console.warn(` warn: ${w.slug}: ${w.reason}`);
|
|
618
|
+
}
|
|
619
|
+
for (const err of result.errors) {
|
|
620
|
+
console.error(` error: ${err.file}: ${err.reason}`);
|
|
621
|
+
}
|
|
622
|
+
if (!options.dryRun && result.imported > 0) {
|
|
623
|
+
console.log("Tip: Run 'memoark embed' to update embeddings for changed pages.");
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
finally {
|
|
627
|
+
await stores.db.close();
|
|
628
|
+
}
|
|
629
|
+
});
|
|
630
|
+
program
|
|
631
|
+
.command("consolidate")
|
|
632
|
+
.description("Run memory lifecycle tier rotation (hot→warm and/or warm→cold)")
|
|
633
|
+
.option("-c, --config <path>", "Path to config file (default: memoark.yaml)")
|
|
634
|
+
.option("--hot", "Run hot→warm rotation only")
|
|
635
|
+
.option("--warm", "Run warm→cold rotation only (requires LLM API key)")
|
|
636
|
+
.option("--dry-run", "Report what would be consolidated without writing")
|
|
637
|
+
.action(async (options) => {
|
|
638
|
+
try {
|
|
639
|
+
const config = loadConfig(options.config);
|
|
640
|
+
const stores = await createStores(config);
|
|
641
|
+
let llmProvider;
|
|
642
|
+
if (options.warm || (!options.hot && !options.warm)) {
|
|
643
|
+
const llmConfig = config.llm;
|
|
644
|
+
const envKey = llmConfig.provider === "anthropic"
|
|
645
|
+
? process.env.ANTHROPIC_API_KEY
|
|
646
|
+
: process.env.OPENAI_API_KEY;
|
|
647
|
+
const apiKey = llmConfig.api_key ?? envKey;
|
|
648
|
+
if (apiKey) {
|
|
649
|
+
if (!llmConfig.api_key)
|
|
650
|
+
llmConfig.api_key = apiKey;
|
|
651
|
+
llmProvider = createLLMProvider(llmConfig);
|
|
652
|
+
}
|
|
653
|
+
else if (options.warm) {
|
|
654
|
+
// Explicit --warm with no LLM key: fail fast
|
|
655
|
+
console.error("Error: --warm requires an LLM API key. Set ANTHROPIC_API_KEY or configure api_key in memoark.yaml.");
|
|
656
|
+
process.exit(1);
|
|
657
|
+
}
|
|
658
|
+
else {
|
|
659
|
+
// Full run with no LLM: skip warm→cold, run hot only
|
|
660
|
+
console.warn("Warning: no LLM API key found. Running hot→warm only. " +
|
|
661
|
+
"Set ANTHROPIC_API_KEY to enable warm→cold consolidation.");
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
const consolidator = new Consolidator({
|
|
665
|
+
pages: stores.pages,
|
|
666
|
+
graph: stores.graph,
|
|
667
|
+
tags: stores.tags,
|
|
668
|
+
timeline: stores.timeline,
|
|
669
|
+
}, llmProvider);
|
|
670
|
+
const mode = options.hot
|
|
671
|
+
? "hot"
|
|
672
|
+
: options.warm
|
|
673
|
+
? "warm"
|
|
674
|
+
: llmProvider
|
|
675
|
+
? "all"
|
|
676
|
+
: "hot"; // fall back to hot-only when full run has no LLM
|
|
677
|
+
const dryRun = options.dryRun ?? false;
|
|
678
|
+
if (dryRun)
|
|
679
|
+
console.log("DRY-RUN mode — no writes will occur\n");
|
|
680
|
+
const result = await consolidator.runOnce(mode, dryRun);
|
|
681
|
+
console.log("Consolidation complete:");
|
|
682
|
+
console.log(` hot→warm pages moved: ${result.hotToWarm}`);
|
|
683
|
+
console.log(` warm→cold pages archived: ${result.warmToCold}`);
|
|
684
|
+
console.log(` dead links checked: ${result.deadLinksChecked}`);
|
|
685
|
+
console.log(` preferences inferred: ${result.preferencesInferred}`);
|
|
686
|
+
await stores.db.close();
|
|
687
|
+
}
|
|
688
|
+
catch (error) {
|
|
689
|
+
console.error("Consolidate failed:", error instanceof Error ? error.message : String(error));
|
|
690
|
+
process.exit(1);
|
|
691
|
+
}
|
|
692
|
+
});
|
|
693
|
+
program.parse(process.argv);
|
|
694
|
+
//# sourceMappingURL=cli.js.map
|