From d94008f0fb3eb572f68f6b341ec58945d1cc4cc3 Mon Sep 17 00:00:00 2001 From: anian Date: Thu, 2 Jul 2026 19:14:14 +0800 Subject: [PATCH] =?UTF-8?q?0.29.1=E5=8E=9F=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .dockerignore | 13 + .gitignore | 33 + .golangci.yaml | 101 + .release-please-manifest.json | 3 + AGENTS.md | 106 + CHANGELOG.md | 183 + CODEOWNERS | 2 + LICENSE | 21 + README.md | 117 + SECURITY.md | 41 + .../definition.md | 35 + .../2026-03-23-memo-detail-outline/plan.md | 47 + .../definition.md | 98 + .../execution.md | 63 + .../2026-03-23-tag-blur-attribute/plan.md | 89 + .../definition.md | 41 + .../design.md | 63 + .../execution.md | 62 + .../plan.md | 106 + .../definition.md | 47 + .../2026-03-31-quick-voice-input/design.md | 58 + .../2026-03-31-quick-voice-input/execution.md | 40 + .../2026-03-31-quick-voice-input/plan.md | 63 + .../2026-04-06-memo-mentions/definition.md | 49 + docs/plans/2026-04-06-memo-mentions/design.md | 69 + .../2026-04-06-memo-mentions/execution.md | 37 + docs/plans/2026-04-06-memo-mentions/plan.md | 104 + .../definition.md | 70 + .../design.md | 173 + .../execution.md | 105 + .../plan.md | 328 + ...2026-05-02-activity-calendar-time-basis.md | 1018 +++ .../plans/2026-05-02-calendar-date-prefill.md | 738 ++ .../plans/2026-05-02-stt-audiollm-split.md | 1590 +++++ .../2026-05-02-transcription-settings.md | 1816 +++++ ...2026-05-12-first-screen-lazy-heavy-deps.md | 774 +++ .../plans/2026-05-12-placeholder-component.md | 776 +++ .../plans/2026-05-31-remove-react-use.md | 673 ++ ...-02-activity-calendar-time-basis-design.md | 124 + ...2026-05-02-calendar-date-prefill-design.md | 165 + .../2026-05-02-stt-audiollm-split-design.md | 511 ++ ...026-05-02-transcription-settings-design.md | 155 + ...-12-first-screen-lazy-heavy-deps-design.md | 113 + ...2026-05-12-placeholder-component-design.md | 282 + .../2026-05-31-remove-react-use-design.md | 82 + go.mod | 152 + go.sum | 361 + internal/ai/ai.go | 20 + internal/ai/audio/webm.go | 161 + internal/ai/audio/webm_test.go | 48 + internal/ai/audiollm/audiollm.go | 41 + internal/ai/audiollm/gemini/gemini.go | 202 + internal/ai/audiollm/gemini/gemini_test.go | 106 + internal/ai/audiollm/options.go | 34 + internal/ai/errors.go | 17 + internal/ai/models.go | 22 + internal/ai/resolver.go | 16 + internal/ai/stt/openai/openai.go | 116 + internal/ai/stt/openai/openai_test.go | 68 + internal/ai/stt/options.go | 34 + internal/ai/stt/stt.go | 41 + internal/base/resource_name.go | 7 + internal/base/resource_name_test.go | 37 + internal/cron/README.md | 1 + internal/cron/chain.go | 96 + internal/cron/chain_test.go | 252 + internal/cron/constantdelay.go | 27 + internal/cron/constantdelay_test.go | 55 + internal/cron/cron.go | 349 + internal/cron/cron_test.go | 705 ++ internal/cron/logger.go | 86 + internal/cron/option.go | 45 + internal/cron/option_test.go | 43 + internal/cron/parser.go | 446 ++ internal/cron/parser_test.go | 384 ++ internal/cron/spec.go | 188 + internal/cron/spec_test.go | 301 + internal/email/README.md | 507 ++ internal/email/client.go | 173 + internal/email/client_test.go | 121 + internal/email/config.go | 47 + internal/email/config_test.go | 80 + internal/email/doc.go | 98 + internal/email/email.go | 61 + internal/email/email_test.go | 127 + internal/email/message.go | 110 + internal/email/message_test.go | 204 + internal/filter/MAINTENANCE.md | 50 + internal/filter/README.md | 65 + internal/filter/engine.go | 118 + internal/filter/engine_test.go | 39 + internal/filter/helpers.go | 25 + internal/filter/ir.go | 166 + internal/filter/parser.go | 616 ++ internal/filter/render.go | 766 ++ internal/filter/schema.go | 335 + internal/httpgetter/html_meta.go | 227 + internal/httpgetter/html_meta_test.go | 189 + internal/httpgetter/http_getter.go | 1 + internal/httpgetter/image.go | 45 + internal/httpgetter/util.go | 15 + internal/idp/idp.go | 8 + internal/idp/oauth2/oauth2.go | 145 + internal/idp/oauth2/oauth2_test.go | 216 + internal/markdown/ast/mention.go | 28 + internal/markdown/ast/tag.go | 28 + internal/markdown/extensions/mention.go | 24 + internal/markdown/extensions/tag.go | 24 + internal/markdown/markdown.go | 472 ++ internal/markdown/markdown_test.go | 603 ++ internal/markdown/parser/mention.go | 87 + internal/markdown/parser/tag.go | 150 + internal/markdown/parser/tag_test.go | 263 + .../markdown/renderer/markdown_renderer.go | 270 + .../renderer/markdown_renderer_test.go | 176 + internal/motionphoto/motionphoto.go | 110 + internal/motionphoto/motionphoto_test.go | 25 + internal/profile/profile.go | 109 + internal/scheduler/README.md | 367 + internal/scheduler/doc.go | 35 + internal/scheduler/example_test.go | 165 + internal/scheduler/integration_test.go | 393 ++ internal/scheduler/job.go | 58 + internal/scheduler/job_test.go | 90 + internal/scheduler/middleware.go | 120 + internal/scheduler/middleware_test.go | 146 + internal/scheduler/parser.go | 229 + internal/scheduler/parser_test.go | 127 + internal/scheduler/scheduler.go | 202 + internal/scheduler/scheduler_test.go | 165 + internal/storage/s3/s3.go | 113 + internal/testutil/motionphoto.go | 18 + internal/util/util.go | 73 + internal/util/util_test.go | 31 + internal/version/version.go | 56 + internal/version/version_test.go | 106 + internal/webhook/validate.go | 83 + internal/webhook/webhook.go | 140 + internal/webhook/webhook_test.go | 13 + proto/README.md | 17 + proto/api/v1/README.md | 3 + proto/api/v1/ai_service.proto | 46 + proto/api/v1/attachment_service.proto | 185 + proto/api/v1/auth_service.proto | 115 + proto/api/v1/common.proto | 23 + proto/api/v1/idp_service.proto | 147 + proto/api/v1/instance_service.proto | 347 + proto/api/v1/memo_service.proto | 637 ++ proto/api/v1/shortcut_service.proto | 124 + proto/api/v1/user_service.proto | 843 +++ proto/buf.gen.yaml | 30 + proto/buf.lock | 6 + proto/buf.yaml | 19 + proto/gen/api/v1/ai_service.pb.go | 292 + proto/gen/api/v1/ai_service.pb.gw.go | 157 + proto/gen/api/v1/ai_service_grpc.pb.go | 123 + .../api/v1/apiv1connect/ai_service.connect.go | 110 + .../attachment_service.connect.go | 267 + .../v1/apiv1connect/auth_service.connect.go | 217 + .../v1/apiv1connect/idp_service.connect.go | 237 + .../apiv1connect/instance_service.connect.go | 267 + .../v1/apiv1connect/memo_service.connect.go | 698 ++ .../apiv1connect/shortcut_service.connect.go | 236 + .../v1/apiv1connect/user_service.connect.go | 857 +++ proto/gen/api/v1/attachment_service.pb.go | 872 +++ proto/gen/api/v1/attachment_service.pb.gw.go | 587 ++ .../gen/api/v1/attachment_service_grpc.pb.go | 324 + proto/gen/api/v1/auth_service.pb.go | 628 ++ proto/gen/api/v1/auth_service.pb.gw.go | 343 + proto/gen/api/v1/auth_service_grpc.pb.go | 258 + proto/gen/api/v1/common.pb.go | 244 + proto/gen/api/v1/idp_service.pb.go | 805 +++ proto/gen/api/v1/idp_service.pb.gw.go | 507 ++ proto/gen/api/v1/idp_service_grpc.pb.go | 285 + proto/gen/api/v1/instance_service.pb.go | 2045 ++++++ proto/gen/api/v1/instance_service.pb.gw.go | 541 ++ proto/gen/api/v1/instance_service_grpc.pb.go | 324 + proto/gen/api/v1/memo_service.pb.go | 2695 ++++++++ proto/gen/api/v1/memo_service.pb.gw.go | 1789 +++++ proto/gen/api/v1/memo_service_grpc.pb.go | 886 +++ proto/gen/api/v1/shortcut_service.pb.go | 496 ++ proto/gen/api/v1/shortcut_service.pb.gw.go | 543 ++ proto/gen/api/v1/shortcut_service_grpc.pb.go | 284 + proto/gen/api/v1/user_service.pb.go | 3633 ++++++++++ proto/gen/api/v1/user_service.pb.gw.go | 2279 ++++++ proto/gen/api/v1/user_service_grpc.pb.go | 1090 +++ proto/gen/openapi.yaml | 3956 +++++++++++ proto/gen/store/attachment.pb.go | 495 ++ proto/gen/store/idp.pb.go | 476 ++ proto/gen/store/inbox.pb.go | 351 + proto/gen/store/instance_setting.pb.go | 1499 ++++ proto/gen/store/memo.pb.go | 293 + proto/gen/store/user_setting.pb.go | 1005 +++ proto/store/attachment.proto | 56 + proto/store/idp.proto | 42 + proto/store/inbox.proto | 32 + proto/store/instance_setting.proto | 199 + proto/store/memo.proto | 29 + proto/store/user_setting.proto | 113 + release-please-config.json | 35 + scripts/Dockerfile | 56 + scripts/build.sh | 32 + scripts/compose.yaml | 8 + scripts/entrypoint.sh | 45 + scripts/entrypoint_test.sh | 131 + scripts/install.sh | 296 + server/auth/authenticator.go | 210 + server/auth/context.go | 99 + server/auth/extract.go | 33 + server/auth/token.go | 249 + server/auth/token_test.go | 306 + server/cors.go | 43 + server/cors_test.go | 122 + server/notification/email.go | 320 + server/router/api/v1/acl_config.go | 48 + server/router/api/v1/acl_config_test.go | 90 + server/router/api/v1/ai_service.go | 240 + server/router/api/v1/attachment_exif_test.go | 232 + server/router/api/v1/attachment_motion.go | 69 + server/router/api/v1/attachment_service.go | 831 +++ server/router/api/v1/auth_service.go | 796 +++ .../api/v1/auth_service_client_info_test.go | 228 + server/router/api/v1/common.go | 83 + server/router/api/v1/common_test.go | 46 + server/router/api/v1/connect_handler.go | 80 + server/router/api/v1/connect_interceptors.go | 246 + .../api/v1/connect_interceptors_test.go | 39 + server/router/api/v1/connect_services.go | 600 ++ server/router/api/v1/header_carrier.go | 124 + server/router/api/v1/health_service.go | 25 + server/router/api/v1/idp_service.go | 235 + server/router/api/v1/instance_service.go | 836 +++ server/router/api/v1/instance_stats.go | 165 + server/router/api/v1/instance_stats_test.go | 34 + server/router/api/v1/link_metadata_test.go | 103 + .../router/api/v1/memo_attachment_service.go | 241 + server/router/api/v1/memo_batch_helpers.go | 34 + server/router/api/v1/memo_mention_helpers.go | 146 + server/router/api/v1/memo_relation_service.go | 197 + server/router/api/v1/memo_service.go | 1048 +++ .../router/api/v1/memo_service_converter.go | 372 + server/router/api/v1/memo_service_filter.go | 1 + server/router/api/v1/memo_share_service.go | 226 + server/router/api/v1/memo_update_helpers.go | 78 + server/router/api/v1/notification_email.go | 28 + server/router/api/v1/reaction_service.go | 181 + server/router/api/v1/resource_name.go | 149 + server/router/api/v1/shortcut_service.go | 360 + server/router/api/v1/sse_event_helpers.go | 40 + server/router/api/v1/sse_handler.go | 123 + server/router/api/v1/sse_hub.go | 144 + server/router/api/v1/sse_hub_test.go | 251 + server/router/api/v1/sse_service_test.go | 314 + server/router/api/v1/sso_username.go | 20 + server/router/api/v1/test/ai_service_test.go | 284 + .../api/v1/test/attachment_service_test.go | 371 + .../router/api/v1/test/auth_service_test.go | 271 + server/router/api/v1/test/auth_test.go | 682 ++ server/router/api/v1/test/idp_service_test.go | 613 ++ .../api/v1/test/instance_admin_cache_test.go | 54 + .../api/v1/test/instance_service_test.go | 945 +++ .../router/api/v1/test/instance_stats_test.go | 72 + .../v1/test/memo_attachment_service_test.go | 346 + .../api/v1/test/memo_relation_service_test.go | 169 + .../v1/test/memo_service_benchmark_test.go | 282 + .../router/api/v1/test/memo_service_test.go | 732 ++ .../api/v1/test/memo_share_service_test.go | 263 + .../api/v1/test/reaction_service_test.go | 235 + .../api/v1/test/shortcut_service_test.go | 838 +++ server/router/api/v1/test/sse_handler_test.go | 135 + server/router/api/v1/test/test_helper.go | 91 + .../api/v1/test/user_email_visibility_test.go | 113 + .../api/v1/test/user_notification_test.go | 526 ++ .../api/v1/test/user_resource_name_test.go | 197 + server/router/api/v1/test/user_search_test.go | 71 + .../api/v1/test/user_service_delete_test.go | 489 ++ .../test/user_service_email_username_test.go | 259 + .../v1/test/user_service_registration_test.go | 387 ++ .../api/v1/test/user_service_stats_test.go | 202 + .../router/api/v1/test/user_setting_test.go | 58 + server/router/api/v1/user_resource_name.go | 59 + .../router/api/v1/user_resource_name_test.go | 116 + server/router/api/v1/user_service.go | 1908 +++++ server/router/api/v1/user_service_stats.go | 296 + server/router/api/v1/v1.go | 150 + server/router/fileserver/README.md | 304 + server/router/fileserver/fileserver.go | 764 ++ server/router/fileserver/fileserver_test.go | 435 ++ server/router/frontend/frontend.go | 189 + server/router/frontend/frontend_test.go | 233 + server/router/mcp/README.md | 167 + server/router/mcp/access.go | 117 + server/router/mcp/api_helpers.go | 74 + server/router/mcp/mcp.go | 251 + server/router/mcp/mcp_test.go | 605 ++ server/router/mcp/prompts.go | 192 + server/router/mcp/resources_memo.go | 88 + server/router/mcp/tool_metadata.go | 102 + server/router/mcp/tools_attachment.go | 327 + server/router/mcp/tools_memo.go | 607 ++ server/router/mcp/tools_reaction.go | 180 + server/router/mcp/tools_relation.go | 297 + server/router/mcp/tools_tag.go | 74 + server/router/rss/rss.go | 431 ++ server/router/rss/rss_test.go | 86 + server/runner/memopayload/runner.go | 88 + server/runner/s3presign/runner.go | 143 + server/runner/s3presign/runner_test.go | 34 + server/server.go | 241 + store/attachment.go | 298 + store/cache.go | 9 + store/cache/cache.go | 327 + store/cache/cache_test.go | 209 + store/common.go | 24 + store/db/db.go | 32 + store/db/mysql/attachment.go | 274 + store/db/mysql/common.go | 10 + store/db/mysql/idp.go | 130 + store/db/mysql/inbox.go | 150 + store/db/mysql/instance_setting.go | 65 + store/db/mysql/memo.go | 270 + store/db/mysql/memo_relation.go | 146 + store/db/mysql/memo_share.go | 121 + store/db/mysql/mysql.go | 80 + store/db/mysql/reaction.go | 113 + store/db/mysql/user.go | 194 + store/db/mysql/user_delete.go | 569 ++ store/db/mysql/user_delete_test.go | 11 + store/db/mysql/user_identity.go | 107 + store/db/mysql/user_setting.go | 109 + store/db/postgres/attachment.go | 254 + store/db/postgres/common.go | 26 + store/db/postgres/idp.go | 123 + store/db/postgres/inbox.go | 151 + store/db/postgres/instance_setting.go | 72 + store/db/postgres/memo.go | 255 + store/db/postgres/memo_relation.go | 173 + store/db/postgres/memo_share.go | 142 + store/db/postgres/postgres.go | 67 + store/db/postgres/reaction.go | 101 + store/db/postgres/user.go | 192 + store/db/postgres/user_delete.go | 532 ++ store/db/postgres/user_identity.go | 95 + store/db/postgres/user_setting.go | 137 + store/db/postgres/user_setting_test.go | 290 + store/db/sqlite/attachment.go | 254 + store/db/sqlite/common.go | 9 + store/db/sqlite/functions.go | 44 + store/db/sqlite/idp.go | 123 + store/db/sqlite/inbox.go | 141 + store/db/sqlite/instance_setting.go | 72 + store/db/sqlite/memo.go | 248 + store/db/sqlite/memo_relation.go | 159 + store/db/sqlite/memo_share.go | 144 + store/db/sqlite/reaction.go | 136 + store/db/sqlite/sqlite.go | 87 + store/db/sqlite/user.go | 202 + store/db/sqlite/user_delete.go | 532 ++ store/db/sqlite/user_identity.go | 95 + store/db/sqlite/user_setting.go | 125 + store/driver.go | 84 + store/idp.go | 186 + store/inbox.go | 75 + store/instance_setting.go | 327 + store/memo.go | 159 + store/memo_relation.go | 53 + store/memo_share.go | 47 + store/migration/mysql/0.17/00__inbox.sql | 9 + .../mysql/0.17/01__delete_activity.sql | 1 + .../migration/mysql/0.18/00__extend_text.sql | 3 + store/migration/mysql/0.18/01__webhook.sql | 10 + .../migration/mysql/0.18/02__user_setting.sql | 4 + .../mysql/0.19/00__add_resource_name.sql | 15 + store/migration/mysql/0.20/00__reaction.sql | 9 + .../mysql/0.21/00__user_description.sql | 1 + store/migration/mysql/0.21/01__rename_uid.sql | 3 + .../mysql/0.22/00__resource_storage_type.sql | 11 + store/migration/mysql/0.22/01__memo_tags.sql | 3 + .../migration/mysql/0.22/02__memo_payload.sql | 3 + store/migration/mysql/0.22/03__drop_tag.sql | 1 + store/migration/mysql/0.23/00__reactions.sql | 12 + store/migration/mysql/0.24/00__memo.sql | 2 + .../migration/mysql/0.24/01__memo_pinned.sql | 8 + .../mysql/0.24/02__s3_reference_length.sql | 2 + .../mysql/0.25/00__remove_webhook.sql | 1 + .../00__rename_resource_to_attachment.sql | 1 + .../mysql/0.26/01__drop_memo_organizer.sql | 1 + .../mysql/0.26/02__migrate_host_to_admin.sql | 1 + .../0.27/00__migrate_storage_setting.sql | 6 + .../migration/mysql/0.27/01__add_idp_uid.sql | 8 + .../02__migrate_inbox_message_payload.sql | 14 + .../mysql/0.27/03__drop_activity.sql | 1 + store/migration/mysql/0.27/04__memo_share.sql | 14 + .../mysql/0.28/00__user_identity.sql | 15 + store/migration/mysql/LATEST.sql | 125 + .../postgres/0.19/00__add_resource_name.sql | 15 + .../migration/postgres/0.20/00__reaction.sql | 9 + .../postgres/0.21/00__user_description.sql | 1 + .../postgres/0.21/01__rename_uid.sql | 3 + .../0.22/00__resource_storage_type.sql | 11 + .../migration/postgres/0.22/01__memo_tags.sql | 1 + .../postgres/0.22/02__memo_payload.sql | 1 + .../migration/postgres/0.22/03__drop_tag.sql | 1 + .../migration/postgres/0.23/00__reactions.sql | 12 + store/migration/postgres/0.24/00__memo.sql | 2 + .../postgres/0.24/01__memo_pinned.sql | 8 + .../postgres/0.25/00__remove_webhook.sql | 1 + .../00__rename_resource_to_attachment.sql | 1 + .../postgres/0.26/01__drop_memo_organizer.sql | 1 + .../0.26/02__migrate_host_to_admin.sql | 1 + .../0.27/00__migrate_storage_setting.sql | 5 + .../postgres/0.27/01__add_idp_uid.sql | 8 + .../02__migrate_inbox_message_payload.sql | 13 + .../postgres/0.27/03__drop_activity.sql | 1 + .../postgres/0.27/04__memo_share.sql | 14 + .../postgres/0.28/00__user_identity.sql | 15 + store/migration/postgres/LATEST.sql | 125 + store/migration/sqlite/0.10/00__activity.sql | 9 + .../migration/sqlite/0.11/00__user_avatar.sql | 4 + store/migration/sqlite/0.11/01__idp.sql | 8 + store/migration/sqlite/0.11/02__storage.sql | 7 + .../sqlite/0.12/00__user_setting.sql | 6 + .../sqlite/0.12/01__system_setting.sql | 69 + .../0.12/03__resource_internal_path.sql | 4 + .../sqlite/0.12/04__resource_public_id.sql | 18 + .../sqlite/0.13/00__memo_relation.sql | 7 + .../0.13/01__remove_memo_organizer_id.sql | 22 + .../0.14/00__drop_resource_public_id.sql | 25 + .../sqlite/0.14/01__create_indexes.sql | 5 + .../sqlite/0.15/00__drop_user_open_id.sql | 25 + .../0.16/00__add_memo_id_to_resource.sql | 13 + .../sqlite/0.16/01__drop_shortcut_table.sql | 1 + store/migration/sqlite/0.17/00__inbox.sql | 9 + .../sqlite/0.17/01__delete_activities.sql | 1 + store/migration/sqlite/0.18/00__webhook.sql | 12 + .../sqlite/0.18/01__user_setting.sql | 4 + .../sqlite/0.19/00__add_resource_name.sql | 11 + store/migration/sqlite/0.2/00__user_role.sql | 60 + .../sqlite/0.2/01__memo_visibility.sql | 4 + store/migration/sqlite/0.20/00__reaction.sql | 9 + .../sqlite/0.21/00__user_description.sql | 1 + .../migration/sqlite/0.21/01__rename_uid.sql | 3 + .../sqlite/0.22/00__resource_storage_type.sql | 17 + store/migration/sqlite/0.22/01__memo_tags.sql | 3 + .../sqlite/0.22/02__memo_payload.sql | 1 + store/migration/sqlite/0.22/03__drop_tag.sql | 1 + store/migration/sqlite/0.23/00__reactions.sql | 12 + store/migration/sqlite/0.24/00__memo.sql | 7 + .../migration/sqlite/0.24/01__memo_pinned.sql | 11 + .../sqlite/0.25/00__remove_webhook.sql | 1 + .../00__rename_resource_to_attachment.sql | 5 + .../sqlite/0.26/01__drop_memo_organizer.sql | 1 + .../sqlite/0.26/02__drop_indexes.sql | 4 + .../sqlite/0.26/03__alter_user_role.sql | 24 + .../sqlite/0.26/04__migrate_host_to_admin.sql | 1 + .../0.27/00__migrate_storage_setting.sql | 5 + .../migration/sqlite/0.27/01__add_idp_uid.sql | 8 + .../02__migrate_inbox_message_payload.sql | 25 + .../sqlite/0.27/03__drop_activity.sql | 1 + .../migration/sqlite/0.27/04__memo_share.sql | 14 + .../sqlite/0.28/00__user_identity.sql | 15 + .../0.3/00__memo_visibility_protected.sql | 43 + .../migration/sqlite/0.4/00__user_setting.sql | 9 + .../0.5/00__regenerate_foreign_keys.sql | 217 + .../sqlite/0.5/01__memo_resource.sql | 10 + .../sqlite/0.5/02__system_setting.sql | 7 + .../sqlite/0.5/03__resource_extermal_link.sql | 4 + .../sqlite/0.6/00__recreate_triggers.sql | 59 + store/migration/sqlite/0.7/00__remove_fk.sql | 191 + .../sqlite/0.7/01__remove_triggers.sql | 7 + .../sqlite/0.8/00__migration_history.sql | 5 + .../sqlite/0.8/01__user_username.sql | 50 + store/migration/sqlite/0.9/00__tag.sql | 6 + store/migration/sqlite/LATEST.sql | 126 + store/migrator.go | 413 ++ store/reaction.go | 41 + store/seed/sqlite/01__dump.sql | 57 + store/store.go | 65 + store/test/README.md | 13 + store/test/attachment_filter_test.go | 375 + store/test/attachment_test.go | 305 + store/test/containers.go | 382 + store/test/database_size_test.go | 19 + store/test/filter_helpers_test.go | 290 + store/test/idp_test.go | 468 ++ store/test/inbox_test.go | 613 ++ store/test/instance_setting_test.go | 459 ++ store/test/main_test.go | 50 + store/test/memo_filter_test.go | 990 +++ store/test/memo_relation_test.go | 946 +++ store/test/memo_test.go | 478 ++ store/test/migrator_test.go | 196 + store/test/migrator_upgrade_test.go | 271 + store/test/reaction_test.go | 189 + store/test/store.go | 111 + store/test/user_delete_test.go | 248 + store/test/user_identity_test.go | 199 + store/test/user_setting_test.go | 993 +++ store/test/user_test.go | 278 + store/user.go | 179 + store/user_delete.go | 47 + store/user_identity.go | 59 + store/user_setting.go | 508 ++ web/.gitignore | 7 + web/biome.json | 202 + web/components.json | 21 + web/docs/auth-architecture.md | 55 + web/index.html | 24 + web/package.json | 110 + web/pnpm-lock.yaml | 6143 +++++++++++++++++ web/pnpm-workspace.yaml | 2 + web/public/android-chrome-192x192.png | Bin 0 -> 25014 bytes web/public/android-chrome-512x512.png | Bin 0 -> 141510 bytes web/public/apple-touch-icon.png | Bin 0 -> 22496 bytes web/public/full-logo.webp | Bin 0 -> 25152 bytes web/public/logo.webp | Bin 0 -> 37158 bytes web/public/site.webmanifest | 14 + web/src/App.tsx | 66 + web/src/auth-state.ts | 128 + .../ActivityCalendar/CalendarCell.tsx | 81 + .../ActivityCalendar/MonthCalendar.tsx | 87 + .../ActivityCalendar/YearCalendar.tsx | 118 + .../components/ActivityCalendar/constants.ts | 34 + web/src/components/ActivityCalendar/hooks.ts | 23 + web/src/components/ActivityCalendar/index.ts | 4 + web/src/components/ActivityCalendar/types.ts | 43 + .../ActivityCalendar/useCalendar.ts | 90 + web/src/components/ActivityCalendar/utils.ts | 75 + web/src/components/AttachmentIcon.tsx | 108 + .../AttachmentLibrary/AttachmentFileRows.tsx | 129 + .../AttachmentLibraryEmptyState.tsx | 57 + .../AttachmentLibraryPrimitives.tsx | 90 + .../AttachmentLibraryStates.tsx | 77 + .../AttachmentLibraryToolbar.tsx | 64 + .../AttachmentLibrary/AttachmentMediaGrid.tsx | 97 + web/src/components/AttachmentLibrary/index.ts | 6 + web/src/components/AuthFooter.tsx | 35 + .../components/ChangeMemberPasswordDialog.tsx | 114 + web/src/components/ConfirmDialog/README.md | 131 + web/src/components/ConfirmDialog/index.tsx | 59 + .../components/CreateAccessTokenDialog.tsx | 183 + .../CreateIdentityProviderDialog.tsx | 615 ++ web/src/components/CreateUserDialog.tsx | 150 + web/src/components/CreateWebhookDialog.tsx | 166 + web/src/components/DateTimeInput.tsx | 43 + web/src/components/ErrorBoundary.tsx | 103 + .../components/Inbox/MemoCommentMessage.tsx | 158 + .../components/Inbox/MemoMentionMessage.tsx | 164 + web/src/components/LearnMore.tsx | 31 + web/src/components/LocaleSelect.tsx | 41 + .../MemoActionMenu/MemoActionMenu.tsx | 165 + .../MemoActionMenu/MemoShareImageDialog.tsx | 137 + .../MemoActionMenu/MemoShareImagePreview.tsx | 87 + web/src/components/MemoActionMenu/hooks.ts | 163 + web/src/components/MemoActionMenu/index.ts | 3 + .../MemoActionMenu/memoShareImage.ts | 117 + .../memoShareImagePreviewModel.ts | 58 + web/src/components/MemoActionMenu/types.ts | 8 + web/src/components/MemoCommentSection.tsx | 79 + web/src/components/MemoContent/CodeBlock.tsx | 156 + .../MemoContent/LinkMetadataCard.tsx | 70 + .../MemoContent/MarkdownRenderContext.tsx | 22 + .../MemoContent/MemoMarkdownRenderer.tsx | 148 + web/src/components/MemoContent/Mention.tsx | 40 + .../MemoContent/MentionResolutionContext.tsx | 41 + .../components/MemoContent/MermaidBlock.tsx | 101 + web/src/components/MemoContent/Table.tsx | 77 + web/src/components/MemoContent/Tag.tsx | 81 + .../components/MemoContent/TaskListItem.tsx | 70 + .../components/MemoContent/TrustedIframe.ts | 14 + web/src/components/MemoContent/constants.ts | 73 + web/src/components/MemoContent/hooks.ts | 28 + web/src/components/MemoContent/index.tsx | 70 + .../MemoContent/markdown/Blockquote.tsx | 18 + .../MemoContent/markdown/Heading.tsx | 31 + .../MemoContent/markdown/HorizontalRule.tsx | 11 + .../components/MemoContent/markdown/Image.tsx | 19 + .../MemoContent/markdown/InlineCode.tsx | 17 + .../components/MemoContent/markdown/Link.tsx | 27 + .../components/MemoContent/markdown/List.tsx | 129 + .../MemoContent/markdown/Paragraph.tsx | 60 + .../components/MemoContent/markdown/README.md | 19 + .../components/MemoContent/markdown/index.ts | 8 + .../components/MemoContent/markdown/types.ts | 9 + web/src/components/MemoContent/types.ts | 12 + web/src/components/MemoContent/utils.ts | 25 + .../MemoDetailSidebar/MemoDetailSidebar.tsx | 139 + .../MemoDetailSidebarDrawer.tsx | 36 + .../MemoDetailSidebar/MemoOutline.tsx | 52 + .../MemoDetailSidebar/MemoSharePanel.tsx | 158 + web/src/components/MemoDetailSidebar/index.ts | 4 + web/src/components/MemoDisplaySettingMenu.tsx | 61 + .../MemoEditor/Editor/SlashCommands.tsx | 45 + .../MemoEditor/Editor/SuggestionsPopup.tsx | 49 + .../MemoEditor/Editor/TagSuggestions.tsx | 50 + .../components/MemoEditor/Editor/commands.ts | 28 + .../components/MemoEditor/Editor/index.tsx | 236 + .../components/MemoEditor/Editor/shortcuts.ts | 80 + .../MemoEditor/Editor/useListCompletion.ts | 82 + .../MemoEditor/Editor/useSuggestions.ts | 165 + web/src/components/MemoEditor/README.md | 73 + .../MemoEditor/Toolbar/InsertMenu.tsx | 256 + .../MemoEditor/Toolbar/VisibilitySelector.tsx | 42 + .../components/MemoEditor/Toolbar/index.ts | 3 + .../components/AudioRecorderPanel.tsx | 100 + .../MemoEditor/components/EditorContent.tsx | 77 + .../MemoEditor/components/EditorMetadata.tsx | 30 + .../MemoEditor/components/EditorToolbar.tsx | 57 + .../components/FocusModeOverlay.tsx | 20 + .../components/TimestampPopover.tsx | 89 + .../MemoEditor/components/VoiceWaveform.tsx | 34 + .../components/MemoEditor/components/index.ts | 8 + web/src/components/MemoEditor/constants.ts | 14 + web/src/components/MemoEditor/hooks/index.ts | 12 + .../MemoEditor/hooks/useAudioRecorder.ts | 241 + .../MemoEditor/hooks/useAudioWaveform.ts | 99 + .../MemoEditor/hooks/useAutoSave.ts | 58 + .../MemoEditor/hooks/useBlobUrls.ts | 28 + .../MemoEditor/hooks/useDragAndDrop.ts | 21 + .../MemoEditor/hooks/useFileUpload.ts | 94 + .../MemoEditor/hooks/useFocusMode.ts | 10 + .../MemoEditor/hooks/useKeyboard.ts | 32 + .../MemoEditor/hooks/useLinkMemo.ts | 89 + .../MemoEditor/hooks/useLocation.ts | 87 + .../MemoEditor/hooks/useMemoInit.ts | 60 + web/src/components/MemoEditor/index.tsx | 355 + .../MemoEditor/services/cacheService.ts | 83 + .../MemoEditor/services/errorService.ts | 18 + .../components/MemoEditor/services/index.ts | 6 + .../MemoEditor/services/memoService.ts | 154 + .../services/transcriptionService.ts | 23 + .../MemoEditor/services/uploadService.ts | 30 + .../MemoEditor/services/validationService.ts | 37 + .../components/MemoEditor/state/actions.ts | 108 + .../components/MemoEditor/state/context.tsx | 40 + web/src/components/MemoEditor/state/index.ts | 4 + .../components/MemoEditor/state/reducer.ts | 182 + web/src/components/MemoEditor/state/types.ts | 93 + .../components/MemoEditor/types/attachment.ts | 199 + .../components/MemoEditor/types/components.ts | 100 + web/src/components/MemoEditor/types/index.ts | 16 + .../MemoEditor/types/insert-menu.ts | 8 + .../utils/deriveDefaultCreateTime.ts | 26 + .../components/MemoExplorer/MemoExplorer.tsx | 87 + .../MemoExplorer/MemoExplorerDrawer.tsx | 42 + .../MemoExplorer/ShortcutsSection.tsx | 118 + .../components/MemoExplorer/TagsSection.tsx | 100 + web/src/components/MemoExplorer/index.ts | 5 + web/src/components/MemoFilters.tsx | 106 + .../Attachment/AttachmentCard.tsx | 45 + .../Attachment/AttachmentListEditor.tsx | 360 + .../Attachment/AttachmentListView.tsx | 278 + .../Attachment/AudioAttachmentItem.tsx | 190 + .../Attachment/attachmentHelpers.ts | 61 + .../Attachment/attachmentVisualClasses.ts | 33 + .../MemoMetadata/Attachment/index.ts | 4 + .../Attachment/visualGalleryLayout.ts | 72 + .../MemoMetadata/Location/LocationDialog.tsx | 113 + .../Location/LocationDisplayEditor.tsx | 47 + .../Location/LocationDisplayView.tsx | 50 + .../components/MemoMetadata/Location/index.ts | 3 + .../MemoMetadata/Location/locationHelpers.ts | 9 + .../MemoMetadata/MetadataSection.tsx | 24 + .../MemoMetadata/Relation/LinkMemoDialog.tsx | 90 + .../MemoMetadata/Relation/RelationCard.tsx | 16 + .../Relation/RelationListEditor.tsx | 71 + .../Relation/RelationListView.tsx | 78 + .../components/MemoMetadata/Relation/index.ts | 4 + .../MemoMetadata/Relation/relationHelpers.ts | 42 + .../Relation/useResolvedRelationMemos.ts | 62 + .../components/MemoMetadata/SectionHeader.tsx | 51 + web/src/components/MemoMetadata/index.ts | 7 + .../components/MemoPreview/MemoPreview.tsx | 160 + web/src/components/MemoPreview/index.ts | 1 + .../MemoReactionListView.tsx | 34 + .../MemoReactionListView/ReactionSelector.tsx | 63 + .../MemoReactionListView/ReactionView.tsx | 58 + .../components/MemoReactionListView/hooks.ts | 82 + .../components/MemoReactionListView/index.ts | 3 + web/src/components/MemoView/MemoView.tsx | 155 + .../components/MemoView/MemoViewContext.tsx | 66 + .../MemoView/components/MemoBody.tsx | 69 + .../components/MemoCommentListView.tsx | 58 + .../MemoView/components/MemoHeader.tsx | 170 + .../MemoView/components/MemoSnippetLink.tsx | 34 + .../components/MemoView/components/index.ts | 3 + web/src/components/MemoView/constants.ts | 4 + web/src/components/MemoView/hooks/index.ts | 3 + .../MemoView/hooks/useImagePreview.ts | 55 + .../MemoView/hooks/useMemoActions.ts | 13 + .../MemoView/hooks/useMemoHandlers.ts | 40 + web/src/components/MemoView/index.ts | 2 + web/src/components/MemoView/types.ts | 23 + web/src/components/MemosLogo.tsx | 26 + web/src/components/MobileHeader.tsx | 46 + web/src/components/MotionPhotoPlayer.tsx | 120 + web/src/components/MotionPhotoPreview.tsx | 88 + web/src/components/Navigation.tsx | 134 + web/src/components/NavigationDrawer.tsx | 38 + .../PagedMemoList/PagedMemoList.tsx | 228 + web/src/components/PagedMemoList/index.ts | 3 + web/src/components/PasswordSignInForm.tsx | 120 + .../Placeholder/TileSpriteStrip.tsx | 67 + web/src/components/Placeholder/index.tsx | 34 + web/src/components/Placeholder/messages.ts | 10 + .../components/Placeholder/pieces/DESIGN.md | 49 + .../Placeholder/pieces/EagleIdle.svg | 122 + .../Placeholder/pieces/OwlBlink.svg | 85 + .../Placeholder/pieces/ToucanIdle.svg | 87 + web/src/components/Placeholder/tileSprites.ts | 43 + web/src/components/PreviewImageDialog.tsx | 331 + web/src/components/RequiredBadge.tsx | 11 + web/src/components/SearchBar.tsx | 51 + web/src/components/Settings/AISection.tsx | 547 ++ .../Settings/AccessTokenSection.tsx | 147 + web/src/components/Settings/InfoChip.tsx | 42 + .../components/Settings/InstanceSection.tsx | 180 + .../Settings/LinkedIdentitySection.tsx | 208 + web/src/components/Settings/MemberSection.tsx | 229 + .../Settings/MemoRelatedSettings.tsx | 153 + .../components/Settings/MyAccountSection.tsx | 114 + .../Settings/NotificationSection.tsx | 308 + .../Settings/PreferencesSection.tsx | 118 + .../Settings/ResourceStatsSection.tsx | 104 + web/src/components/Settings/SSOSection.tsx | 202 + .../components/Settings/SectionMenuItem.tsx | 25 + web/src/components/Settings/SettingGroup.tsx | 36 + web/src/components/Settings/SettingList.tsx | 95 + web/src/components/Settings/SettingRow.tsx | 47 + .../components/Settings/SettingSection.tsx | 33 + web/src/components/Settings/SettingTable.tsx | 80 + .../components/Settings/StorageSection.tsx | 347 + web/src/components/Settings/TagsSection.tsx | 284 + .../components/Settings/WebhookSection.tsx | 121 + .../components/Settings/settingSections.ts | 151 + .../Settings/useInstanceSettingUpdater.ts | 36 + web/src/components/Skeleton.tsx | 51 + .../StatisticsView/MonthNavigator.tsx | 96 + .../StatisticsView/StatisticsView.tsx | 40 + web/src/components/StatisticsView/index.ts | 1 + web/src/components/TagTree.tsx | 159 + web/src/components/ThemeSelect.tsx | 52 + web/src/components/UpdateAccountDialog.tsx | 226 + .../UpdateCustomizedProfileDialog.tsx | 154 + web/src/components/UserAvatar.tsx | 23 + .../components/UserMemoMap/UserMemoMap.tsx | 170 + web/src/components/UserMemoMap/index.ts | 1 + web/src/components/UserMenu.tsx | 192 + web/src/components/VideoPoster.tsx | 82 + web/src/components/VisibilityIcon.tsx | 28 + web/src/components/kit/OverflowTip.tsx | 40 + web/src/components/kit/SquareDiv.tsx | 45 + web/src/components/map/LazyLocationPicker.tsx | 29 + web/src/components/map/LocationPicker.tsx | 248 + web/src/components/map/index.ts | 1 + web/src/components/map/map-utils.tsx | 41 + web/src/components/map/types.ts | 4 + web/src/components/map/useReverseGeocoding.ts | 39 + web/src/components/ui/badge.tsx | 34 + web/src/components/ui/button.tsx | 45 + web/src/components/ui/checkbox.tsx | 28 + web/src/components/ui/dialog.tsx | 122 + web/src/components/ui/dropdown-menu.tsx | 268 + web/src/components/ui/input.tsx | 18 + web/src/components/ui/label.tsx | 18 + web/src/components/ui/popover.tsx | 47 + web/src/components/ui/radio-group.tsx | 27 + web/src/components/ui/select.tsx | 148 + web/src/components/ui/separator.tsx | 25 + web/src/components/ui/sheet.tsx | 124 + web/src/components/ui/switch.tsx | 25 + web/src/components/ui/textarea.tsx | 17 + web/src/components/ui/tooltip.tsx | 49 + web/src/components/ui/visually-hidden.tsx | 19 + web/src/connect.ts | 203 + web/src/contexts/AuthContext.tsx | 204 + web/src/contexts/InstanceContext.tsx | 239 + web/src/contexts/MemoFilterContext.tsx | 160 + web/src/contexts/ViewContext.tsx | 88 + web/src/helpers/consts.ts | 5 + web/src/helpers/resource-names.ts | 60 + web/src/helpers/sso-display.ts | 123 + web/src/helpers/utils.ts | 39 + web/src/hooks/index.ts | 13 + web/src/hooks/useAsyncEffect.ts | 9 + web/src/hooks/useAttachmentLibrary.ts | 203 + web/src/hooks/useAttachmentQueries.ts | 100 + web/src/hooks/useCurrentUser.ts | 8 + web/src/hooks/useDateFilterNavigation.ts | 19 + web/src/hooks/useDebouncedEffect.ts | 16 + web/src/hooks/useDialog.ts | 75 + web/src/hooks/useFilteredMemoStats.ts | 98 + web/src/hooks/useInstanceQueries.ts | 105 + web/src/hooks/useLiveMemoRefresh.ts | 254 + web/src/hooks/useLoading.ts | 35 + web/src/hooks/useLocalStorage.ts | 48 + web/src/hooks/useMediaQuery.ts | 34 + web/src/hooks/useMemoDetailError.ts | 32 + web/src/hooks/useMemoFilters.ts | 96 + web/src/hooks/useMemoQueries.ts | 286 + web/src/hooks/useMemoShareQueries.ts | 101 + web/src/hooks/useMemoSorting.ts | 53 + web/src/hooks/useNavigateTo.ts | 24 + web/src/hooks/useTokenRefreshOnFocus.ts | 49 + web/src/hooks/useUserLocale.ts | 35 + web/src/hooks/useUserQueries.ts | 305 + web/src/hooks/useUserTheme.ts | 37 + web/src/i18n.ts | 86 + web/src/index.css | 33 + web/src/layouts/MainLayout.tsx | 88 + web/src/layouts/RootLayout.tsx | 69 + web/src/lib/calendar-utils.ts | 23 + web/src/lib/color.ts | 21 + web/src/lib/error.ts | 38 + web/src/lib/query-client.ts | 29 + web/src/lib/tag.ts | 64 + web/src/lib/utils.ts | 6 + web/src/locales/ar.json | 544 ++ web/src/locales/ca.json | 544 ++ web/src/locales/cs.json | 544 ++ web/src/locales/de.json | 544 ++ web/src/locales/en-GB.json | 544 ++ web/src/locales/en.json | 816 +++ web/src/locales/es.json | 544 ++ web/src/locales/fa.json | 544 ++ web/src/locales/fr.json | 544 ++ web/src/locales/gl.json | 544 ++ web/src/locales/hi.json | 544 ++ web/src/locales/hr.json | 544 ++ web/src/locales/hu.json | 544 ++ web/src/locales/id.json | 544 ++ web/src/locales/it.json | 544 ++ web/src/locales/ja.json | 535 ++ web/src/locales/ka-GE.json | 544 ++ web/src/locales/ko.json | 544 ++ web/src/locales/mr.json | 544 ++ web/src/locales/nb.json | 544 ++ web/src/locales/nl.json | 544 ++ web/src/locales/pl.json | 545 ++ web/src/locales/pt-BR.json | 544 ++ web/src/locales/pt-PT.json | 544 ++ web/src/locales/ru.json | 544 ++ web/src/locales/sl.json | 545 ++ web/src/locales/sv.json | 544 ++ web/src/locales/th.json | 544 ++ web/src/locales/tr.json | 544 ++ web/src/locales/uk.json | 544 ++ web/src/locales/vi.json | 544 ++ web/src/locales/zh-Hans.json | 706 ++ web/src/locales/zh-Hant.json | 810 +++ web/src/main.tsx | 80 + web/src/pages/About.tsx | 167 + web/src/pages/AdminSignIn.tsx | 23 + web/src/pages/Archived.tsx | 35 + web/src/pages/Attachments.tsx | 221 + web/src/pages/AuthCallback.tsx | 149 + web/src/pages/Explore.tsx | 41 + web/src/pages/Home.tsx | 38 + web/src/pages/Inboxes.tsx | 124 + web/src/pages/MemoDetail.tsx | 126 + web/src/pages/NotFound.tsx | 15 + web/src/pages/PermissionDenied.tsx | 15 + web/src/pages/Setting.tsx | 138 + web/src/pages/Shortcuts.tsx | 500 ++ web/src/pages/SignIn.tsx | 123 + web/src/pages/SignUp.tsx | 162 + web/src/pages/UserProfile.tsx | 160 + web/src/router/guards.tsx | 67 + web/src/router/index.tsx | 121 + web/src/router/routes.ts | 15 + web/src/themes/COLOR_GUIDE.md | 299 + web/src/themes/default-dark.css | 43 + web/src/themes/default.css | 83 + web/src/themes/paper.css | 32 + web/src/types/common.d.ts | 1 + web/src/types/common.ts | 13 + web/src/types/i18n.d.ts | 1 + web/src/types/markdown.ts | 90 + web/src/types/modules/setting.d.ts | 1 + web/src/types/proto/api/v1/ai_service_pb.ts | 119 + .../proto/api/v1/attachment_service_pb.ts | 450 ++ web/src/types/proto/api/v1/auth_service_pb.ts | 300 + web/src/types/proto/api/v1/common_pb.ts | 90 + web/src/types/proto/api/v1/idp_service_pb.ts | 376 + .../types/proto/api/v1/instance_service_pb.ts | 1033 +++ web/src/types/proto/api/v1/memo_service_pb.ts | 1433 ++++ .../types/proto/api/v1/shortcut_service_pb.ts | 250 + web/src/types/proto/api/v1/user_service_pb.ts | 1901 +++++ .../types/proto/google/api/annotations_pb.ts | 39 + web/src/types/proto/google/api/client_pb.ts | 953 +++ .../proto/google/api/field_behavior_pb.ts | 157 + web/src/types/proto/google/api/http_pb.ts | 474 ++ .../types/proto/google/api/launch_stage_pb.ts | 118 + web/src/types/proto/google/api/resource_pb.ts | 354 + web/src/types/proto/google/type/color_pb.ts | 204 + web/src/types/relative-time-element.d.ts | 15 + web/src/types/statistics.ts | 17 + web/src/types/view.d.ts | 5 + web/src/utils/attachment.ts | 76 + web/src/utils/auth-redirect.ts | 52 + web/src/utils/format.ts | 76 + web/src/utils/i18n.ts | 124 + web/src/utils/markdown-list-detection.ts | 67 + web/src/utils/markdown-manipulation.ts | 201 + web/src/utils/markdown-task-actions.ts | 147 + web/src/utils/media-item.ts | 192 + web/src/utils/memo.ts | 27 + web/src/utils/oauth.ts | 160 + web/src/utils/redirect-safety.ts | 73 + .../utils/rehype-plugins/rehype-heading-id.ts | 37 + .../remark-plugins/remark-disable-setext.ts | 14 + .../utils/remark-plugins/remark-mention.ts | 102 + .../remark-plugins/remark-preserve-type.ts | 22 + .../remark-split-mixed-task-lists.ts | 67 + web/src/utils/remark-plugins/remark-tag.ts | 112 + web/src/utils/theme.ts | 262 + web/src/utils/user.ts | 5 + web/src/utils/uuid.ts | 5 + web/tests/about-page.test.tsx | 58 + web/tests/activity-calendar-tooltip.test.ts | 26 + web/tests/auth-redirect.test.ts | 115 + .../calendar-cell-empty-clickable.test.tsx | 50 + web/tests/derive-default-create-time.test.ts | 75 + web/tests/filtered-memo-stats.test.ts | 109 + web/tests/guards.test.tsx | 192 + web/tests/hooks.test.tsx | 194 + web/tests/location-picker.test.tsx | 73 + web/tests/markdown-task-actions.test.ts | 38 + web/tests/memo-content-list.test.tsx | 77 + web/tests/memo-content-paragraph.test.tsx | 34 + web/tests/memo-content-security.test.tsx | 87 + web/tests/memo-editor-cache.test.ts | 57 + web/tests/memo-editor-paste.test.tsx | 81 + web/tests/memo-share-image.test.ts | 134 + web/tests/mermaid-block.test.tsx | 33 + web/tests/oauth.test.ts | 44 + web/tests/paged-memo-list.test.tsx | 49 + web/tests/placeholder-component.test.tsx | 85 + web/tests/placeholder-pool.test.ts | 36 + web/tests/preview-image-dialog.test.tsx | 118 + web/tests/redirect-safety.test.ts | 77 + web/tests/router-config.test.tsx | 69 + web/tests/setup.ts | 42 + web/tests/video-poster.test.tsx | 47 + web/tsconfig.json | 24 + web/vite.config.mts | 63 + web/vitest.config.mts | 28 + 947 files changed, 174905 insertions(+) create mode 100644 .dockerignore create mode 100644 .gitignore create mode 100644 .golangci.yaml create mode 100644 .release-please-manifest.json create mode 100644 AGENTS.md create mode 100644 CHANGELOG.md create mode 100644 CODEOWNERS create mode 100644 LICENSE create mode 100644 README.md create mode 100644 SECURITY.md create mode 100644 docs/plans/2026-03-23-memo-detail-outline/definition.md create mode 100644 docs/plans/2026-03-23-memo-detail-outline/plan.md create mode 100644 docs/plans/2026-03-23-tag-blur-attribute/definition.md create mode 100644 docs/plans/2026-03-23-tag-blur-attribute/execution.md create mode 100644 docs/plans/2026-03-23-tag-blur-attribute/plan.md create mode 100644 docs/plans/2026-03-24-user-resource-identifiers/definition.md create mode 100644 docs/plans/2026-03-24-user-resource-identifiers/design.md create mode 100644 docs/plans/2026-03-24-user-resource-identifiers/execution.md create mode 100644 docs/plans/2026-03-24-user-resource-identifiers/plan.md create mode 100644 docs/plans/2026-03-31-quick-voice-input/definition.md create mode 100644 docs/plans/2026-03-31-quick-voice-input/design.md create mode 100644 docs/plans/2026-03-31-quick-voice-input/execution.md create mode 100644 docs/plans/2026-03-31-quick-voice-input/plan.md create mode 100644 docs/plans/2026-04-06-memo-mentions/definition.md create mode 100644 docs/plans/2026-04-06-memo-mentions/design.md create mode 100644 docs/plans/2026-04-06-memo-mentions/execution.md create mode 100644 docs/plans/2026-04-06-memo-mentions/plan.md create mode 100644 docs/plans/2026-04-21-sso-user-identity-linkage/definition.md create mode 100644 docs/plans/2026-04-21-sso-user-identity-linkage/design.md create mode 100644 docs/plans/2026-04-21-sso-user-identity-linkage/execution.md create mode 100644 docs/plans/2026-04-21-sso-user-identity-linkage/plan.md create mode 100644 docs/superpowers/plans/2026-05-02-activity-calendar-time-basis.md create mode 100644 docs/superpowers/plans/2026-05-02-calendar-date-prefill.md create mode 100644 docs/superpowers/plans/2026-05-02-stt-audiollm-split.md create mode 100644 docs/superpowers/plans/2026-05-02-transcription-settings.md create mode 100644 docs/superpowers/plans/2026-05-12-first-screen-lazy-heavy-deps.md create mode 100644 docs/superpowers/plans/2026-05-12-placeholder-component.md create mode 100644 docs/superpowers/plans/2026-05-31-remove-react-use.md create mode 100644 docs/superpowers/specs/2026-05-02-activity-calendar-time-basis-design.md create mode 100644 docs/superpowers/specs/2026-05-02-calendar-date-prefill-design.md create mode 100644 docs/superpowers/specs/2026-05-02-stt-audiollm-split-design.md create mode 100644 docs/superpowers/specs/2026-05-02-transcription-settings-design.md create mode 100644 docs/superpowers/specs/2026-05-12-first-screen-lazy-heavy-deps-design.md create mode 100644 docs/superpowers/specs/2026-05-12-placeholder-component-design.md create mode 100644 docs/superpowers/specs/2026-05-31-remove-react-use-design.md create mode 100644 go.mod create mode 100644 go.sum create mode 100644 internal/ai/ai.go create mode 100644 internal/ai/audio/webm.go create mode 100644 internal/ai/audio/webm_test.go create mode 100644 internal/ai/audiollm/audiollm.go create mode 100644 internal/ai/audiollm/gemini/gemini.go create mode 100644 internal/ai/audiollm/gemini/gemini_test.go create mode 100644 internal/ai/audiollm/options.go create mode 100644 internal/ai/errors.go create mode 100644 internal/ai/models.go create mode 100644 internal/ai/resolver.go create mode 100644 internal/ai/stt/openai/openai.go create mode 100644 internal/ai/stt/openai/openai_test.go create mode 100644 internal/ai/stt/options.go create mode 100644 internal/ai/stt/stt.go create mode 100644 internal/base/resource_name.go create mode 100644 internal/base/resource_name_test.go create mode 100644 internal/cron/README.md create mode 100644 internal/cron/chain.go create mode 100644 internal/cron/chain_test.go create mode 100644 internal/cron/constantdelay.go create mode 100644 internal/cron/constantdelay_test.go create mode 100644 internal/cron/cron.go create mode 100644 internal/cron/cron_test.go create mode 100644 internal/cron/logger.go create mode 100644 internal/cron/option.go create mode 100644 internal/cron/option_test.go create mode 100644 internal/cron/parser.go create mode 100644 internal/cron/parser_test.go create mode 100644 internal/cron/spec.go create mode 100644 internal/cron/spec_test.go create mode 100644 internal/email/README.md create mode 100644 internal/email/client.go create mode 100644 internal/email/client_test.go create mode 100644 internal/email/config.go create mode 100644 internal/email/config_test.go create mode 100644 internal/email/doc.go create mode 100644 internal/email/email.go create mode 100644 internal/email/email_test.go create mode 100644 internal/email/message.go create mode 100644 internal/email/message_test.go create mode 100644 internal/filter/MAINTENANCE.md create mode 100644 internal/filter/README.md create mode 100644 internal/filter/engine.go create mode 100644 internal/filter/engine_test.go create mode 100644 internal/filter/helpers.go create mode 100644 internal/filter/ir.go create mode 100644 internal/filter/parser.go create mode 100644 internal/filter/render.go create mode 100644 internal/filter/schema.go create mode 100644 internal/httpgetter/html_meta.go create mode 100644 internal/httpgetter/html_meta_test.go create mode 100644 internal/httpgetter/http_getter.go create mode 100644 internal/httpgetter/image.go create mode 100644 internal/httpgetter/util.go create mode 100644 internal/idp/idp.go create mode 100644 internal/idp/oauth2/oauth2.go create mode 100644 internal/idp/oauth2/oauth2_test.go create mode 100644 internal/markdown/ast/mention.go create mode 100644 internal/markdown/ast/tag.go create mode 100644 internal/markdown/extensions/mention.go create mode 100644 internal/markdown/extensions/tag.go create mode 100644 internal/markdown/markdown.go create mode 100644 internal/markdown/markdown_test.go create mode 100644 internal/markdown/parser/mention.go create mode 100644 internal/markdown/parser/tag.go create mode 100644 internal/markdown/parser/tag_test.go create mode 100644 internal/markdown/renderer/markdown_renderer.go create mode 100644 internal/markdown/renderer/markdown_renderer_test.go create mode 100644 internal/motionphoto/motionphoto.go create mode 100644 internal/motionphoto/motionphoto_test.go create mode 100644 internal/profile/profile.go create mode 100644 internal/scheduler/README.md create mode 100644 internal/scheduler/doc.go create mode 100644 internal/scheduler/example_test.go create mode 100644 internal/scheduler/integration_test.go create mode 100644 internal/scheduler/job.go create mode 100644 internal/scheduler/job_test.go create mode 100644 internal/scheduler/middleware.go create mode 100644 internal/scheduler/middleware_test.go create mode 100644 internal/scheduler/parser.go create mode 100644 internal/scheduler/parser_test.go create mode 100644 internal/scheduler/scheduler.go create mode 100644 internal/scheduler/scheduler_test.go create mode 100644 internal/storage/s3/s3.go create mode 100644 internal/testutil/motionphoto.go create mode 100644 internal/util/util.go create mode 100644 internal/util/util_test.go create mode 100644 internal/version/version.go create mode 100644 internal/version/version_test.go create mode 100644 internal/webhook/validate.go create mode 100644 internal/webhook/webhook.go create mode 100644 internal/webhook/webhook_test.go create mode 100644 proto/README.md create mode 100644 proto/api/v1/README.md create mode 100644 proto/api/v1/ai_service.proto create mode 100644 proto/api/v1/attachment_service.proto create mode 100644 proto/api/v1/auth_service.proto create mode 100644 proto/api/v1/common.proto create mode 100644 proto/api/v1/idp_service.proto create mode 100644 proto/api/v1/instance_service.proto create mode 100644 proto/api/v1/memo_service.proto create mode 100644 proto/api/v1/shortcut_service.proto create mode 100644 proto/api/v1/user_service.proto create mode 100644 proto/buf.gen.yaml create mode 100644 proto/buf.lock create mode 100644 proto/buf.yaml create mode 100644 proto/gen/api/v1/ai_service.pb.go create mode 100644 proto/gen/api/v1/ai_service.pb.gw.go create mode 100644 proto/gen/api/v1/ai_service_grpc.pb.go create mode 100644 proto/gen/api/v1/apiv1connect/ai_service.connect.go create mode 100644 proto/gen/api/v1/apiv1connect/attachment_service.connect.go create mode 100644 proto/gen/api/v1/apiv1connect/auth_service.connect.go create mode 100644 proto/gen/api/v1/apiv1connect/idp_service.connect.go create mode 100644 proto/gen/api/v1/apiv1connect/instance_service.connect.go create mode 100644 proto/gen/api/v1/apiv1connect/memo_service.connect.go create mode 100644 proto/gen/api/v1/apiv1connect/shortcut_service.connect.go create mode 100644 proto/gen/api/v1/apiv1connect/user_service.connect.go create mode 100644 proto/gen/api/v1/attachment_service.pb.go create mode 100644 proto/gen/api/v1/attachment_service.pb.gw.go create mode 100644 proto/gen/api/v1/attachment_service_grpc.pb.go create mode 100644 proto/gen/api/v1/auth_service.pb.go create mode 100644 proto/gen/api/v1/auth_service.pb.gw.go create mode 100644 proto/gen/api/v1/auth_service_grpc.pb.go create mode 100644 proto/gen/api/v1/common.pb.go create mode 100644 proto/gen/api/v1/idp_service.pb.go create mode 100644 proto/gen/api/v1/idp_service.pb.gw.go create mode 100644 proto/gen/api/v1/idp_service_grpc.pb.go create mode 100644 proto/gen/api/v1/instance_service.pb.go create mode 100644 proto/gen/api/v1/instance_service.pb.gw.go create mode 100644 proto/gen/api/v1/instance_service_grpc.pb.go create mode 100644 proto/gen/api/v1/memo_service.pb.go create mode 100644 proto/gen/api/v1/memo_service.pb.gw.go create mode 100644 proto/gen/api/v1/memo_service_grpc.pb.go create mode 100644 proto/gen/api/v1/shortcut_service.pb.go create mode 100644 proto/gen/api/v1/shortcut_service.pb.gw.go create mode 100644 proto/gen/api/v1/shortcut_service_grpc.pb.go create mode 100644 proto/gen/api/v1/user_service.pb.go create mode 100644 proto/gen/api/v1/user_service.pb.gw.go create mode 100644 proto/gen/api/v1/user_service_grpc.pb.go create mode 100644 proto/gen/openapi.yaml create mode 100644 proto/gen/store/attachment.pb.go create mode 100644 proto/gen/store/idp.pb.go create mode 100644 proto/gen/store/inbox.pb.go create mode 100644 proto/gen/store/instance_setting.pb.go create mode 100644 proto/gen/store/memo.pb.go create mode 100644 proto/gen/store/user_setting.pb.go create mode 100644 proto/store/attachment.proto create mode 100644 proto/store/idp.proto create mode 100644 proto/store/inbox.proto create mode 100644 proto/store/instance_setting.proto create mode 100644 proto/store/memo.proto create mode 100644 proto/store/user_setting.proto create mode 100644 release-please-config.json create mode 100644 scripts/Dockerfile create mode 100755 scripts/build.sh create mode 100644 scripts/compose.yaml create mode 100755 scripts/entrypoint.sh create mode 100755 scripts/entrypoint_test.sh create mode 100755 scripts/install.sh create mode 100644 server/auth/authenticator.go create mode 100644 server/auth/context.go create mode 100644 server/auth/extract.go create mode 100644 server/auth/token.go create mode 100644 server/auth/token_test.go create mode 100644 server/cors.go create mode 100644 server/cors_test.go create mode 100644 server/notification/email.go create mode 100644 server/router/api/v1/acl_config.go create mode 100644 server/router/api/v1/acl_config_test.go create mode 100644 server/router/api/v1/ai_service.go create mode 100644 server/router/api/v1/attachment_exif_test.go create mode 100644 server/router/api/v1/attachment_motion.go create mode 100644 server/router/api/v1/attachment_service.go create mode 100644 server/router/api/v1/auth_service.go create mode 100644 server/router/api/v1/auth_service_client_info_test.go create mode 100644 server/router/api/v1/common.go create mode 100644 server/router/api/v1/common_test.go create mode 100644 server/router/api/v1/connect_handler.go create mode 100644 server/router/api/v1/connect_interceptors.go create mode 100644 server/router/api/v1/connect_interceptors_test.go create mode 100644 server/router/api/v1/connect_services.go create mode 100644 server/router/api/v1/header_carrier.go create mode 100644 server/router/api/v1/health_service.go create mode 100644 server/router/api/v1/idp_service.go create mode 100644 server/router/api/v1/instance_service.go create mode 100644 server/router/api/v1/instance_stats.go create mode 100644 server/router/api/v1/instance_stats_test.go create mode 100644 server/router/api/v1/link_metadata_test.go create mode 100644 server/router/api/v1/memo_attachment_service.go create mode 100644 server/router/api/v1/memo_batch_helpers.go create mode 100644 server/router/api/v1/memo_mention_helpers.go create mode 100644 server/router/api/v1/memo_relation_service.go create mode 100644 server/router/api/v1/memo_service.go create mode 100644 server/router/api/v1/memo_service_converter.go create mode 100644 server/router/api/v1/memo_service_filter.go create mode 100644 server/router/api/v1/memo_share_service.go create mode 100644 server/router/api/v1/memo_update_helpers.go create mode 100644 server/router/api/v1/notification_email.go create mode 100644 server/router/api/v1/reaction_service.go create mode 100644 server/router/api/v1/resource_name.go create mode 100644 server/router/api/v1/shortcut_service.go create mode 100644 server/router/api/v1/sse_event_helpers.go create mode 100644 server/router/api/v1/sse_handler.go create mode 100644 server/router/api/v1/sse_hub.go create mode 100644 server/router/api/v1/sse_hub_test.go create mode 100644 server/router/api/v1/sse_service_test.go create mode 100644 server/router/api/v1/sso_username.go create mode 100644 server/router/api/v1/test/ai_service_test.go create mode 100644 server/router/api/v1/test/attachment_service_test.go create mode 100644 server/router/api/v1/test/auth_service_test.go create mode 100644 server/router/api/v1/test/auth_test.go create mode 100644 server/router/api/v1/test/idp_service_test.go create mode 100644 server/router/api/v1/test/instance_admin_cache_test.go create mode 100644 server/router/api/v1/test/instance_service_test.go create mode 100644 server/router/api/v1/test/instance_stats_test.go create mode 100644 server/router/api/v1/test/memo_attachment_service_test.go create mode 100644 server/router/api/v1/test/memo_relation_service_test.go create mode 100644 server/router/api/v1/test/memo_service_benchmark_test.go create mode 100644 server/router/api/v1/test/memo_service_test.go create mode 100644 server/router/api/v1/test/memo_share_service_test.go create mode 100644 server/router/api/v1/test/reaction_service_test.go create mode 100644 server/router/api/v1/test/shortcut_service_test.go create mode 100644 server/router/api/v1/test/sse_handler_test.go create mode 100644 server/router/api/v1/test/test_helper.go create mode 100644 server/router/api/v1/test/user_email_visibility_test.go create mode 100644 server/router/api/v1/test/user_notification_test.go create mode 100644 server/router/api/v1/test/user_resource_name_test.go create mode 100644 server/router/api/v1/test/user_search_test.go create mode 100644 server/router/api/v1/test/user_service_delete_test.go create mode 100644 server/router/api/v1/test/user_service_email_username_test.go create mode 100644 server/router/api/v1/test/user_service_registration_test.go create mode 100644 server/router/api/v1/test/user_service_stats_test.go create mode 100644 server/router/api/v1/test/user_setting_test.go create mode 100644 server/router/api/v1/user_resource_name.go create mode 100644 server/router/api/v1/user_resource_name_test.go create mode 100644 server/router/api/v1/user_service.go create mode 100644 server/router/api/v1/user_service_stats.go create mode 100644 server/router/api/v1/v1.go create mode 100644 server/router/fileserver/README.md create mode 100644 server/router/fileserver/fileserver.go create mode 100644 server/router/fileserver/fileserver_test.go create mode 100644 server/router/frontend/frontend.go create mode 100644 server/router/frontend/frontend_test.go create mode 100644 server/router/mcp/README.md create mode 100644 server/router/mcp/access.go create mode 100644 server/router/mcp/api_helpers.go create mode 100644 server/router/mcp/mcp.go create mode 100644 server/router/mcp/mcp_test.go create mode 100644 server/router/mcp/prompts.go create mode 100644 server/router/mcp/resources_memo.go create mode 100644 server/router/mcp/tool_metadata.go create mode 100644 server/router/mcp/tools_attachment.go create mode 100644 server/router/mcp/tools_memo.go create mode 100644 server/router/mcp/tools_reaction.go create mode 100644 server/router/mcp/tools_relation.go create mode 100644 server/router/mcp/tools_tag.go create mode 100644 server/router/rss/rss.go create mode 100644 server/router/rss/rss_test.go create mode 100644 server/runner/memopayload/runner.go create mode 100644 server/runner/s3presign/runner.go create mode 100644 server/runner/s3presign/runner_test.go create mode 100644 server/server.go create mode 100644 store/attachment.go create mode 100644 store/cache.go create mode 100644 store/cache/cache.go create mode 100644 store/cache/cache_test.go create mode 100644 store/common.go create mode 100644 store/db/db.go create mode 100644 store/db/mysql/attachment.go create mode 100644 store/db/mysql/common.go create mode 100644 store/db/mysql/idp.go create mode 100644 store/db/mysql/inbox.go create mode 100644 store/db/mysql/instance_setting.go create mode 100644 store/db/mysql/memo.go create mode 100644 store/db/mysql/memo_relation.go create mode 100644 store/db/mysql/memo_share.go create mode 100644 store/db/mysql/mysql.go create mode 100644 store/db/mysql/reaction.go create mode 100644 store/db/mysql/user.go create mode 100644 store/db/mysql/user_delete.go create mode 100644 store/db/mysql/user_delete_test.go create mode 100644 store/db/mysql/user_identity.go create mode 100644 store/db/mysql/user_setting.go create mode 100644 store/db/postgres/attachment.go create mode 100644 store/db/postgres/common.go create mode 100644 store/db/postgres/idp.go create mode 100644 store/db/postgres/inbox.go create mode 100644 store/db/postgres/instance_setting.go create mode 100644 store/db/postgres/memo.go create mode 100644 store/db/postgres/memo_relation.go create mode 100644 store/db/postgres/memo_share.go create mode 100644 store/db/postgres/postgres.go create mode 100644 store/db/postgres/reaction.go create mode 100644 store/db/postgres/user.go create mode 100644 store/db/postgres/user_delete.go create mode 100644 store/db/postgres/user_identity.go create mode 100644 store/db/postgres/user_setting.go create mode 100644 store/db/postgres/user_setting_test.go create mode 100644 store/db/sqlite/attachment.go create mode 100644 store/db/sqlite/common.go create mode 100644 store/db/sqlite/functions.go create mode 100644 store/db/sqlite/idp.go create mode 100644 store/db/sqlite/inbox.go create mode 100644 store/db/sqlite/instance_setting.go create mode 100644 store/db/sqlite/memo.go create mode 100644 store/db/sqlite/memo_relation.go create mode 100644 store/db/sqlite/memo_share.go create mode 100644 store/db/sqlite/reaction.go create mode 100644 store/db/sqlite/sqlite.go create mode 100644 store/db/sqlite/user.go create mode 100644 store/db/sqlite/user_delete.go create mode 100644 store/db/sqlite/user_identity.go create mode 100644 store/db/sqlite/user_setting.go create mode 100644 store/driver.go create mode 100644 store/idp.go create mode 100644 store/inbox.go create mode 100644 store/instance_setting.go create mode 100644 store/memo.go create mode 100644 store/memo_relation.go create mode 100644 store/memo_share.go create mode 100644 store/migration/mysql/0.17/00__inbox.sql create mode 100644 store/migration/mysql/0.17/01__delete_activity.sql create mode 100644 store/migration/mysql/0.18/00__extend_text.sql create mode 100644 store/migration/mysql/0.18/01__webhook.sql create mode 100644 store/migration/mysql/0.18/02__user_setting.sql create mode 100644 store/migration/mysql/0.19/00__add_resource_name.sql create mode 100644 store/migration/mysql/0.20/00__reaction.sql create mode 100644 store/migration/mysql/0.21/00__user_description.sql create mode 100644 store/migration/mysql/0.21/01__rename_uid.sql create mode 100644 store/migration/mysql/0.22/00__resource_storage_type.sql create mode 100644 store/migration/mysql/0.22/01__memo_tags.sql create mode 100644 store/migration/mysql/0.22/02__memo_payload.sql create mode 100644 store/migration/mysql/0.22/03__drop_tag.sql create mode 100644 store/migration/mysql/0.23/00__reactions.sql create mode 100644 store/migration/mysql/0.24/00__memo.sql create mode 100644 store/migration/mysql/0.24/01__memo_pinned.sql create mode 100644 store/migration/mysql/0.24/02__s3_reference_length.sql create mode 100644 store/migration/mysql/0.25/00__remove_webhook.sql create mode 100644 store/migration/mysql/0.26/00__rename_resource_to_attachment.sql create mode 100644 store/migration/mysql/0.26/01__drop_memo_organizer.sql create mode 100644 store/migration/mysql/0.26/02__migrate_host_to_admin.sql create mode 100644 store/migration/mysql/0.27/00__migrate_storage_setting.sql create mode 100644 store/migration/mysql/0.27/01__add_idp_uid.sql create mode 100644 store/migration/mysql/0.27/02__migrate_inbox_message_payload.sql create mode 100644 store/migration/mysql/0.27/03__drop_activity.sql create mode 100644 store/migration/mysql/0.27/04__memo_share.sql create mode 100644 store/migration/mysql/0.28/00__user_identity.sql create mode 100644 store/migration/mysql/LATEST.sql create mode 100644 store/migration/postgres/0.19/00__add_resource_name.sql create mode 100644 store/migration/postgres/0.20/00__reaction.sql create mode 100644 store/migration/postgres/0.21/00__user_description.sql create mode 100644 store/migration/postgres/0.21/01__rename_uid.sql create mode 100644 store/migration/postgres/0.22/00__resource_storage_type.sql create mode 100644 store/migration/postgres/0.22/01__memo_tags.sql create mode 100644 store/migration/postgres/0.22/02__memo_payload.sql create mode 100644 store/migration/postgres/0.22/03__drop_tag.sql create mode 100644 store/migration/postgres/0.23/00__reactions.sql create mode 100644 store/migration/postgres/0.24/00__memo.sql create mode 100644 store/migration/postgres/0.24/01__memo_pinned.sql create mode 100644 store/migration/postgres/0.25/00__remove_webhook.sql create mode 100644 store/migration/postgres/0.26/00__rename_resource_to_attachment.sql create mode 100644 store/migration/postgres/0.26/01__drop_memo_organizer.sql create mode 100644 store/migration/postgres/0.26/02__migrate_host_to_admin.sql create mode 100644 store/migration/postgres/0.27/00__migrate_storage_setting.sql create mode 100644 store/migration/postgres/0.27/01__add_idp_uid.sql create mode 100644 store/migration/postgres/0.27/02__migrate_inbox_message_payload.sql create mode 100644 store/migration/postgres/0.27/03__drop_activity.sql create mode 100644 store/migration/postgres/0.27/04__memo_share.sql create mode 100644 store/migration/postgres/0.28/00__user_identity.sql create mode 100644 store/migration/postgres/LATEST.sql create mode 100644 store/migration/sqlite/0.10/00__activity.sql create mode 100644 store/migration/sqlite/0.11/00__user_avatar.sql create mode 100644 store/migration/sqlite/0.11/01__idp.sql create mode 100644 store/migration/sqlite/0.11/02__storage.sql create mode 100644 store/migration/sqlite/0.12/00__user_setting.sql create mode 100644 store/migration/sqlite/0.12/01__system_setting.sql create mode 100644 store/migration/sqlite/0.12/03__resource_internal_path.sql create mode 100644 store/migration/sqlite/0.12/04__resource_public_id.sql create mode 100644 store/migration/sqlite/0.13/00__memo_relation.sql create mode 100644 store/migration/sqlite/0.13/01__remove_memo_organizer_id.sql create mode 100644 store/migration/sqlite/0.14/00__drop_resource_public_id.sql create mode 100644 store/migration/sqlite/0.14/01__create_indexes.sql create mode 100644 store/migration/sqlite/0.15/00__drop_user_open_id.sql create mode 100644 store/migration/sqlite/0.16/00__add_memo_id_to_resource.sql create mode 100644 store/migration/sqlite/0.16/01__drop_shortcut_table.sql create mode 100644 store/migration/sqlite/0.17/00__inbox.sql create mode 100644 store/migration/sqlite/0.17/01__delete_activities.sql create mode 100644 store/migration/sqlite/0.18/00__webhook.sql create mode 100644 store/migration/sqlite/0.18/01__user_setting.sql create mode 100644 store/migration/sqlite/0.19/00__add_resource_name.sql create mode 100644 store/migration/sqlite/0.2/00__user_role.sql create mode 100644 store/migration/sqlite/0.2/01__memo_visibility.sql create mode 100644 store/migration/sqlite/0.20/00__reaction.sql create mode 100644 store/migration/sqlite/0.21/00__user_description.sql create mode 100644 store/migration/sqlite/0.21/01__rename_uid.sql create mode 100644 store/migration/sqlite/0.22/00__resource_storage_type.sql create mode 100644 store/migration/sqlite/0.22/01__memo_tags.sql create mode 100644 store/migration/sqlite/0.22/02__memo_payload.sql create mode 100644 store/migration/sqlite/0.22/03__drop_tag.sql create mode 100644 store/migration/sqlite/0.23/00__reactions.sql create mode 100644 store/migration/sqlite/0.24/00__memo.sql create mode 100644 store/migration/sqlite/0.24/01__memo_pinned.sql create mode 100644 store/migration/sqlite/0.25/00__remove_webhook.sql create mode 100644 store/migration/sqlite/0.26/00__rename_resource_to_attachment.sql create mode 100644 store/migration/sqlite/0.26/01__drop_memo_organizer.sql create mode 100644 store/migration/sqlite/0.26/02__drop_indexes.sql create mode 100644 store/migration/sqlite/0.26/03__alter_user_role.sql create mode 100644 store/migration/sqlite/0.26/04__migrate_host_to_admin.sql create mode 100644 store/migration/sqlite/0.27/00__migrate_storage_setting.sql create mode 100644 store/migration/sqlite/0.27/01__add_idp_uid.sql create mode 100644 store/migration/sqlite/0.27/02__migrate_inbox_message_payload.sql create mode 100644 store/migration/sqlite/0.27/03__drop_activity.sql create mode 100644 store/migration/sqlite/0.27/04__memo_share.sql create mode 100644 store/migration/sqlite/0.28/00__user_identity.sql create mode 100644 store/migration/sqlite/0.3/00__memo_visibility_protected.sql create mode 100644 store/migration/sqlite/0.4/00__user_setting.sql create mode 100644 store/migration/sqlite/0.5/00__regenerate_foreign_keys.sql create mode 100644 store/migration/sqlite/0.5/01__memo_resource.sql create mode 100644 store/migration/sqlite/0.5/02__system_setting.sql create mode 100644 store/migration/sqlite/0.5/03__resource_extermal_link.sql create mode 100644 store/migration/sqlite/0.6/00__recreate_triggers.sql create mode 100644 store/migration/sqlite/0.7/00__remove_fk.sql create mode 100644 store/migration/sqlite/0.7/01__remove_triggers.sql create mode 100644 store/migration/sqlite/0.8/00__migration_history.sql create mode 100644 store/migration/sqlite/0.8/01__user_username.sql create mode 100644 store/migration/sqlite/0.9/00__tag.sql create mode 100644 store/migration/sqlite/LATEST.sql create mode 100644 store/migrator.go create mode 100644 store/reaction.go create mode 100644 store/seed/sqlite/01__dump.sql create mode 100644 store/store.go create mode 100644 store/test/README.md create mode 100644 store/test/attachment_filter_test.go create mode 100644 store/test/attachment_test.go create mode 100644 store/test/containers.go create mode 100644 store/test/database_size_test.go create mode 100644 store/test/filter_helpers_test.go create mode 100644 store/test/idp_test.go create mode 100644 store/test/inbox_test.go create mode 100644 store/test/instance_setting_test.go create mode 100644 store/test/main_test.go create mode 100644 store/test/memo_filter_test.go create mode 100644 store/test/memo_relation_test.go create mode 100644 store/test/memo_test.go create mode 100644 store/test/migrator_test.go create mode 100644 store/test/migrator_upgrade_test.go create mode 100644 store/test/reaction_test.go create mode 100644 store/test/store.go create mode 100644 store/test/user_delete_test.go create mode 100644 store/test/user_identity_test.go create mode 100644 store/test/user_setting_test.go create mode 100644 store/test/user_test.go create mode 100644 store/user.go create mode 100644 store/user_delete.go create mode 100644 store/user_identity.go create mode 100644 store/user_setting.go create mode 100644 web/.gitignore create mode 100644 web/biome.json create mode 100644 web/components.json create mode 100644 web/docs/auth-architecture.md create mode 100644 web/index.html create mode 100644 web/package.json create mode 100644 web/pnpm-lock.yaml create mode 100644 web/pnpm-workspace.yaml create mode 100644 web/public/android-chrome-192x192.png create mode 100644 web/public/android-chrome-512x512.png create mode 100644 web/public/apple-touch-icon.png create mode 100644 web/public/full-logo.webp create mode 100644 web/public/logo.webp create mode 100644 web/public/site.webmanifest create mode 100644 web/src/App.tsx create mode 100644 web/src/auth-state.ts create mode 100644 web/src/components/ActivityCalendar/CalendarCell.tsx create mode 100644 web/src/components/ActivityCalendar/MonthCalendar.tsx create mode 100644 web/src/components/ActivityCalendar/YearCalendar.tsx create mode 100644 web/src/components/ActivityCalendar/constants.ts create mode 100644 web/src/components/ActivityCalendar/hooks.ts create mode 100644 web/src/components/ActivityCalendar/index.ts create mode 100644 web/src/components/ActivityCalendar/types.ts create mode 100644 web/src/components/ActivityCalendar/useCalendar.ts create mode 100644 web/src/components/ActivityCalendar/utils.ts create mode 100644 web/src/components/AttachmentIcon.tsx create mode 100644 web/src/components/AttachmentLibrary/AttachmentFileRows.tsx create mode 100644 web/src/components/AttachmentLibrary/AttachmentLibraryEmptyState.tsx create mode 100644 web/src/components/AttachmentLibrary/AttachmentLibraryPrimitives.tsx create mode 100644 web/src/components/AttachmentLibrary/AttachmentLibraryStates.tsx create mode 100644 web/src/components/AttachmentLibrary/AttachmentLibraryToolbar.tsx create mode 100644 web/src/components/AttachmentLibrary/AttachmentMediaGrid.tsx create mode 100644 web/src/components/AttachmentLibrary/index.ts create mode 100644 web/src/components/AuthFooter.tsx create mode 100644 web/src/components/ChangeMemberPasswordDialog.tsx create mode 100644 web/src/components/ConfirmDialog/README.md create mode 100644 web/src/components/ConfirmDialog/index.tsx create mode 100644 web/src/components/CreateAccessTokenDialog.tsx create mode 100644 web/src/components/CreateIdentityProviderDialog.tsx create mode 100644 web/src/components/CreateUserDialog.tsx create mode 100644 web/src/components/CreateWebhookDialog.tsx create mode 100644 web/src/components/DateTimeInput.tsx create mode 100644 web/src/components/ErrorBoundary.tsx create mode 100644 web/src/components/Inbox/MemoCommentMessage.tsx create mode 100644 web/src/components/Inbox/MemoMentionMessage.tsx create mode 100644 web/src/components/LearnMore.tsx create mode 100644 web/src/components/LocaleSelect.tsx create mode 100644 web/src/components/MemoActionMenu/MemoActionMenu.tsx create mode 100644 web/src/components/MemoActionMenu/MemoShareImageDialog.tsx create mode 100644 web/src/components/MemoActionMenu/MemoShareImagePreview.tsx create mode 100644 web/src/components/MemoActionMenu/hooks.ts create mode 100644 web/src/components/MemoActionMenu/index.ts create mode 100644 web/src/components/MemoActionMenu/memoShareImage.ts create mode 100644 web/src/components/MemoActionMenu/memoShareImagePreviewModel.ts create mode 100644 web/src/components/MemoActionMenu/types.ts create mode 100644 web/src/components/MemoCommentSection.tsx create mode 100644 web/src/components/MemoContent/CodeBlock.tsx create mode 100644 web/src/components/MemoContent/LinkMetadataCard.tsx create mode 100644 web/src/components/MemoContent/MarkdownRenderContext.tsx create mode 100644 web/src/components/MemoContent/MemoMarkdownRenderer.tsx create mode 100644 web/src/components/MemoContent/Mention.tsx create mode 100644 web/src/components/MemoContent/MentionResolutionContext.tsx create mode 100644 web/src/components/MemoContent/MermaidBlock.tsx create mode 100644 web/src/components/MemoContent/Table.tsx create mode 100644 web/src/components/MemoContent/Tag.tsx create mode 100644 web/src/components/MemoContent/TaskListItem.tsx create mode 100644 web/src/components/MemoContent/TrustedIframe.ts create mode 100644 web/src/components/MemoContent/constants.ts create mode 100644 web/src/components/MemoContent/hooks.ts create mode 100644 web/src/components/MemoContent/index.tsx create mode 100644 web/src/components/MemoContent/markdown/Blockquote.tsx create mode 100644 web/src/components/MemoContent/markdown/Heading.tsx create mode 100644 web/src/components/MemoContent/markdown/HorizontalRule.tsx create mode 100644 web/src/components/MemoContent/markdown/Image.tsx create mode 100644 web/src/components/MemoContent/markdown/InlineCode.tsx create mode 100644 web/src/components/MemoContent/markdown/Link.tsx create mode 100644 web/src/components/MemoContent/markdown/List.tsx create mode 100644 web/src/components/MemoContent/markdown/Paragraph.tsx create mode 100644 web/src/components/MemoContent/markdown/README.md create mode 100644 web/src/components/MemoContent/markdown/index.ts create mode 100644 web/src/components/MemoContent/markdown/types.ts create mode 100644 web/src/components/MemoContent/types.ts create mode 100644 web/src/components/MemoContent/utils.ts create mode 100644 web/src/components/MemoDetailSidebar/MemoDetailSidebar.tsx create mode 100644 web/src/components/MemoDetailSidebar/MemoDetailSidebarDrawer.tsx create mode 100644 web/src/components/MemoDetailSidebar/MemoOutline.tsx create mode 100644 web/src/components/MemoDetailSidebar/MemoSharePanel.tsx create mode 100644 web/src/components/MemoDetailSidebar/index.ts create mode 100644 web/src/components/MemoDisplaySettingMenu.tsx create mode 100644 web/src/components/MemoEditor/Editor/SlashCommands.tsx create mode 100644 web/src/components/MemoEditor/Editor/SuggestionsPopup.tsx create mode 100644 web/src/components/MemoEditor/Editor/TagSuggestions.tsx create mode 100644 web/src/components/MemoEditor/Editor/commands.ts create mode 100644 web/src/components/MemoEditor/Editor/index.tsx create mode 100644 web/src/components/MemoEditor/Editor/shortcuts.ts create mode 100644 web/src/components/MemoEditor/Editor/useListCompletion.ts create mode 100644 web/src/components/MemoEditor/Editor/useSuggestions.ts create mode 100644 web/src/components/MemoEditor/README.md create mode 100644 web/src/components/MemoEditor/Toolbar/InsertMenu.tsx create mode 100644 web/src/components/MemoEditor/Toolbar/VisibilitySelector.tsx create mode 100644 web/src/components/MemoEditor/Toolbar/index.ts create mode 100644 web/src/components/MemoEditor/components/AudioRecorderPanel.tsx create mode 100644 web/src/components/MemoEditor/components/EditorContent.tsx create mode 100644 web/src/components/MemoEditor/components/EditorMetadata.tsx create mode 100644 web/src/components/MemoEditor/components/EditorToolbar.tsx create mode 100644 web/src/components/MemoEditor/components/FocusModeOverlay.tsx create mode 100644 web/src/components/MemoEditor/components/TimestampPopover.tsx create mode 100644 web/src/components/MemoEditor/components/VoiceWaveform.tsx create mode 100644 web/src/components/MemoEditor/components/index.ts create mode 100644 web/src/components/MemoEditor/constants.ts create mode 100644 web/src/components/MemoEditor/hooks/index.ts create mode 100644 web/src/components/MemoEditor/hooks/useAudioRecorder.ts create mode 100644 web/src/components/MemoEditor/hooks/useAudioWaveform.ts create mode 100644 web/src/components/MemoEditor/hooks/useAutoSave.ts create mode 100644 web/src/components/MemoEditor/hooks/useBlobUrls.ts create mode 100644 web/src/components/MemoEditor/hooks/useDragAndDrop.ts create mode 100644 web/src/components/MemoEditor/hooks/useFileUpload.ts create mode 100644 web/src/components/MemoEditor/hooks/useFocusMode.ts create mode 100644 web/src/components/MemoEditor/hooks/useKeyboard.ts create mode 100644 web/src/components/MemoEditor/hooks/useLinkMemo.ts create mode 100644 web/src/components/MemoEditor/hooks/useLocation.ts create mode 100644 web/src/components/MemoEditor/hooks/useMemoInit.ts create mode 100644 web/src/components/MemoEditor/index.tsx create mode 100644 web/src/components/MemoEditor/services/cacheService.ts create mode 100644 web/src/components/MemoEditor/services/errorService.ts create mode 100644 web/src/components/MemoEditor/services/index.ts create mode 100644 web/src/components/MemoEditor/services/memoService.ts create mode 100644 web/src/components/MemoEditor/services/transcriptionService.ts create mode 100644 web/src/components/MemoEditor/services/uploadService.ts create mode 100644 web/src/components/MemoEditor/services/validationService.ts create mode 100644 web/src/components/MemoEditor/state/actions.ts create mode 100644 web/src/components/MemoEditor/state/context.tsx create mode 100644 web/src/components/MemoEditor/state/index.ts create mode 100644 web/src/components/MemoEditor/state/reducer.ts create mode 100644 web/src/components/MemoEditor/state/types.ts create mode 100644 web/src/components/MemoEditor/types/attachment.ts create mode 100644 web/src/components/MemoEditor/types/components.ts create mode 100644 web/src/components/MemoEditor/types/index.ts create mode 100644 web/src/components/MemoEditor/types/insert-menu.ts create mode 100644 web/src/components/MemoEditor/utils/deriveDefaultCreateTime.ts create mode 100644 web/src/components/MemoExplorer/MemoExplorer.tsx create mode 100644 web/src/components/MemoExplorer/MemoExplorerDrawer.tsx create mode 100644 web/src/components/MemoExplorer/ShortcutsSection.tsx create mode 100644 web/src/components/MemoExplorer/TagsSection.tsx create mode 100644 web/src/components/MemoExplorer/index.ts create mode 100644 web/src/components/MemoFilters.tsx create mode 100644 web/src/components/MemoMetadata/Attachment/AttachmentCard.tsx create mode 100644 web/src/components/MemoMetadata/Attachment/AttachmentListEditor.tsx create mode 100644 web/src/components/MemoMetadata/Attachment/AttachmentListView.tsx create mode 100644 web/src/components/MemoMetadata/Attachment/AudioAttachmentItem.tsx create mode 100644 web/src/components/MemoMetadata/Attachment/attachmentHelpers.ts create mode 100644 web/src/components/MemoMetadata/Attachment/attachmentVisualClasses.ts create mode 100644 web/src/components/MemoMetadata/Attachment/index.ts create mode 100644 web/src/components/MemoMetadata/Attachment/visualGalleryLayout.ts create mode 100644 web/src/components/MemoMetadata/Location/LocationDialog.tsx create mode 100644 web/src/components/MemoMetadata/Location/LocationDisplayEditor.tsx create mode 100644 web/src/components/MemoMetadata/Location/LocationDisplayView.tsx create mode 100644 web/src/components/MemoMetadata/Location/index.ts create mode 100644 web/src/components/MemoMetadata/Location/locationHelpers.ts create mode 100644 web/src/components/MemoMetadata/MetadataSection.tsx create mode 100644 web/src/components/MemoMetadata/Relation/LinkMemoDialog.tsx create mode 100644 web/src/components/MemoMetadata/Relation/RelationCard.tsx create mode 100644 web/src/components/MemoMetadata/Relation/RelationListEditor.tsx create mode 100644 web/src/components/MemoMetadata/Relation/RelationListView.tsx create mode 100644 web/src/components/MemoMetadata/Relation/index.ts create mode 100644 web/src/components/MemoMetadata/Relation/relationHelpers.ts create mode 100644 web/src/components/MemoMetadata/Relation/useResolvedRelationMemos.ts create mode 100644 web/src/components/MemoMetadata/SectionHeader.tsx create mode 100644 web/src/components/MemoMetadata/index.ts create mode 100644 web/src/components/MemoPreview/MemoPreview.tsx create mode 100644 web/src/components/MemoPreview/index.ts create mode 100644 web/src/components/MemoReactionListView/MemoReactionListView.tsx create mode 100644 web/src/components/MemoReactionListView/ReactionSelector.tsx create mode 100644 web/src/components/MemoReactionListView/ReactionView.tsx create mode 100644 web/src/components/MemoReactionListView/hooks.ts create mode 100644 web/src/components/MemoReactionListView/index.ts create mode 100644 web/src/components/MemoView/MemoView.tsx create mode 100644 web/src/components/MemoView/MemoViewContext.tsx create mode 100644 web/src/components/MemoView/components/MemoBody.tsx create mode 100644 web/src/components/MemoView/components/MemoCommentListView.tsx create mode 100644 web/src/components/MemoView/components/MemoHeader.tsx create mode 100644 web/src/components/MemoView/components/MemoSnippetLink.tsx create mode 100644 web/src/components/MemoView/components/index.ts create mode 100644 web/src/components/MemoView/constants.ts create mode 100644 web/src/components/MemoView/hooks/index.ts create mode 100644 web/src/components/MemoView/hooks/useImagePreview.ts create mode 100644 web/src/components/MemoView/hooks/useMemoActions.ts create mode 100644 web/src/components/MemoView/hooks/useMemoHandlers.ts create mode 100644 web/src/components/MemoView/index.ts create mode 100644 web/src/components/MemoView/types.ts create mode 100644 web/src/components/MemosLogo.tsx create mode 100644 web/src/components/MobileHeader.tsx create mode 100644 web/src/components/MotionPhotoPlayer.tsx create mode 100644 web/src/components/MotionPhotoPreview.tsx create mode 100644 web/src/components/Navigation.tsx create mode 100644 web/src/components/NavigationDrawer.tsx create mode 100644 web/src/components/PagedMemoList/PagedMemoList.tsx create mode 100644 web/src/components/PagedMemoList/index.ts create mode 100644 web/src/components/PasswordSignInForm.tsx create mode 100644 web/src/components/Placeholder/TileSpriteStrip.tsx create mode 100644 web/src/components/Placeholder/index.tsx create mode 100644 web/src/components/Placeholder/messages.ts create mode 100644 web/src/components/Placeholder/pieces/DESIGN.md create mode 100644 web/src/components/Placeholder/pieces/EagleIdle.svg create mode 100644 web/src/components/Placeholder/pieces/OwlBlink.svg create mode 100644 web/src/components/Placeholder/pieces/ToucanIdle.svg create mode 100644 web/src/components/Placeholder/tileSprites.ts create mode 100644 web/src/components/PreviewImageDialog.tsx create mode 100644 web/src/components/RequiredBadge.tsx create mode 100644 web/src/components/SearchBar.tsx create mode 100644 web/src/components/Settings/AISection.tsx create mode 100644 web/src/components/Settings/AccessTokenSection.tsx create mode 100644 web/src/components/Settings/InfoChip.tsx create mode 100644 web/src/components/Settings/InstanceSection.tsx create mode 100644 web/src/components/Settings/LinkedIdentitySection.tsx create mode 100644 web/src/components/Settings/MemberSection.tsx create mode 100644 web/src/components/Settings/MemoRelatedSettings.tsx create mode 100644 web/src/components/Settings/MyAccountSection.tsx create mode 100644 web/src/components/Settings/NotificationSection.tsx create mode 100644 web/src/components/Settings/PreferencesSection.tsx create mode 100644 web/src/components/Settings/ResourceStatsSection.tsx create mode 100644 web/src/components/Settings/SSOSection.tsx create mode 100644 web/src/components/Settings/SectionMenuItem.tsx create mode 100644 web/src/components/Settings/SettingGroup.tsx create mode 100644 web/src/components/Settings/SettingList.tsx create mode 100644 web/src/components/Settings/SettingRow.tsx create mode 100644 web/src/components/Settings/SettingSection.tsx create mode 100644 web/src/components/Settings/SettingTable.tsx create mode 100644 web/src/components/Settings/StorageSection.tsx create mode 100644 web/src/components/Settings/TagsSection.tsx create mode 100644 web/src/components/Settings/WebhookSection.tsx create mode 100644 web/src/components/Settings/settingSections.ts create mode 100644 web/src/components/Settings/useInstanceSettingUpdater.ts create mode 100644 web/src/components/Skeleton.tsx create mode 100644 web/src/components/StatisticsView/MonthNavigator.tsx create mode 100644 web/src/components/StatisticsView/StatisticsView.tsx create mode 100644 web/src/components/StatisticsView/index.ts create mode 100644 web/src/components/TagTree.tsx create mode 100644 web/src/components/ThemeSelect.tsx create mode 100644 web/src/components/UpdateAccountDialog.tsx create mode 100644 web/src/components/UpdateCustomizedProfileDialog.tsx create mode 100644 web/src/components/UserAvatar.tsx create mode 100644 web/src/components/UserMemoMap/UserMemoMap.tsx create mode 100644 web/src/components/UserMemoMap/index.ts create mode 100644 web/src/components/UserMenu.tsx create mode 100644 web/src/components/VideoPoster.tsx create mode 100644 web/src/components/VisibilityIcon.tsx create mode 100644 web/src/components/kit/OverflowTip.tsx create mode 100644 web/src/components/kit/SquareDiv.tsx create mode 100644 web/src/components/map/LazyLocationPicker.tsx create mode 100644 web/src/components/map/LocationPicker.tsx create mode 100644 web/src/components/map/index.ts create mode 100644 web/src/components/map/map-utils.tsx create mode 100644 web/src/components/map/types.ts create mode 100644 web/src/components/map/useReverseGeocoding.ts create mode 100644 web/src/components/ui/badge.tsx create mode 100644 web/src/components/ui/button.tsx create mode 100644 web/src/components/ui/checkbox.tsx create mode 100644 web/src/components/ui/dialog.tsx create mode 100644 web/src/components/ui/dropdown-menu.tsx create mode 100644 web/src/components/ui/input.tsx create mode 100644 web/src/components/ui/label.tsx create mode 100644 web/src/components/ui/popover.tsx create mode 100644 web/src/components/ui/radio-group.tsx create mode 100644 web/src/components/ui/select.tsx create mode 100644 web/src/components/ui/separator.tsx create mode 100644 web/src/components/ui/sheet.tsx create mode 100644 web/src/components/ui/switch.tsx create mode 100644 web/src/components/ui/textarea.tsx create mode 100644 web/src/components/ui/tooltip.tsx create mode 100644 web/src/components/ui/visually-hidden.tsx create mode 100644 web/src/connect.ts create mode 100644 web/src/contexts/AuthContext.tsx create mode 100644 web/src/contexts/InstanceContext.tsx create mode 100644 web/src/contexts/MemoFilterContext.tsx create mode 100644 web/src/contexts/ViewContext.tsx create mode 100644 web/src/helpers/consts.ts create mode 100644 web/src/helpers/resource-names.ts create mode 100644 web/src/helpers/sso-display.ts create mode 100644 web/src/helpers/utils.ts create mode 100644 web/src/hooks/index.ts create mode 100644 web/src/hooks/useAsyncEffect.ts create mode 100644 web/src/hooks/useAttachmentLibrary.ts create mode 100644 web/src/hooks/useAttachmentQueries.ts create mode 100644 web/src/hooks/useCurrentUser.ts create mode 100644 web/src/hooks/useDateFilterNavigation.ts create mode 100644 web/src/hooks/useDebouncedEffect.ts create mode 100644 web/src/hooks/useDialog.ts create mode 100644 web/src/hooks/useFilteredMemoStats.ts create mode 100644 web/src/hooks/useInstanceQueries.ts create mode 100644 web/src/hooks/useLiveMemoRefresh.ts create mode 100644 web/src/hooks/useLoading.ts create mode 100644 web/src/hooks/useLocalStorage.ts create mode 100644 web/src/hooks/useMediaQuery.ts create mode 100644 web/src/hooks/useMemoDetailError.ts create mode 100644 web/src/hooks/useMemoFilters.ts create mode 100644 web/src/hooks/useMemoQueries.ts create mode 100644 web/src/hooks/useMemoShareQueries.ts create mode 100644 web/src/hooks/useMemoSorting.ts create mode 100644 web/src/hooks/useNavigateTo.ts create mode 100644 web/src/hooks/useTokenRefreshOnFocus.ts create mode 100644 web/src/hooks/useUserLocale.ts create mode 100644 web/src/hooks/useUserQueries.ts create mode 100644 web/src/hooks/useUserTheme.ts create mode 100644 web/src/i18n.ts create mode 100644 web/src/index.css create mode 100644 web/src/layouts/MainLayout.tsx create mode 100644 web/src/layouts/RootLayout.tsx create mode 100644 web/src/lib/calendar-utils.ts create mode 100644 web/src/lib/color.ts create mode 100644 web/src/lib/error.ts create mode 100644 web/src/lib/query-client.ts create mode 100644 web/src/lib/tag.ts create mode 100644 web/src/lib/utils.ts create mode 100644 web/src/locales/ar.json create mode 100644 web/src/locales/ca.json create mode 100644 web/src/locales/cs.json create mode 100644 web/src/locales/de.json create mode 100644 web/src/locales/en-GB.json create mode 100644 web/src/locales/en.json create mode 100644 web/src/locales/es.json create mode 100644 web/src/locales/fa.json create mode 100644 web/src/locales/fr.json create mode 100644 web/src/locales/gl.json create mode 100644 web/src/locales/hi.json create mode 100644 web/src/locales/hr.json create mode 100644 web/src/locales/hu.json create mode 100644 web/src/locales/id.json create mode 100644 web/src/locales/it.json create mode 100644 web/src/locales/ja.json create mode 100644 web/src/locales/ka-GE.json create mode 100644 web/src/locales/ko.json create mode 100644 web/src/locales/mr.json create mode 100644 web/src/locales/nb.json create mode 100644 web/src/locales/nl.json create mode 100644 web/src/locales/pl.json create mode 100644 web/src/locales/pt-BR.json create mode 100644 web/src/locales/pt-PT.json create mode 100644 web/src/locales/ru.json create mode 100644 web/src/locales/sl.json create mode 100644 web/src/locales/sv.json create mode 100644 web/src/locales/th.json create mode 100644 web/src/locales/tr.json create mode 100644 web/src/locales/uk.json create mode 100644 web/src/locales/vi.json create mode 100644 web/src/locales/zh-Hans.json create mode 100644 web/src/locales/zh-Hant.json create mode 100644 web/src/main.tsx create mode 100644 web/src/pages/About.tsx create mode 100644 web/src/pages/AdminSignIn.tsx create mode 100644 web/src/pages/Archived.tsx create mode 100644 web/src/pages/Attachments.tsx create mode 100644 web/src/pages/AuthCallback.tsx create mode 100644 web/src/pages/Explore.tsx create mode 100644 web/src/pages/Home.tsx create mode 100644 web/src/pages/Inboxes.tsx create mode 100644 web/src/pages/MemoDetail.tsx create mode 100644 web/src/pages/NotFound.tsx create mode 100644 web/src/pages/PermissionDenied.tsx create mode 100644 web/src/pages/Setting.tsx create mode 100644 web/src/pages/Shortcuts.tsx create mode 100644 web/src/pages/SignIn.tsx create mode 100644 web/src/pages/SignUp.tsx create mode 100644 web/src/pages/UserProfile.tsx create mode 100644 web/src/router/guards.tsx create mode 100644 web/src/router/index.tsx create mode 100644 web/src/router/routes.ts create mode 100644 web/src/themes/COLOR_GUIDE.md create mode 100644 web/src/themes/default-dark.css create mode 100644 web/src/themes/default.css create mode 100644 web/src/themes/paper.css create mode 100644 web/src/types/common.d.ts create mode 100644 web/src/types/common.ts create mode 100644 web/src/types/i18n.d.ts create mode 100644 web/src/types/markdown.ts create mode 100644 web/src/types/modules/setting.d.ts create mode 100644 web/src/types/proto/api/v1/ai_service_pb.ts create mode 100644 web/src/types/proto/api/v1/attachment_service_pb.ts create mode 100644 web/src/types/proto/api/v1/auth_service_pb.ts create mode 100644 web/src/types/proto/api/v1/common_pb.ts create mode 100644 web/src/types/proto/api/v1/idp_service_pb.ts create mode 100644 web/src/types/proto/api/v1/instance_service_pb.ts create mode 100644 web/src/types/proto/api/v1/memo_service_pb.ts create mode 100644 web/src/types/proto/api/v1/shortcut_service_pb.ts create mode 100644 web/src/types/proto/api/v1/user_service_pb.ts create mode 100644 web/src/types/proto/google/api/annotations_pb.ts create mode 100644 web/src/types/proto/google/api/client_pb.ts create mode 100644 web/src/types/proto/google/api/field_behavior_pb.ts create mode 100644 web/src/types/proto/google/api/http_pb.ts create mode 100644 web/src/types/proto/google/api/launch_stage_pb.ts create mode 100644 web/src/types/proto/google/api/resource_pb.ts create mode 100644 web/src/types/proto/google/type/color_pb.ts create mode 100644 web/src/types/relative-time-element.d.ts create mode 100644 web/src/types/statistics.ts create mode 100644 web/src/types/view.d.ts create mode 100644 web/src/utils/attachment.ts create mode 100644 web/src/utils/auth-redirect.ts create mode 100644 web/src/utils/format.ts create mode 100644 web/src/utils/i18n.ts create mode 100644 web/src/utils/markdown-list-detection.ts create mode 100644 web/src/utils/markdown-manipulation.ts create mode 100644 web/src/utils/markdown-task-actions.ts create mode 100644 web/src/utils/media-item.ts create mode 100644 web/src/utils/memo.ts create mode 100644 web/src/utils/oauth.ts create mode 100644 web/src/utils/redirect-safety.ts create mode 100644 web/src/utils/rehype-plugins/rehype-heading-id.ts create mode 100644 web/src/utils/remark-plugins/remark-disable-setext.ts create mode 100644 web/src/utils/remark-plugins/remark-mention.ts create mode 100644 web/src/utils/remark-plugins/remark-preserve-type.ts create mode 100644 web/src/utils/remark-plugins/remark-split-mixed-task-lists.ts create mode 100644 web/src/utils/remark-plugins/remark-tag.ts create mode 100644 web/src/utils/theme.ts create mode 100644 web/src/utils/user.ts create mode 100644 web/src/utils/uuid.ts create mode 100644 web/tests/about-page.test.tsx create mode 100644 web/tests/activity-calendar-tooltip.test.ts create mode 100644 web/tests/auth-redirect.test.ts create mode 100644 web/tests/calendar-cell-empty-clickable.test.tsx create mode 100644 web/tests/derive-default-create-time.test.ts create mode 100644 web/tests/filtered-memo-stats.test.ts create mode 100644 web/tests/guards.test.tsx create mode 100644 web/tests/hooks.test.tsx create mode 100644 web/tests/location-picker.test.tsx create mode 100644 web/tests/markdown-task-actions.test.ts create mode 100644 web/tests/memo-content-list.test.tsx create mode 100644 web/tests/memo-content-paragraph.test.tsx create mode 100644 web/tests/memo-content-security.test.tsx create mode 100644 web/tests/memo-editor-cache.test.ts create mode 100644 web/tests/memo-editor-paste.test.tsx create mode 100644 web/tests/memo-share-image.test.ts create mode 100644 web/tests/mermaid-block.test.tsx create mode 100644 web/tests/oauth.test.ts create mode 100644 web/tests/paged-memo-list.test.tsx create mode 100644 web/tests/placeholder-component.test.tsx create mode 100644 web/tests/placeholder-pool.test.ts create mode 100644 web/tests/preview-image-dialog.test.tsx create mode 100644 web/tests/redirect-safety.test.ts create mode 100644 web/tests/router-config.test.tsx create mode 100644 web/tests/setup.ts create mode 100644 web/tests/video-poster.test.tsx create mode 100644 web/tsconfig.json create mode 100644 web/vite.config.mts create mode 100644 web/vitest.config.mts diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..d465134 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,13 @@ +web/node_modules +web/dist +.git +.github +build/ +tmp/ +memos +*.md +.gitignore +.golangci.yaml +.dockerignore +docs/ +.DS_Store \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6b0f279 --- /dev/null +++ b/.gitignore @@ -0,0 +1,33 @@ +# temp folder +tmp + +# Frontend asset +web/dist + +# Build artifacts +build/ +bin/ +memos + +.DS_Store + +# Jetbrains +.idea + +# Docker Compose Environment File +.env + +dist + +# VSCode settings +.vscode + +# Git worktrees +.worktrees/ + +# Local pnpm store (project-scoped, created when --config.store-dir is set +# without an existing store; contains a symlink back to the workspace). +.pnpm-store/ + +# Frontend test coverage output (Vitest + @vitest/coverage-v8). +web/coverage/ diff --git a/.golangci.yaml b/.golangci.yaml new file mode 100644 index 0000000..b97938f --- /dev/null +++ b/.golangci.yaml @@ -0,0 +1,101 @@ +version: "2" + +linters: + enable: + - revive + - govet + - staticcheck + - misspell + - gocritic + - sqlclosecheck + - rowserrcheck + - nilerr + - godot + - forbidigo + - mirror + - bodyclose + disable: + - errcheck + settings: + exhaustive: + explicit-exhaustive-switch: false + staticcheck: + checks: + - all + - -ST1000 + - -ST1003 + - -ST1021 + - -QF1003 + revive: + # Default to run all linters so that new rules in the future could automatically be added to the static check. + enable-all-rules: true + rules: + # The following rules are too strict and make coding harder. We do not enable them for now. + - name: file-header + disabled: true + - name: line-length-limit + disabled: true + - name: function-length + disabled: true + - name: max-public-structs + disabled: true + - name: function-result-limit + disabled: true + - name: banned-characters + disabled: true + - name: argument-limit + disabled: true + - name: cognitive-complexity + disabled: true + - name: cyclomatic + disabled: true + - name: confusing-results + disabled: true + - name: add-constant + disabled: true + - name: flag-parameter + disabled: true + - name: nested-structs + disabled: true + - name: import-shadowing + disabled: true + - name: early-return + disabled: true + - name: use-any + disabled: true + - name: exported + disabled: true + - name: unhandled-error + disabled: true + - name: if-return + disabled: true + - name: max-control-nesting + disabled: true + - name: redefines-builtin-id + disabled: true + - name: package-comments + disabled: true + gocritic: + disabled-checks: + - ifElseChain + govet: + settings: + printf: # The name of the analyzer, run `go tool vet help` to see the list of all analyzers + funcs: # Run `go tool vet help printf` to see the full configuration of `printf`. + - common.Errorf + enable-all: true + disable: + - fieldalignment + - shadow + forbidigo: + forbid: + - pattern: 'fmt\.Errorf(# Please use errors\.Wrap\|Wrapf\|Errorf instead)?' + - pattern: 'ioutil\.ReadDir(# Please use os\.ReadDir)?' + +formatters: + enable: + - goimports + settings: + goimports: + local-prefixes: + - github.com/usememos/memos diff --git a/.release-please-manifest.json b/.release-please-manifest.json new file mode 100644 index 0000000..712789e --- /dev/null +++ b/.release-please-manifest.json @@ -0,0 +1,3 @@ +{ + ".": "0.29.1" +} diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..fb12935 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,106 @@ +# AGENTS.md + +This file provides guidance to AI coding agents when working with code in this repository. + +Self-hosted note-taking tool. Go 1.26 backend (Echo v5, Connect RPC + gRPC-Gateway), React 18 + TypeScript 6 + Vite 7 frontend, Protocol Buffers API, SQLite/MySQL/PostgreSQL. + +## Commands + +```bash +# Backend +go run ./cmd/memos --port 8081 # Start dev server +go test ./... # Run all tests +go test -v ./store/... # Run store tests (all 3 DB drivers via TestContainers) +go test -v -race ./server/... # Run server tests with race detection +go test -v -race ./internal/... # Run internal package tests with race detection +go test -v -run TestFoo ./pkg/... # Run a single test +go mod tidy -go=1.26.2 # Match CI tidy check +golangci-lint run # Lint (v2, config: .golangci.yaml) +golangci-lint run --fix # Auto-fix lint issues (includes goimports) + +# Frontend (cd web) +pnpm install # Install deps +pnpm dev # Dev server (:3001, proxies API to :8081) +pnpm lint # Type check + Biome lint +pnpm lint:fix # Auto-fix lint issues +pnpm format # Format code +pnpm build # Production build +pnpm release # Build to server/router/frontend/dist + +# Protocol Buffers (cd proto) +buf generate # Regenerate Go + TypeScript + OpenAPI +buf lint # Lint proto files +buf format -w # Format proto files +``` + +## Architecture + +``` +cmd/memos/main.go # Cobra CLI + Viper config, server init + +server/ +├── server.go # Echo v5 HTTP server, background runners +├── auth/ # JWT access (15min) + refresh (30d) tokens, PAT +├── router/ +│ ├── api/v1/ # 8 gRPC services (Connect + Gateway) +│ │ ├── acl_config.go # Public endpoints whitelist +│ │ ├── sse_hub.go # Server-Sent Events (live updates) +│ │ └── mcp/ # MCP server for AI assistants +│ ├── frontend/ # SPA static file serving +│ ├── fileserver/ # Native HTTP file server (thumbnails, range requests) +│ └── rss/ # RSS feeds +└── runner/ # Background: memo payload processing, S3 presign refresh + +store/ +├── driver.go # Database driver interface +├── store.go # Store wrapper + in-memory cache (TTL 10min, max 1000) +├── migrator.go # Migration logic (LATEST.sql for fresh, incremental for upgrades) +└── db/{sqlite,mysql,postgres}/ # Driver implementations + +proto/ +├── api/v1/ # Service definitions +├── store/ # Internal storage messages +└── gen/ # Generated Go, TypeScript, OpenAPI + +internal/ # app-private packages: scheduler, cron, email, filter (CEL), + # webhook, markdown (Goldmark), httpgetter, idp (OAuth2), storage/s3 + +web/src/ +├── connect.ts # Connect RPC client + auth interceptor + token refresh +├── auth-state.ts # Token storage (localStorage + BroadcastChannel cross-tab) +├── contexts/ # AuthContext, InstanceContext, ViewContext, MemoFilterContext +├── hooks/ # React Query hooks (useMemoQueries, useUserQueries, etc.) +├── lib/query-client.ts # React Query v5 (staleTime: 30s, gcTime: 5min) +├── router/index.tsx # Route definitions +├── components/ # UI components (Radix UI primitives, MemoEditor, Settings, etc.) +├── themes/ # CSS themes (default, dark, paper) — OKLch color tokens +└── pages/ # Page components +``` + +## Conventions + +### Go +- **Errors:** `errors.Wrap(err, "context")` from `github.com/pkg/errors`. Never `fmt.Errorf` (lint-enforced via forbidigo). +- **gRPC errors:** `status.Errorf(codes.X, "message")` from service methods. +- **Imports:** stdlib, then third-party, then local (`github.com/usememos/memos`). Enforced by goimports (runs as golangci-lint formatter). +- **Comments:** All exported functions must have doc comments (godot enforced). + +### Frontend +- **Imports:** Use `@/` alias for absolute imports. +- **Formatting:** Biome — 140 char lines, double quotes, always semicolons, 2-space indent. +- **State:** Server data via React Query hooks (`hooks/`). Client state via React Context (`contexts/`). +- **Styling:** Tailwind CSS v4 (`@tailwindcss/vite`), `cn()` utility (clsx + tailwind-merge), CVA for variants. + +### Database & Proto +- **DB changes:** Migration files for all 3 drivers + update `LATEST.sql`. +- **Proto changes:** Run `buf generate`. Generated code: `proto/gen/` and `web/src/types/proto/`. +- **Public endpoints:** Add to `server/router/api/v1/acl_config.go`. + +## CI/CD + +- **backend-tests.yml:** Go 1.26.2, `go mod tidy -go=1.26.2`, golangci-lint v2.11.3, tests parallelized by group (store, server, internal, other) +- **build-canary-image.yml:** Builds frontend with `pnpm release`, then publishes canary multi-arch container images for linux/amd64 and linux/arm64 +- **frontend-tests.yml:** Node 24, pnpm 11, lint + build +- **proto-linter.yml:** buf lint + format check +- **release.yml:** On version tags, builds frontend once, packages binaries for Linux/macOS/Windows, and publishes release container images/tags +- **Docker:** Multi-stage (`scripts/Dockerfile`), Alpine 3.21, non-root user, port 5230, multi-arch (amd64/arm64/arm/v7) diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..8832d6e --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,183 @@ +# Changelog + +## [0.29.1](https://github.com/usememos/memos/compare/v0.29.0...v0.29.1) (2026-06-04) + + +### Bug Fixes + +* **markdown:** keep task item content in one grid column ([7c3bff4](https://github.com/usememos/memos/commit/7c3bff4e98223fb99a5d49f093e3cd57dd140ba4)) +* support <meta name=description> in link previews ([#6000](https://github.com/usememos/memos/issues/6000)) ([e8d32e8](https://github.com/usememos/memos/commit/e8d32e87d1d6e4927250ad5794ba5965e0260153)) +* **web:** render video attachment posters on mobile ([0e2a9a9](https://github.com/usememos/memos/commit/0e2a9a9c0ce0e2da63535210c553b3ae2f79b239)) + +## [0.29.0](https://github.com/usememos/memos/compare/v0.28.0...v0.29.0) (2026-05-27) + + +### Features + +* **about:** add about page with bird sprites ([411ba7b](https://github.com/usememos/memos/commit/411ba7b34c0c23ad217a7897835097887a28a036)) +* **activity-calendar:** aggregate by ViewContext.timeBasis ([8daef1d](https://github.com/usememos/memos/commit/8daef1dc89544512fff78fd64d8216b2babc2e42)) +* add <Placeholder> component with ASCII bird states ([#5949](https://github.com/usememos/memos/issues/5949)) ([8c16ffa](https://github.com/usememos/memos/commit/8c16ffa1f1410f9413cb57ebe251b4b604f9aeff)) +* add configurable `--log-level` flag ([#5934](https://github.com/usememos/memos/issues/5934)) ([f1e2a06](https://github.com/usememos/memos/commit/f1e2a06b46c7f45ba6562c308d2703fdfb4067b0)) +* add dedicated shortcuts page ([#5942](https://github.com/usememos/memos/issues/5942)) ([1df6479](https://github.com/usememos/memos/commit/1df6479443c334732b862d60a0f76e61f00ebb89)) +* add link metadata endpoints ([9c5c604](https://github.com/usememos/memos/commit/9c5c604944428d3f682f35c9d05a87c1d4c3152f)) +* **frontend:** add pixel bird tilemaps ([cf55f11](https://github.com/usememos/memos/commit/cf55f1107273c928e7c2d6bc26df5f3efea26458)) +* **memo:** add task list quick actions ([#5983](https://github.com/usememos/memos/issues/5983)) ([648b3bd](https://github.com/usememos/memos/commit/648b3bd812e5bf2b1abb9f8b3529efefe4734e7c)) +* **memo:** create memos on the selected calendar date ([#5925](https://github.com/usememos/memos/issues/5925)) ([ef55013](https://github.com/usememos/memos/commit/ef55013418d68e2d6a24a6d02a0365c1ffff03d7)) +* **notification:** add smtp email settings ([cd4f28a](https://github.com/usememos/memos/commit/cd4f28ae1058a125e245ea0a6eae16aea71b8f9d)) +* **placeholder:** add woodpecker tilemap ([638e4f3](https://github.com/usememos/memos/commit/638e4f398e90c556f70af150a79538312c8fc760)) +* render link metadata cards ([0bc5669](https://github.com/usememos/memos/commit/0bc56694b0ca347ab1eb083f62997a22007b763d)) +* **stats:** admin instance resource statistics ([ea0625d](https://github.com/usememos/memos/commit/ea0625da45a419e08158ab4102051f3fe5e59b87)) +* **stats:** support filtered all-user stats ([88ac3ec](https://github.com/usememos/memos/commit/88ac3ec31ee3e808db82663c04a31cf730d1221e)) +* **transcription:** explicit STT settings with provider, model, prompt ([#5926](https://github.com/usememos/memos/issues/5926)) ([238f27d](https://github.com/usememos/memos/commit/238f27dea149492a78a8994470b0aac55fece78d)) + + +### Bug Fixes + +* avoid update event on memo create attachments ([#5961](https://github.com/usememos/memos/issues/5961)) ([3c3382a](https://github.com/usememos/memos/commit/3c3382a3c652bed3b58058931ff3cbf1d875b9a8)) +* delete user cleanup ([#5981](https://github.com/usememos/memos/issues/5981)) ([e53b7d9](https://github.com/usememos/memos/commit/e53b7d96e70965529ba3b04ea720ea6966f77b60)) +* **editor:** wrap selected text when pasting URL ([e0bb3a2](https://github.com/usememos/memos/commit/e0bb3a2e684e932309df2f9fb0ff774ce8e6b692)) +* **fileserver:** preserve HDR image metadata in thumbnails ([c724232](https://github.com/usememos/memos/commit/c7242324a18962e453e7f2a0309a7c07b358bdbe)) +* **frontend:** correct static cache headers ([084f40b](https://github.com/usememos/memos/commit/084f40bc9e5922ff2d41c08dce837b96696437aa)) +* **frontend:** use correct url path for memos in sitemap.xml ([#5921](https://github.com/usememos/memos/issues/5921)) ([603781f](https://github.com/usememos/memos/commit/603781f792b2603fbda93146988a64a93c92d760)) +* **httpgetter:** prevent DNS rebinding in link metadata fetch ([078488c](https://github.com/usememos/memos/commit/078488ca818626fbcab69bdfb4b93b58dca6b6eb)) +* **markdown:** align list items with checkboxes ([e008b1a](https://github.com/usememos/memos/commit/e008b1a23c77945eff87707eb15578d4d6d74e4c)) +* **memo:** enforce parent visibility for comments ([4a1e401](https://github.com/usememos/memos/commit/4a1e401bd99c7850ac48e9693b25c9ebeecfb042)) +* **s3presign:** preserve motion media payload ([7f1f53f](https://github.com/usememos/memos/commit/7f1f53ffc417962f6930d1e6e3783eacd911003d)) +* **security:** enforce attachment ownership on memo updates ([35bf761](https://github.com/usememos/memos/commit/35bf761b8c2c3f155bdc06e9b373b6076116a725)) +* **sse:** stream initial response and refresh tokens ([21303e8](https://github.com/usememos/memos/commit/21303e879d2c7a857306206d2cbdae83f61983e6)) +* **user:** omit internal settings from list responses ([#5917](https://github.com/usememos/memos/issues/5917)) ([1df3fe7](https://github.com/usememos/memos/commit/1df3fe79559ccf94b6c71e9ffb58e870ed43820d)) +* **web:** sync avatar changes immediately after profile update ([#5903](https://github.com/usememos/memos/issues/5903)) ([328396a](https://github.com/usememos/memos/commit/328396a97f2219592032e8418c383e0ab7edaca6)) + + +### Performance Improvements + +* lazy load heavy first-screen dependencies ([#5947](https://github.com/usememos/memos/issues/5947)) ([a6024ee](https://github.com/usememos/memos/commit/a6024eebf129c4b8fb65ee0cba09c6657274bfde)) + +## [0.28.0](https://github.com/usememos/memos/compare/v0.27.1...v0.28.0) (2026-04-27) + + +### Features + +* **auth:** add SSO user identity linkage ([#5883](https://github.com/usememos/memos/issues/5883)) ([d688914](https://github.com/usememos/memos/commit/d688914b2864791eeadbf21c882608632875f17c)) +* **memos:** choose created or updated time for memos ([#5894](https://github.com/usememos/memos/issues/5894)) ([c268551](https://github.com/usememos/memos/commit/c268551a16929a2cbea6891951feff91926bba59)) +* redesign account and SSO management ([#5886](https://github.com/usememos/memos/issues/5886)) ([ee17998](https://github.com/usememos/memos/commit/ee1799851e88674a6920c7a56d93428fcf95e662)) + + +### Bug Fixes + +* **auth:** harden authorization and username validation ([#5890](https://github.com/usememos/memos/issues/5890)) ([0fb83a7](https://github.com/usememos/memos/commit/0fb83a745dd5057ade45a3caad2c444af2239113)) +* disable modal prop on DropdownMenu to prevent scroll disappearing ([#5861](https://github.com/usememos/memos/issues/5861)) ([d98f665](https://github.com/usememos/memos/commit/d98f6659190b8d1a8252e64549d9120d85e05d33)) +* fix legacy username auth flows ([#5885](https://github.com/usememos/memos/issues/5885)) ([30c0611](https://github.com/usememos/memos/commit/30c0611a82f9254952a74650095105254f2940e4)) +* **markdown:** split mixed task and bullet lists ([e2c6084](https://github.com/usememos/memos/commit/e2c60845eaff9a78b8d8eb3ccc9a067ef5690976)) +* reduce list memo query overhead ([#5880](https://github.com/usememos/memos/issues/5880)) ([5063804](https://github.com/usememos/memos/commit/50638040f618b02b0c6d010e1d41554c75067517)) +* **web:** preserve task checkbox state ([#5867](https://github.com/usememos/memos/issues/5867)) ([b5863d7](https://github.com/usememos/memos/commit/b5863d76be3cfbf3e0f8237d8e762122b5a0a679)) + +## [0.27.1](https://github.com/usememos/memos/compare/v0.27.0...v0.27.1) (2026-04-19) + + +### Bug Fixes + +* mixed-case user resource names ([#5853](https://github.com/usememos/memos/issues/5853)) ([01be01f](https://github.com/usememos/memos/commit/01be01f4b7676af41bdd1758b1e9b096aa922546)) +* **release:** inject build version into artifacts ([f8a304b](https://github.com/usememos/memos/commit/f8a304bae33086320b39095d631288156eec4249)) +* user resource names can be uuidv4 from idp sub claim ([#5856](https://github.com/usememos/memos/issues/5856)) ([bbded58](https://github.com/usememos/memos/commit/bbded584ce85a856d863485768e08b53adec7244)) + +## [0.27.0](https://github.com/usememos/memos/compare/v0.26.2...v0.27.0) (2026-04-18) + + +### Features + +* add --allow-private-webhooks flag to bypass SSRF protection ([#5694](https://github.com/usememos/memos/issues/5694)) ([cd5816c](https://github.com/usememos/memos/commit/cd5816c428931f56561f7d48b649a33858812539)) +* add blur_content attribute to tag metadata settings ([#5767](https://github.com/usememos/memos/issues/5767)) ([45b2153](https://github.com/usememos/memos/commit/45b21530d9ebbc730e77bcbcf407f4c295b52e93)) +* add Gemini transcription provider ([#5830](https://github.com/usememos/memos/issues/5830)) ([d87539a](https://github.com/usememos/memos/commit/d87539a1e1261590ab355220e33fa0ae00bd9431)) +* add GitHub release installer and release workflow ([1ed542c](https://github.com/usememos/memos/commit/1ed542c21db421e9aa0cc47417a92c6bd103e257)) +* add live refresh via Server-Sent Events (SSE) with visual indicator ([#5638](https://github.com/usememos/memos/issues/5638)) ([ea0892a](https://github.com/usememos/memos/commit/ea0892a8b26d8806a093e3a942562dfc22794f68)) +* add MCP server with PAT authentication ([47d9414](https://github.com/usememos/memos/commit/47d9414702dc18966af385352b960bfe451511b7)) +* add outline navigation to memo detail sidebar ([#5771](https://github.com/usememos/memos/issues/5771)) ([6b30579](https://github.com/usememos/memos/commit/6b3057990396f9cb6f21706c2e99dddebc35ffd5)) +* **ai:** add BYOK audio transcription ([#5832](https://github.com/usememos/memos/issues/5832)) ([101704c](https://github.com/usememos/memos/commit/101704c8eac17c7f34508d8db6c53bc972061cdb)) +* **ai:** add instance AI providers and transcription ([#5829](https://github.com/usememos/memos/issues/5829)) ([83ed32f](https://github.com/usememos/memos/commit/83ed32f1195841d2d6c057c3e00086a3147879a2)) +* **attachments:** add Live Photo and Motion Photo support ([#5810](https://github.com/usememos/memos/issues/5810)) ([4b4e719](https://github.com/usememos/memos/commit/4b4e719470184e49cd62084b1aa53c9a777a9fec)) +* **cli:** add version subcommand ([#5731](https://github.com/usememos/memos/issues/5731)) ([0ba4c0f](https://github.com/usememos/memos/commit/0ba4c0f397c532a5a314f35ddeb3ce3633e84d42)) +* **editor:** add voice note recording to the memo composer ([#5801](https://github.com/usememos/memos/issues/5801)) ([c0d5854](https://github.com/usememos/memos/commit/c0d5854f678f357cf4054d448e0311f2ee90f8ac)) +* extract title from first H1 heading into memo property ([#5726](https://github.com/usememos/memos/issues/5726)) ([1e688b2](https://github.com/usememos/memos/commit/1e688b2a5d78c2972f4b0078a7b033dae5d1cbf3)) +* **i18n:** update sse connect label in Chinese ([#5732](https://github.com/usememos/memos/issues/5732)) ([89c6902](https://github.com/usememos/memos/commit/89c69028953fa33dbb6e0e257d764636c0fc2d09)) +* **instance:** add canonical tag metadata setting ([#5736](https://github.com/usememos/memos/issues/5736)) ([65d14fb](https://github.com/usememos/memos/commit/65d14fbb63053fc1fbf1f63881c81adbc9d01671)) +* **instance:** add notification transport setting ([#5737](https://github.com/usememos/memos/issues/5737)) ([a249d06](https://github.com/usememos/memos/commit/a249d06e2e0f33e0e3fea34471a891352dacc466)) +* **mcp:** enhance MCP server with full capabilities and new tools ([#5720](https://github.com/usememos/memos/issues/5720)) ([b8e9ee2](https://github.com/usememos/memos/commit/b8e9ee2b26a59e1b19aab6db3ca39656fc18785a)) +* **mcp:** harden tool exposure and side effects ([#5850](https://github.com/usememos/memos/issues/5850)) ([583c3d2](https://github.com/usememos/memos/commit/583c3d24f4d785faa5e034c1b88ed90eda119baa)) +* **mcp:** refactor MCP server to standard protocol structure ([803d488](https://github.com/usememos/memos/commit/803d488a5f8f55477cd3ad4cc4cf0fac98901dd3)) +* **memo-editor:** add compact live waveform recorder panel ([#5817](https://github.com/usememos/memos/issues/5817)) ([e51985a](https://github.com/usememos/memos/commit/e51985a29ffeeecd318b2fb793358ed45bb0eff4)) +* **memo-preview:** support comment metadata in previews ([#5768](https://github.com/usememos/memos/issues/5768)) ([e176b28](https://github.com/usememos/memos/commit/e176b28c801cc3bb3718208a96a7d64c36620d0f)) +* **memo:** add image sharing in detail view ([38fc22b](https://github.com/usememos/memos/commit/38fc22b7541b8a9ddcd848cf77054fcf844eb87f)) +* **memo:** add share links for private memos ([#5742](https://github.com/usememos/memos/issues/5742)) ([3f3133d](https://github.com/usememos/memos/commit/3f3133d6e2f404061e147f9dd2424680dc0303a3)) +* **mentions:** add memo mention parsing, notifications, and rendering ([#5811](https://github.com/usememos/memos/issues/5811)) ([24fc8ab](https://github.com/usememos/memos/commit/24fc8ab8ca68d092e7b12a5d51c48ca9420f72b5)) +* replace auto-increment ID with UID for identity provider resource names ([#5687](https://github.com/usememos/memos/issues/5687)) ([92d937b](https://github.com/usememos/memos/commit/92d937b1aa87365152edc005a3b736e6bf9b9e45)) +* show inline comment preview in list view ([3a5d3c8](https://github.com/usememos/memos/commit/3a5d3c8ff92ae5c24559dc4574300d6475820a87)) +* **store:** change default storage type to local filesystem ([78efa68](https://github.com/usememos/memos/commit/78efa6802e2fd96c981e86c5b658fb4b5c05091f)) +* treat tag setting keys as anchored regex patterns ([#5759](https://github.com/usememos/memos/issues/5759)) ([9e04049](https://github.com/usememos/memos/commit/9e04049632e63f1cf53535773f170c1aa5af7168)) +* **ui:** allow navigating between images with arrows in preview dialog ([#5669](https://github.com/usememos/memos/issues/5669)) ([104d2ec](https://github.com/usememos/memos/commit/104d2ec0a6973e983c46724165fdc0916515ad16)) +* **user:** add per-user tag metadata settings ([#5735](https://github.com/usememos/memos/issues/5735)) ([330291d](https://github.com/usememos/memos/commit/330291d4d9fa95649e940001898929b4f6f0367e)) +* **web:** add demo mode banner ([#5836](https://github.com/usememos/memos/issues/5836)) ([35504cc](https://github.com/usememos/memos/commit/35504cc8bd6f9921291fb565633d549388a3f948)) +* **webhook:** dispatch webhook on memo comment creation ([7c1defb](https://github.com/usememos/memos/commit/7c1defba01fbc91cc81e1a0841cecb6738056db7)) + + +### Bug Fixes + +* access token refresh on web app ([#5681](https://github.com/usememos/memos/issues/5681)) ([3010f10](https://github.com/usememos/memos/commit/3010f10eafb49af5aadd71a94b3ef7a6ec71f617)) +* add unix socket file permission setting (755 -> 660) ([#5849](https://github.com/usememos/memos/issues/5849)) ([0fc1dab](https://github.com/usememos/memos/commit/0fc1dab28b33f7fdbe9a21cd3bd3affe75dd7f19)) +* **api:** appease image size lint ([ff6389a](https://github.com/usememos/memos/commit/ff6389a5ef73772fcb5c132bf1cb169fb4744c00)) +* **api:** improve SSE hub design and fix double-broadcast on comments ([c53677f](https://github.com/usememos/memos/commit/c53677fcba202a8eed35c8ecdfaacea5152b8691)) +* **api:** make credentials write-only and restrict sensitive settings to admins ([9d3a74b](https://github.com/usememos/memos/commit/9d3a74bcccf934aa2fa95ee240b56cc3b3a25776)) +* **api:** reduce memory pressure in backend paths ([c456637](https://github.com/usememos/memos/commit/c45663761d148e94d3e1b30f4810922e7c2571ab)) +* **api:** remove public activity service ([#5734](https://github.com/usememos/memos/issues/5734)) ([04f239a](https://github.com/usememos/memos/commit/04f239a2fc74f7090c779a6a7b8a08238fd31b88)) +* **api:** restrict user email exposure to self and admins ([#5784](https://github.com/usememos/memos/issues/5784)) ([a24d420](https://github.com/usememos/memos/commit/a24d4209222814e4a8bedfc0392e91462bc855ad)) +* **api:** switch user resource names to usernames ([#5779](https://github.com/usememos/memos/issues/5779)) ([acddef1](https://github.com/usememos/memos/commit/acddef1f3dcca44806bcbb85e9dc5cae7daa5285)) +* **api:** tolerate missing related users in memo conversions ([#5809](https://github.com/usememos/memos/issues/5809)) ([25feef3](https://github.com/usememos/memos/commit/25feef3aadd34bfd474d7e3b685815a6509bc4c6)) +* **auth:** recover session via refresh cookie when localStorage is empty ([#5748](https://github.com/usememos/memos/issues/5748)) ([551ee1d](https://github.com/usememos/memos/commit/551ee1d81f398abdcaf73a0c2b782c8379b0e3f2)) +* backend tests action ([065e817](https://github.com/usememos/memos/commit/065e817470b1d3b6b00222525791b85d825c1492)) +* clear content search filter when selecting shortcut ([#5499](https://github.com/usememos/memos/issues/5499)) ([2c3f9e3](https://github.com/usememos/memos/commit/2c3f9e3bfbe09e5d0028d1525c1df83c03f547c9)) +* correct typos in comments, error messages, and identifiers ([#5704](https://github.com/usememos/memos/issues/5704)) ([8f43e80](https://github.com/usememos/memos/commit/8f43e8075b62706f99da4005ab04b165b35215f6)) +* detect legacy installations with empty schema version ([9628d3d](https://github.com/usememos/memos/commit/9628d3de21289e887ffeb6cc4b6710913a0de44e)) +* **editor:** show newly linked memos when editing a memo with attachments ([026ea92](https://github.com/usememos/memos/commit/026ea92f7b4005c30ca84340c22018740659ab51)) +* ensure comment divs span full width in MemoDetail ([ce44164](https://github.com/usememos/memos/commit/ce441644af34ffff156f1793c40011c2b82e8d5f)) +* **fileserver:** render SVG attachment previews ([40fd700](https://github.com/usememos/memos/commit/40fd700fb8be27a8d7a300a2636cf4f366572176)) +* **filter:** enforce CEL syntax semantics ([0e89407](https://github.com/usememos/memos/commit/0e89407ee91deda87e0df7464a89d26d1e9a88b3)) +* **frontend:** restore sitemap and robots routes ([fee7fcd](https://github.com/usememos/memos/commit/fee7fcd6608b9d07da1f146c33c9bb8f898f708f)) +* handle chunk load errors after redeployment with auto-reload ([#5703](https://github.com/usememos/memos/issues/5703)) ([bdd3554](https://github.com/usememos/memos/commit/bdd3554b897246bac5c1e6fd801495c24b6a656e)) +* harden memo content iframe and HTML sanitization ([7e21b72](https://github.com/usememos/memos/commit/7e21b728b346e80023c93e8986130f83e70584f9)) +* hide transcribe button without AI provider ([ab53329](https://github.com/usememos/memos/commit/ab5332901fd6626f0a2ae6b99671af9663f68078)) +* improve image preview dialog and live photo trigger ([aafcc21](https://github.com/usememos/memos/commit/aafcc21ae6f96a313fb372365dd1af8a1a69d1ba)) +* improve installer compatibility and docs ([f90d9a4](https://github.com/usememos/memos/commit/f90d9a49a78d0764a6c5cf8f6720e69ea1164b25)) +* improve KaTeX and Mermaid error handling and overflow ([6b37fcc](https://github.com/usememos/memos/commit/6b37fcc01b5dcded6a2ec254fbaf895f7812d072)) +* include plain URLs and tags in memo snippet generation ([#5688](https://github.com/usememos/memos/issues/5688)) ([3d4f793](https://github.com/usememos/memos/commit/3d4f793f97b567bda823a60b7fe10e09e14499ce)) +* **lint:** correct goimports struct literal alignment after removing write-only credential fields ([#5794](https://github.com/usememos/memos/issues/5794)) ([9610ed8](https://github.com/usememos/memos/commit/9610ed8fc809b3e7aa4b93e4909634957fa94cf7)) +* **map:** align dark mode map styling ([7ac9989](https://github.com/usememos/memos/commit/7ac9989d43f3967b466f340da3841290d86b20f1)) +* **map:** refine Leaflet controls and memo map styling ([894b3eb](https://github.com/usememos/memos/commit/894b3eb045c7d2c2acce847c34a85295c909dcf7)) +* **markdown:** support height/width attributes on img elements ([737acbb](https://github.com/usememos/memos/commit/737acbba2f5e3dd911da3a77d2d5d1cde1bf8ba1)) +* **memo-editor:** scope Cmd+Enter save to the active editor ([#5745](https://github.com/usememos/memos/issues/5745)) ([05810e7](https://github.com/usememos/memos/commit/05810e7882cb03d448d9d8fa84bc6ca54eafbed0)) +* **mysql:** handle CreateMemo custom timestamps with FROM_UNIXTIME ([#5673](https://github.com/usememos/memos/issues/5673)) ([09d73e8](https://github.com/usememos/memos/commit/09d73e8b6e16c43a61767817909a472916c83daa)) +* normalize attachment MIME types before validation ([c3e7e2c](https://github.com/usememos/memos/commit/c3e7e2c316d01bf857931c38303efc87307f2a19)) +* preserve draft content when tab is suspended or editor remounts ([9ca7122](https://github.com/usememos/memos/commit/9ca71229a6c0dfad44b76ed06fced46c5bef49c7)) +* prevent local attachment uploads from overwriting files ([4add9b0](https://github.com/usememos/memos/commit/4add9b04ad5d0b7608c985281f5975dc39f9a572)) +* prevent stale comment drafts from being restored ([e520b63](https://github.com/usememos/memos/commit/e520b637fd8d0f6331674003abe72f9dfbae8231)) +* remove duplicate Japanese locale keys ([efeb28c](https://github.com/usememos/memos/commit/efeb28c872a2bd6edd28fa3b68bd0b15af923d50)) +* render audio attachments as inline players ([#5699](https://github.com/usememos/memos/issues/5699)) ([2ccb98a](https://github.com/usememos/memos/commit/2ccb98a6cbc40544e81eeeca2a2cbbaf8348f45e)) +* restrict archived memo access to creator only ([#5707](https://github.com/usememos/memos/issues/5707)) ([f4154d0](https://github.com/usememos/memos/commit/f4154d090be3896c8e0dd83440f24953bbeb308c)) +* **routing:** redirect unauthenticated users to /explore when public visibility is allowed ([98859eb](https://github.com/usememos/memos/commit/98859eb5e5065a7c12ada983b7c38c5af5035bb6)) +* **server:** close SSE clients during shutdown ([a5ddd5a](https://github.com/usememos/memos/commit/a5ddd5adafef282f00b23e00e145119d4316f24f)) +* sync html lang attribute with active locale ([#5753](https://github.com/usememos/memos/issues/5753)) ([be00abe](https://github.com/usememos/memos/commit/be00abe852479820b7c574e15e276d70961ab7bd)) +* tag parsing truncates emojis with variation selectors ([#5496](https://github.com/usememos/memos/issues/5496)) ([3ea6ea3](https://github.com/usememos/memos/commit/3ea6ea3108f58dc34f39fa6f21d761bd2e97732b)) +* **tags:** allow blur-only tag metadata ([#5800](https://github.com/usememos/memos/issues/5800)) ([1921b57](https://github.com/usememos/memos/commit/1921b57662c2129d179930f71e5c42caf9070a19)) +* toggle focus mode do not reset editor height ([#5504](https://github.com/usememos/memos/issues/5504)) ([0729779](https://github.com/usememos/memos/commit/0729779e0427c68bdbc5b6b711a5683f66ba9bbc)) +* **ui:** show comment editor above the comment list ([#5662](https://github.com/usememos/memos/issues/5662)) ([6b0736b](https://github.com/usememos/memos/commit/6b0736b29325ff7698b7395dc761f2ca41e6521c)) +* **ui:** unify metadata component styles across MemoView and MemoEditor ([664b8c5](https://github.com/usememos/memos/commit/664b8c56290026ba2beb7b75db24c684824b8670)) +* unify live photo previews around LIVE badge playback ([6b0487d](https://github.com/usememos/memos/commit/6b0487dcd857ba72189ca0624cb4985961f08f25)) +* **webhooks:** trigger memo updates for attachment and relation changes ([#5795](https://github.com/usememos/memos/issues/5795)) ([acbc914](https://github.com/usememos/memos/commit/acbc914dea8d4e533028b03929193a4af1ac32b4)) +* **web:** prevent MemoContent prop leaks ([22519b5](https://github.com/usememos/memos/commit/22519b57a0a971ab927a03015c994c63b8c3f1da)) +* **web:** refine attachment media layout ([a0d83e1](https://github.com/usememos/memos/commit/a0d83e1a9e9d0ba50a0103e594adb011728faf8c)) +* **web:** refresh memo detail cache after editor save ([333c9df](https://github.com/usememos/memos/commit/333c9df233240a843a9e62d17c6ff464690636f8)) +* **web:** use BroadcastChannel to sync token refreshes across tabs ([bbdc998](https://github.com/usememos/memos/commit/bbdc998646e8093223a448378a2c29690f0d8612)) + + +### Performance Improvements + +* batch load memo relations when listing memos ([#5692](https://github.com/usememos/memos/issues/5692)) ([1e82714](https://github.com/usememos/memos/commit/1e82714a52c72455a6ba02605cc641d7ad4fbf1a)) diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 0000000..b75ef17 --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1,2 @@ +# These owners will be the default owners for everything in the repo. +* @usememos/moderators diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..ad324ee --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Memos + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..deacb94 --- /dev/null +++ b/README.md @@ -0,0 +1,117 @@ +
+

