LockIn について
LockInは、Claude、Codex、Cursorなどのコーディングエージェント向けノートブックです。テーマ別のノートをセッション間で共有でき、質問への回答には参照ページが示されます。セルフホストとMarkdown・JSONへのエクスポートにも対応しています。
主な機能
- 01エージェントによるノートの保存・検索・閲覧
- 02Markdown、PDF、リンクのテーマ別整理
- 03ノートへの質問と参照ページの提示
- 04タスク、集中時間、復習の計画
- 05セルフホストとMarkdown・JSONへのエクスポート
活用シーン
- 01コーディングエージェント間でプロジェクト情報を引き継ぐ
- 02コード関連の発見を保存して整理する
- 03ノートから情報を検索し参照先を確認する
- 04学習タスクと間隔を空けた復習を計画する
MCP 対応
LockInは`/api/mcp`でStreamable HTTPのMCPサーバーを稼働し、クライアントにノートの保存、検索、閲覧機能を提供します。設定画面でエージェント用トークンを作成し、表示される設定でクライアントを接続します。
設定
リモートサーバーはインストール不要です。クライアントを選んで設定をコピーするか、ワンクリックで導入できます。
https://lockin.namankhandelwal.dev/api/mcpclaude mcp add --transport http sky-walkerx-lockin https://lockin.namankhandelwal.dev/api/mcp{"mcpServers":{"sky-walkerx-lockin":{"type":"http","url":"https://lockin.namankhandelwal.dev/api/mcp"}}}Cursor で開く{"servers":{"sky-walkerx-lockin":{"type":"http","url":"https://lockin.namankhandelwal.dev/api/mcp"}}}VS Code で開く{"mcpServers":{"sky-walkerx-lockin":{"type":"http","url":"https://lockin.namankhandelwal.dev/api/mcp"}}}{"mcpServers":{"sky-walkerx-lockin":{"serverUrl":"https://lockin.namankhandelwal.dev/api/mcp"}}}コマンドはターミナルで実行し、JSON は各クライアントの MCP 設定に貼り付けて再起動します。認可が必要なサーバーは初回接続時にログインを求めます。
ツール
詳細
Claude、Codex、Cursor を使うなかで毎日さまざまなことを学びますが、そのほとんどはセッションが終わると消えてしまいます。LockIn はそれを保存します。エージェントは MCP 経由でノートを書き込み、あなたはそれをテーマごとに整理できます。そして、選んだ任意のモデルがノートをもとに質問に答えます。
音声付きの45秒のローンチ動画:
https://github.com/user-attachments/assets/3ae46572-283e-49fd-a3dc-e178dd269e40
仕組み
月曜日:Claude Code が Project-X にノートを保存し、あなたが確認します。木曜日:Codex が前回の続きから作業を再開します。
flowchart LR
cc["Claude Code"] -- save_note --> mcp
cx["Codex"] -- search_notes --> mcp
more["Cursor, Claude.ai, ChatGPT,<br/>any MCP client"] --> mcp
mcp(["LockIn's MCP server<br/>/api/mcp"]) --> nb[("Your notebook<br/>notes filed by subject")]
nb --> you["You<br/>witness, read, plan"]
nb --> ask["Ask<br/>a model you choose,<br/>answers cite your pages"]
内容
|
エージェントがここに書き込みます Claude Code、Codex、Cursor、または任意の MCP クライアントが、メモを保存、検索、閲覧できます。エージェントが保存したものには、誰が記録したかがすべて記され、あなたが確認するまで保留されます。 |
メモに質問する ブラウザー上(WebGPU)、自分のマシン上(Ollama、LM Studio)、または自分のキーを使ってAnthropic、OpenAI、Gemini、OpenRouterでモデルとチャットできます。回答には、引用元となったメモのページが示されます。 |
|
テーマごとのメモ コードを含むMarkdownに加え、読んでいるPDFやリンクを、それぞれに該当するテーマに分類して保存できます。 |
集中を妨げずに読む どのメモも全画面で開きます。 |
|
必要なときに使える計画 タスク、集中時間、試験のペース、間隔を空けた復習は、それぞれのテーマの「計画」タブにあります。必要になるまで表示されません。 |
自分のもの AGPL-3.0で、1つのコマンドでセルフホストでき、すべてMarkdownまたはJSONにエクスポートできます。 |
セルフホスティング
Composeを含むDockerが必要です。
git clone https://github.com/Sky-walkerX/LockIn.git && cd LockIn
cp .env.example .env
# set AUTH_SECRET in .env: openssl rand -base64 32
docker compose up -d
http://localhost:3000 を開き、アカウントを作成してください。ポートが応答するのはマシン自身からの接続のみです。サーバーで使う場合は、下記のHTTPSを参照してください。初回起動時にはリリース済みのイメージを取得し、Postgresの準備が整うのを待ってから、アプリの起動前にデータベースのマイグレーションを適用します。イメージはamd64とarm64向けに公開されています。お使いのバージョン用のイメージがない場合は、代わりにComposeがチェックアウトからビルドします。
実行されるサービス:
| サービス | 機能 |
|---|---|
db | Postgres 17です。データはdbボリュームに保存されます。 |
migrate | マイグレーション(prisma migrate deploy)を適用して終了します。 |
app | ポート3000で動作するLockInです。メモの画像とPDFはuploadsボリュームに保存されます。 |
ingest | 任意です。PDFやウェブページのテキスト抽出と、サーバー側の埋め込みに使用します。 |
caddy | 任意です。アプリの前段でHTTPSを提供します。詳しくは下記を参照してください。 |
テキスト抽出とサーバー側の埋め込みを有効にするには、.envでINGEST_SECRET(長いランダムな文字列)とINGEST_URL=http://ingest:8080を設定してから、次を実行します。
docker compose --profile ingest up -d
ingestイメージには埋め込みモデルが含まれているため、サイズは約1 GBです。これがなくてもキーワード検索は使え、埋め込みはブラウザー側で行われます。一度に2つのドキュメントを読み込み、処理に140秒を超えたものは停止します。3つ目のドキュメントは20秒間、空きが出るのを待ち、その後サービスがビジー状態であることが通知されます。.envのPARSE_CONCURRENCYを設定すると、1つ目の数値を増やせます。ただし、マシンにコアがあり、ドキュメントごとに数百MBの余裕がある場合に限ります。
更新するには、新しいリリースを取得します。Composeファイルには対応するバージョンが指定されているため、イメージとチェックアウトのバージョンは常に一致します。起動時にマイグレーションが実行されます。
git pull && docker compose pull && docker compose up -d
リリースではなくチェックアウト内のコードを実行するには、ビルドしてください。docker compose up -d --build
docker compose psでアプリが正常かどうか確認できます。稼働状況の監視には、同じ確認を行う/api/health(アプリがデータベースに接続できる場合は200)を使えます。
バックアップ
すべては2つのボリュームに保存されます。db(Postgres)とuploads(ノートの画像とPDF)です。両方をバックアップし、更新前にもバックアップを取ってください。
# back up
docker compose exec -T db pg_dump -U lockin -Fc lockin > lockin.dump
docker compose cp app:/data/uploads ./uploads-backup
# restore, into a stack that is up
docker compose exec -T db pg_restore -U lockin -d lockin --clean --if-exists < lockin.dump
docker compose cp ./uploads-backup/. app:/data/uploads
docker compose exec -u root app chown -R lockin /data/uploads # copied files arrive owned by the host user
バックアップと一緒にAUTH_SECRETも保管してください。復元したコピーで異なるシークレットを使うと、全員がサインアウトされます。
.envの設定:
| 変数 | |
|---|---|
AUTH_SECRET | 必須です。セッションとアップロードリンクの署名に使います。 |
PUBLIC_URL | LockInを開くときのアドレスです。デフォルトはhttp://localhost:3000です。 |
LOCKIN_PORT | ホスト側のポートです。デフォルトは3000です。 |
LOCKIN_BIND | このポートが待ち受ける、マシンのアドレスです。デフォルトは127.0.0.1で、マシン自体、またはそのマシン上で動作するプロキシからアクセスできます。 |
LOCKIN_VERSION | 実行するリリースです。たとえば1.0.0を指定します。デフォルトはチェックアウトしたリリースです。 |
POSTGRES_PASSWORD | 同梱のPostgresのパスワードです。 |
SIGNUP | open(デフォルト)では、アドレスにアクセスできる人なら誰でもアカウントを作成できます。closedでは、最初のアカウントが作成された後、新しいアカウントの作成を停止します。 |
GOOGLE_CLIENT_ID、GOOGLE_CLIENT_SECRET | 任意です。両方を設定した場合のみ、「Googleで続行」が表示されます。 |
SMTP_HOST、SMTP_PORT、SMTP_USER、SMTP_PASSWORD、SMTP_FROM | 任意です。送信メールについては、以下の「アカウント」を参照してください。 |
OPERATOR_EMAIL、OPERATOR_NAME、OPERATOR_HOSTING | 任意です。プライバシーと利用規約のページについては、以下の「アカウント」を参照してください。 |
STORAGE_QUOTA_MB | 各アカウントが保存できる画像とPDFの容量(メガバイト)です。デフォルトは1024です。上限を設けない場合は0を指定します。 |
RATE_LIMITS | offにすると、以下の制限が無効になります。デフォルトはonです。 |
TRUSTED_PROXY_HOPS | LockInの前段にあるリバースプロキシの数です。デフォルトは1です。訪問者がポートに直接アクセスする場合は0にします。 |
INGEST_URL、INGEST_SECRET | 任意です。上記を参照してください。 |
HTTPS
インターネットからアクセスできるマシンでは、LockInにHTTPSが必要です。HTTPSを使わないと、セッションとエージェントトークンが暗号化されずにネットワークを通過し、ブラウザーでローカルモデルも実行できません。httpsプロファイルを有効にすると、Caddyが追加されます。CaddyはLet's Encryptから証明書を取得し、自動更新します。ドメインをマシンに向け、ポート80と443を開放して、.envに次の設定を追加してください。
PUBLIC_URL=https://notes.example.com # no trailing slash
docker compose --profile https up -d
プロキシの設定はCaddyfileにあり、Strict-Transport-Securityの有効期間は1年、リクエストボディの上限は60 MBです。
マシン上で独自のプロキシ(nginx、Traefik)を使う場合は、プロファイルを無効のままにし、PUBLIC_URLを設定して、プロキシから127.0.0.1:3000に接続するようにし、Strict-Transport-Securityを送信してください。LockInがこのセキュリティヘッダーを送信しないのは、サイトがHTTPSで配信されているかどうかを把握しているのがプロキシだけだからです。その他のヘッダー(コンテンツセキュリティポリシー、他のサイトによるフレーム内表示の防止、コンテンツのスニッフィング防止)は、LockIn自身が送信します。
ポート3000はネットワークに公開されないため、プロキシを迂回することはできません。自宅のネットワークなどで、プロキシを使わずに他のマシンからLockInを利用するには、LOCKIN_BIND=0.0.0.0とTRUSTED_PROXY_HOPS=0を設定してください。Dockerはこのポートをほとんどのホストファイアウォールを越えて公開します。その場合、パスワードやエージェントトークンを含むすべてのデータが暗号化されずに送信されます。
アカウント
このアドレスを開ける人なら誰でも登録できます。ただし、SIGNUP=closed を設定すると登録できなくなるため、先に自分のアカウントを作成してから閉じてください。
SMTP_HOST を設定すると、LockIn はメールを2通送信します。新しいアカウントにはアドレスを確認するリンクが送られ、確認が完了するまでサインインできません。また、「パスワードをお忘れですか」から新しいパスワードを設定するリンクを送信できます。リンクは PUBLIC_URL をもとに作成されるため、実際に利用するアドレスを設定してください。SMTP がない場合、メールは送信されません。アカウントにはすぐサインインでき、パスワードを忘れた場合は自分でリセットします。
scripts/set-password.sh [email protected]
パスワードを変更またはリセットすると、そのアカウントはすべての場所からサインアウトされます。メールのリンクまたはスクリプトでリセットした場合は、他の誰かがアクセスしていた可能性を考慮し、すべてのエージェントと接続済みアプリも切断されます。作成済みのトークンは、新しいパスワードに変えても有効なままだからです。「設定」で再接続してください。「設定」には「パスワードを変更」と「アカウントを削除」があり、アカウントを削除するとノートブックとそのファイル、すべてのエージェントのアクセス権が削除されます。
自分だけで使うノートブックには、プライバシーや利用規約のページはありません。他の人が登録できるようにする場合は、OPERATOR_EMAIL を設定してください。必要であれば OPERATOR_NAME も設定できます。/privacy と /terms が表示され、ランディングページと登録ページからリンクされます。また、問い合わせ先としてあなたの名前が記載されます。OPERATOR_HOSTING には、データの保管場所とバックアップの保存期間について、プライバシーページに表示する文章を設定します。どちらのページにも、LockIn の動作と、あなたの名前で行ういくつかの約束(他の人のノートを読まないこと、サービスを終了する前に通知することなど)が記載されるため、有効にする前に内容を確認してください。
「Google で続行」すると、新しいアカウントが作成されるか、そのアドレスが確認済みであれば既存のアカウントが開きます。アドレスが未確認のままパスワードで作成されたアカウントには紐付けられません。そのため、アドレスの所有者より先に他の人がそのアドレスを登録することはできません。
制限
LockIn は、単一の呼び出し元がインスタンスを使い果たさないよう、いくつかの項目を制限しています。上限を超えると、Retry-After とともに 429 を返します。
| 上限 | |
|---|---|
| サインインの試行 | 1つのネットワークからの1つのアドレスにつき、10分間に10回 |
| 登録 | 1つのネットワークから、1時間に10回 |
| パスワードリセットメールと確認メール | 1つのネットワークから、1時間にそれぞれ10通と20通。さらに、1アカウントにつき1分に1通 |
| アップロード | STORAGE_QUOTA_MB の範囲内で、1アカウントにつき1分に60回 |
| ドキュメントの抽出 | 1アカウントにつき、1時間に30回 |
| エージェント(MCP) | 1トークンにつき、1分に60リクエスト |
ネットワーク単位の制限は訪問者のアドレスに基づきます。LockIn がそのアドレスを把握できるのは、プロキシが設定する X-Forwarded-For ヘッダー経由のみです。この点も、プロキシの背後で実行する理由の1つです。プロキシの前に CDN も配置する場合は、TRUSTED_PROXY_HOPS=2 を設定し、プロキシで CDN のヘッダーを保持してください(方法は Caddyfile に記載されています)。そうしないと、CDN の背後にいる人は全員、1人の訪問者として数えられます。プロキシをまったく使用しない場合は、TRUSTED_PROXY_HOPS=0 にします。LockIn に直接アクセスする訪問者は、そのヘッダーを自分で書き換えられるため信頼されず、訪問者全員がまとめて制限の対象になります。
リクエストの各フィールドにも上限があります(ノートの本文は100万文字、タイトルは300文字まで)。リクエスト本文そのものには上限がありません。プロキシ側で、PDF のアップロードも通るように60 MB以上の上限を設定してください(https プロファイルでは設定済みです。nginx では client_max_body_size を使用します)。
ノートブックの規模
意味による検索では、Postgres 内で、アカウントのノートブックに含まれるすべての文章と質問との関連度を評価します。同梱のデータベースを使ってノートパソコンで測定した結果は、通常のノートブック(数百の文章)で12ミリ秒、300件のノートと3冊の教科書(3,900の文章)で0.1秒、2,000件のノートと20冊の教科書(26,000の文章)で0.65秒でした。1つのアカウントの文章数に比例して増加し、アカウント数には左右されません。この規模を超えると、保存済みベクトルに pgvector が必要になりますが、まだ使用していません。
科目のページは、その科目のノートをすべて一度に送信します。1つの科目に数百件のノートがあれば問題ありませんが、数千件になると遅くなります(2,000件のノートで約10 MB)。そのように大きくなった科目は分割してください。
エージェントを接続する(MCP)
LockIn は /api/mcp(Streamable HTTP)で MCP サーバーを実行します。LockIn で 設定 → エージェントを接続 を開き、エージェント名を付けたトークンを作成して、表示された設定をコピーします。Claude Code の場合:
claude mcp add --transport http lockin https://your-lockin/api/mcp \
--header "Authorization: Bearer lk_pat_…"
設定には、Codex(~/.codex/config.toml)と Cursor(~/.cursor/mcp.json)用の設定も表示されます。
ツール:
| ツール | |
|---|---|
list_subjects | 各サブジェクトと、それぞれのメモの数、および受信箱を表示します。 |
search_notes | インジェストサービスの実行中は意味で、常にキーワードでメモを検索します。メモとリソースには、それらが属するページの情報も含まれます。 |
get_note | ID を指定して、メモ、タスク、またはサブタスクを全文取得します。メモには、その計画(タスク、そのメモ、入れ子になったサブタスク)が含まれます。 |
get_plan | サブジェクト全体の計画を取得します。各メモのタスクとサブタスク、および完了状況に加え、メモに紐付いていないタスクも表示します。 |
save_note | 指定したサブジェクトの下に新しいメモを保存します。サブジェクトが指定されていない場合や存在しない場合は、受信箱に保存されます。コードに関するメモには、対象となるリポジトリ、コミット(およびその日付)、ファイルを記載できます。応答には関連がありそうなメモが一覧表示されるため、エージェントは自分のメモが既存のメモに置き換わるかどうかを伝えられます。 |
append_to_note | メモの末尾に追記します。既存の内容を置き換えることはありません。同じエージェントが記録したメモなら、そのまま続けて追記します。他のエージェントが記録したメモなら、日付付きの「From Codex」行の下に追記します。 |
edit_note | メモのタイトルを変更するか、メモ内の完全に一致する一節を置き換えます。そのエージェントが記録したメモのみが対象です。自分のメモは追記のみです。メモは「確認待ち」に戻ります。 |
confirm_note | メモが引き続きコードと一致していることを伝えます。アンカーはエージェントのコミットに移動し、古いというフラグがあれば解除されます。 |
link_replacement | エージェントが保存したメモによって古いメモが誤りになったことを伝えます。メモは再びあなたの確認待ちとなり、確認ボタンには置き換え対象のページが表示されます。 |
flag_stale | メモが古くなっている可能性があることと、その理由を記録し、確認できるようにします。 |
supersede_note | 古くなったメモに置き換わる新しいメモを作成します。新しいメモを確認するまで、古いページはアーカイブされません。確認後は、検索と「質問」の対象から除外されます。 |
save_handoff | 次のエージェントに引き継ぎ事項を残します。目標、作業の進捗、除外したこと、次の手順、最初に読むべきページを記載します。 |
pickup_handoff | サブジェクトまたはリポジトリの未完了の引き継ぎ事項を取得し、紐付けられたページの本文も取得します。また、MCP プロンプト pickup でもあります。 |
capture_session | セッションの要約を、セッションごとに 1 つのメモとして保存します。Claude Code プラグインは、セッションのコンテキストが圧縮されたときと終了時にこれを呼び出します。 |
move_note | メモを別のサブジェクトまたは受信箱に移動します。タスクも一緒に移動します。 |
add_task | メモの下、またはサブジェクト内のメモに紐付いていないタスクとしてタスクを追加します。 |
add_subtask | タスクの下、またはその最上位サブタスクのいずれかの下にサブタスクを追加します。 |
update_plan_item | タスクまたはサブタスクを完了/未完了にする、名前を変更する、またはメモを追記します。繰り返しタスクを完了すると、次回分が予定されます。 |
エージェントは何も削除できません。
エージェントがコードに紐付いたメモを読むと、get_note は実行する git diff を提示します。そのため、メモを利用する前にコードがその後変更されていないかを確認できます。メモにはコミットの日付が記録されるため、2 つのメモの内容が食い違う場合は、どちらが後のコードを記述しているかを確認できます。置き換え時のメモページには、両方のコミットと日付が表示されます。
Claude Code プラグイン
integrations/claude-code のプラグインは、Claude Code がセッションをコンパクト化したときと終了したときに、各セッションをノートブックに記録します。また、あるエージェントから別のエージェントへ未完了の作業を引き継ぐための /lockin:handoff と /lockin:pickup を追加します。前述の lockin サーバーを使用します:
claude plugin marketplace add Sky-walkerX/LockIn
claude plugin install lockin@lockin
終了時のキャプチャでは、Claude on Haiku をバックグラウンドで短時間実行し、セッションを要約します。Claude の使用量にカウントされます。LOCKIN_CAPTURE_ON_EXIT=0 で無効にできます。プラグインの README に詳細があります。
各エージェントには専用のトークンが割り当てられます。エージェントのメモにはトークン名が記録され、ほかのトークンに影響を与えずに個別に失効できます。保存されるのは各トークンのハッシュのみです。トークンで毎分 60 件のリクエストを送信できます。上限を超えると Retry-After を伴う 429 が返されます。
Claude.ai、ChatGPT などのサインインするアプリでは、トークンは不要です。URL https://your-lockin/api/mcp を指定してカスタムコネクターを追加すると、サインインして接続を許可するために LockIn に移動します。この機能には LockIn 独自の OAuth 2.1 サーバー(PKCE、Client ID Metadata Documents、動的登録、ローテーションするリフレッシュトークン)を使用するため、セルフホスト環境でも同様に動作します。接続済みのアプリは設定に一覧表示され、そこで接続を解除できます。
質問(⌘J)
質問機能では、ブラウザー上、お使いのマシン上、または独自のキーを使ってプロバイダー上でモデルを実行できます。LockIn のサーバーはメモからプロンプトを作成し、会話の記録を保存しますが、エンドポイントや API キーを取得することはありません。ブラウザーがモデルを直接呼び出します。複数の接続を保持して、質問画面の上部で切り替えられます。
-
独自のキー: Anthropic、OpenAI、Gemini、OpenRouter に対応しています。キーはこのブラウザー内に保存されます。質問と回答に使用するメモは、ブラウザーからプロバイダーに送信されます。メモの自動補完は、ローカルモデルとブラウザー内モデルでのみ実行されます。
-
ブラウザー内: WebGPU 上で WebLLM を実行します。質問機能の設定でモデルを選択して一度ダウンロードすると、ブラウザーにキャッシュされます。新しいバージョンの Chrome または Edge が必要です。
-
ローカルサーバー: OpenAI 互換サーバー(Ollama、LM Studio、llama.cpp、vLLM)ならどれでも使用できます。ブラウザーが直接呼び出すため、LockIn のオリジンを許可する必要があります:
OLLAMA_ORIGINS=https://your-lockin ollama serve
# macOS app: launchctl setenv OLLAMA_ORIGINS "https://your-lockin", then restart Ollama
両方を localhost 上で実行する場合、設定は不要です。
メモが 1 つのプロンプトに収まらなくなると、質問機能はメモの切り詰めをやめ、検索を開始します。メモはチャンクに分割されて埋め込み化され(取り込みサービスまたはブラウザー内で実行)、質問に対して、テーマの概要と関連性の高い箇所が提示されます。ブラウザー内での埋め込み化では、Hugging Face からモデルを一度ダウンロードします(約 130 MB。その後はキャッシュされます)。モデルを実行するコードは LockIn 自体から配信されます。
すべてのメモと保存されたリソースには、ノートブック内のページ番号が付いています。モデルには各項目がページ番号とともに提示され、[p. 12] のように引用されます。回答内では、引用箇所がメモへのリンクになります。各回答の下にある ノートブックから には、使用した箇所と引用したページが一覧表示されます。箇所の引用を開くと、その箇所までスクロールした状態でメモが開き、該当箇所がマークされます。
開発
pnpm install
pnpm dev # http://localhost:3000
pnpm test # vitest
pnpm lint # eslint
pnpm build # prisma generate && next build
pnpm db:migrate # prisma migrate deploy
開発環境(Prisma CLI 用の .env とアプリ用の .env.local):
DATABASE_URL= # Postgres, runtime. Supabase: transaction pooler (:6543, pgbouncer=true)
DIRECT_URL= # Postgres, migrations. Supabase: session pooler (:5432, no pgbouncer params)
AUTH_SECRET=
NEXTAUTH_SECRET=
NEXTAUTH_URL= # e.g. http://localhost:3000
任意:Supabase Storage ではなく ./storage にアップロードを保存する場合は、GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET、SIGNUP と SMTP_*(上記の「アカウント」)、INGEST_URL / INGEST_SECRET、SUPABASE_URL / SUPABASE_SERVICE_ROLE_KEY を設定します。
Supabase では、DIRECT_URL を DATABASE_URL のコピーにしてはいけません。トランザクションモードの pgbouncer は DDL を実行できないため、マイグレーションは失敗する代わりにハングします。
AUTH_SECRET は必須です。NextAuth 独自のルートは内部シークレットにフォールバックするため、設定しなくてもサインインは動作しているように見えますが、すべての API ルートは getToken で JWT を読み取り、401 を返します。
スキーマの変更はマイグレーションで行います。prisma/schema.prisma を編集してから、pnpm exec prisma migrate dev --name what-changed を実行します。マイグレーションが存在する前に db push でセットアップされたデータベースは、一度ベースラインとしてマークします(pnpm exec prisma migrate resolve --applied 0001_baseline)。その後は通常どおりマイグレーションされます。
Prisma クライアントは pnpm build によって app/generated/prisma/ に生成されます(コミット対象ではありません)。単独で生成する場合は pnpm exec prisma generate を実行します。
データモデル
User ──< Subject ──< Milestone ──< Task ──< Subtask の関係に加え、Subject ──< Resource、User ──< ApiToken、User ──< OAuthGrant ──< OAuthToken(サインインしたアプリ)、User ──< EmailToken(確認リンクとリセットリンク)の関係があり、チャットテーブルと埋め込みテーブルもその隣にあります。
ノートは Milestone の行として保存されます(タイトルと notes の Markdown)。Subject の Plan タスクは、そのノートに関連付けることができます。Inbox は isInbox が設定された Subject です。Milestone.source にはノートを書いた人(「web」またはエージェント名)が記録され、witnessedAt にはエージェントが作成したノートをユーザーが承認した日時が記録されます。
デザイン
PRODUCT.md は製品概要、DESIGN.md はデザインシステムです(Lab Book の外観:布張りの背表紙、方眼紙、読みやすいページ)。
コントリビューション
CONTRIBUTING.md を参照してください。セキュリティの問題は、SECURITY.md の説明に従って非公開で報告してください。
ライセンス
AGPL-3.0-or-later。LockIn は自由に使用、変更、セルフホストできます。変更したバージョンを他者向けのサービスとして運用する場合は、変更内容を公開する必要があります。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。