Featured Sponsors

+ + + + + +
+ + + + + Warp + +
+ Warp is an agentic development environment. +
+
+ + + + + CodeRabbit + +
+ Cut code review time & bugs in half, instantly. +
+
+
+ +# Memos + +Memos + +Open-source, self-hosted note-taking tool built for quick capture. Markdown-native, lightweight, and fully yours. + +[![Home](https://img.shields.io/badge/🏠-usememos.com-blue?style=flat-square)](https://usememos.com) +[![Live Demo](https://img.shields.io/badge/✨-Try%20Demo-orange?style=flat-square)](https://demo.usememos.com/) +[![Docs](https://img.shields.io/badge/📚-Documentation-green?style=flat-square)](https://usememos.com/docs) +[![Discord](https://img.shields.io/badge/💬-Discord-5865f2?style=flat-square&logo=discord&logoColor=white)](https://discord.gg/tfPJa4UmAv) +[![Docker Pulls](https://img.shields.io/docker/pulls/neosmemo/memos?style=flat-square&logo=docker)](https://hub.docker.com/r/neosmemo/memos) + +Memos Demo Screenshot + +## Features + +- **Instant Capture** — Timeline-first UI. Open, write, done — no folders to navigate. +- **Total Data Ownership** — Self-hosted on your infrastructure. Notes stored in Markdown, always portable. Zero telemetry. +- **Radical Simplicity** — Single Go binary, ~20MB Docker image. One command to deploy with SQLite, MySQL, or PostgreSQL. +- **Open & Extensible** — MIT-licensed with full REST and gRPC APIs for integration. + +## Quick Start + +### Docker (Recommended) + +```bash +docker run -d \ + --name memos \ + -p 5230:5230 \ + -v ~/.memos:/var/opt/memos \ + neosmemo/memos:stable +``` + +Open `http://localhost:5230` and start writing! + +### Native Binary + +```bash +curl -fsSL https://raw.githubusercontent.com/usememos/memos/main/scripts/install.sh | sh +``` + +### Try the Live Demo + +Don't want to install yet? Try our [live demo](https://demo.usememos.com/) first! + +### Other Installation Methods + +- **Docker Compose** - Recommended for production deployments +- **Pre-built Binaries** - Available for Linux, macOS, and Windows +- **Kubernetes** - Helm charts and manifests available +- **Build from Source** - For development and customization + +See our [installation guide](https://usememos.com/docs/deploy) for detailed instructions. + +## Contributing + +Contributions are welcome — bug reports, feature suggestions, pull requests, documentation, and translations. + +- [Report bugs](https://github.com/usememos/memos/issues/new?template=bug_report.md) +- [Suggest features](https://github.com/usememos/memos/issues/new?template=feature_request.md) +- [Submit pull requests](https://github.com/usememos/memos/pulls) +- [Improve documentation](https://github.com/usememos/dotcom) +- [Help with translations](https://github.com/usememos/memos/tree/main/web/src/locales) + +## Sponsors +* [**CodeRabbit** - Cut code review time & bugs in half, instantly](https://coderabbit.link/usememos) +* [**Warp** - The agentic development environment](https://go.warp.dev/memos) +* [**SSD Nodes** - Affordable VPS hosting for self-hosters](https://ssdnodes.com/?utm_source=memos&utm_medium=sponsor) +* [**InstaPods** - Get your app online in seconds](https://instapods.com/?utm_source=memos&utm_medium=sponsor) • [Deploy Memos in 30 Seconds](https://instapods.com/apps/memos/?utm_source=memos&utm_medium=sponsor) + +Love Memos? [Sponsor us on GitHub](https://github.com/sponsors/usememos) to help keep the project growing! + +## Star History + +[![Star History Chart](https://api.star-history.com/svg?repos=usememos/memos&type=Date)](https://star-history.com/#usememos/memos&Date) + +## License + +Memos is open-source software licensed under the [MIT License](LICENSE). See our [Privacy Policy](https://usememos.com/privacy) for details on data handling. + +--- + +**[Website](https://usememos.com)** • **[Documentation](https://usememos.com/docs)** • **[Demo](https://demo.usememos.com/)** • **[Discord](https://discord.gg/tfPJa4UmAv)** • **[X/Twitter](https://x.com/usememos)** + + + Vercel OSS Program + diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..4464620 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,41 @@ +# Security Policy + +## Supported Versions + +Memos is currently a `0.x` project. Security fixes are only provided for the latest release. Older releases are not supported for security updates, and fixes are not backported. + +If you run Memos in production, keep your instance updated to the latest release. + +## Reporting a Vulnerability + +Please report security issues privately by email: `dev@usememos.com` + +Do not open public GitHub issues, discussions, or pull requests for suspected vulnerabilities. + +Please include: + +- A clear description of the issue +- Steps to reproduce +- Affected version or commit +- Deployment details that matter to reproduction +- Your assessment of impact + +We will review reports as time permits and fix valid issues in regular releases. + +## Disclosure and CVEs + +Memos is self-hosted software and is still in the `0.x` stage. At this stage, we do not run a formal disclosure program, publish separate security advisories for every issue, or request CVE IDs. + +Security fixes may be shipped directly in normal releases or noted briefly in release notes and changelogs. + +## Self-Hosted Deployment Notes + +The security posture of a Memos instance depends heavily on how it is deployed and operated. In particular: + +- Keep Memos updated +- Put it behind a properly configured reverse proxy when exposed to the internet +- Require authentication for any non-public deployment +- Use TLS in production +- Limit access to trusted users and administrators + +Reports that depend entirely on intentionally unsafe deployment choices, unsupported local patches, or administrator actions may be treated as deployment issues rather than product vulnerabilities. diff --git a/docs/plans/2026-03-23-memo-detail-outline/definition.md b/docs/plans/2026-03-23-memo-detail-outline/definition.md new file mode 100644 index 0000000..58a7b70 --- /dev/null +++ b/docs/plans/2026-03-23-memo-detail-outline/definition.md @@ -0,0 +1,35 @@ +## Background & Context + +The MemoDetail page (`web/src/pages/MemoDetail.tsx`) renders a memo's full content with a right sidebar (`MemoDetailSidebar`) on desktop. The sidebar currently shows share controls, timestamps, property badges (links, to-do, code), and tags. Memo content is rendered via `react-markdown` with custom heading components (h1–h6) in `MemoContent/markdown/Heading.tsx`. The page already has hash-based scroll-to-element infrastructure for comments (lines 39–43 of MemoDetail.tsx). + +## Issue Statement + +When viewing a memo with structured headings, there is no outline or table of contents in the MemoDetail sidebar, so readers cannot see the document structure at a glance or jump to specific sections. Heading elements rendered by the `Heading` component do not have `id` attributes, preventing any anchor-based navigation to them. + +## Current State + +- **`web/src/pages/MemoDetail.tsx`** (93 lines) — MemoDetail page. Hash-based `scrollIntoView` logic exists at lines 39–43 but only targets comment elements. The sidebar is rendered at lines 82–86 as ``. +- **`web/src/components/MemoDetailSidebar/MemoDetailSidebar.tsx`** (109 lines) — Desktop sidebar. Contains sections: Share (lines 58–65), Created-at (lines 67–76), Properties (lines 78–89), Tags (lines 91–102). Uses a reusable `SidebarSection` helper (lines 24–32). No outline section exists. +- **`web/src/components/MemoDetailSidebar/MemoDetailSidebarDrawer.tsx`** (36 lines) — Mobile drawer wrapper for the sidebar. +- **`web/src/components/MemoContent/markdown/Heading.tsx`** (30 lines) — Renders h1–h6 with Tailwind classes. Does not generate `id` attributes on heading elements. +- **`web/src/components/MemoContent/index.tsx`** (157 lines) — ReactMarkdown renderer. Maps h1–h6 to the `Heading` component (lines 72–101). No rehype-slug or equivalent plugin is installed. +- **`web/src/utils/markdown-manipulation.ts`** (143 lines) — Contains `fromMarkdown()` MDAST parsing with GFM extensions. Used for task extraction; no heading extraction exists. + +## Non-Goals + +- Redesigning the overall MemoDetail layout or sidebar structure beyond adding the outline section. +- Supporting outline for the mobile drawer — the outline section should appear in the desktop sidebar only for now. +- Adding active heading highlighting on scroll (scroll-spy behavior). +- Supporting outline in the memo list/timeline view (compact mode). +- Changing the existing heading visual styles in the content area. + +## Open Questions + +- Which heading levels to include in the outline? (default: h1–h4, matching user request) +- How to generate slug IDs — install `rehype-slug` or custom implementation? (default: lightweight custom slug generation in the Heading component to avoid a new dependency) +- Should the outline section be hidden when no headings exist? (default: yes, hide entirely like Properties/Tags sections) +- Should duplicate heading text produce unique slugs (e.g. `my-heading`, `my-heading-1`)? (default: yes, append numeric suffix for duplicates) + +## Scope + +**M** — Touches 3–4 files (Heading component, MemoDetailSidebar, possibly a new outline component, and a slug utility). Existing patterns (SidebarSection, hash scrolling) apply directly. No new subsystem or novel approach required. diff --git a/docs/plans/2026-03-23-memo-detail-outline/plan.md b/docs/plans/2026-03-23-memo-detail-outline/plan.md new file mode 100644 index 0000000..3c03967 --- /dev/null +++ b/docs/plans/2026-03-23-memo-detail-outline/plan.md @@ -0,0 +1,47 @@ +## Task List + +T1: Add heading extraction utility [S] — T2: Add slug IDs to Heading component [S] — T3: Create MemoOutline sidebar component [M] — T4: Integrate outline into MemoDetailSidebar [S] + +### T1: Add heading extraction utility [S] + +**Objective**: Provide a function to extract h1–h4 headings from markdown content with slugified IDs, reusing the existing MDAST parsing pattern from `markdown-manipulation.ts`. +**Files**: `web/src/utils/markdown-manipulation.ts` +**Implementation**: Add `HeadingItem` interface (text, level, slug) and `extractHeadings(markdown: string): HeadingItem[]` function. Use existing `fromMarkdown()` + `visit()` pattern. Visit `"heading"` nodes with depth 1–4, extract text from children, generate slug via `slugify()` helper (lowercase, replace non-alphanumeric with hyphens, deduplicate). Export both. +**Validation**: `cd web && pnpm lint` — no new errors + +### T2: Add slug IDs to Heading component [S] + +**Objective**: Generate deterministic `id` attributes on h1–h6 elements so outline links can scroll to them via `#hash`. +**Files**: `web/src/components/MemoContent/markdown/Heading.tsx` +**Implementation**: In `Heading` (~line 13), extract text from `children` using a `getTextContent(children)` helper that recursively extracts string content from React children. Generate slug with the same `slugify` logic. Apply `id={slug}` to the rendered ``. +**Validation**: `cd web && pnpm lint` — no new errors + +### T3: Create MemoOutline sidebar component [M] + +**Objective**: Create a modern, Claude/Linear-style outline component that renders h1–h4 headings as anchor links with indentation by level. +**Size**: M (new component file, modern styling) +**Files**: +- Create: `web/src/components/MemoDetailSidebar/MemoOutline.tsx` +**Implementation**: +1. Props: `{ headings: HeadingItem[] }` from `markdown-manipulation.ts` +2. Render a `