Clepit
概要
- カテゴリー
- 開発者向けプラットフォーム
- ウェブサイト
- clepit.com
- コンソール
- app.clepit.com
- ドキュメント
- clepit.com/en/docs
- GraphQL API
- api.clepit.com/graphql
- リアルタイム
- ws.clepit.com
- MCP インターフェース
- api.clepit.com/mcp
- 公開ページ
- clepit.space
リッチテキストの多くは、HTML のかたまりとしてデータベースに収まります。表示し直す以外に何もしないのであれば、それで十分です。ところが、ある顧客に触れているページをすべて探したい、同じ文書をウェブページとメールとモバイルアプリに出したい、二人が同時に編集しても段落が消えないようにしたい、となると話が変わります。その頃には言葉と体裁が絡み合っていて、その文書を確実に読めるのは、それを書いたエディターだけになっています。
Clepit はその二つを切り離します。ページはブロックの並びであり、ブロックはそれぞれ型のついた小さなオブジェクトで、文書そのものは JSON です。解析すべきマークアップはなく、読むためにエディターも要りません。エディターが単独で成り立つのもそのためです。@clepit/core は MIT ライセンスで npm に公開されており、ホスティング側のことは何も知りません。一方、app.clepit.com のワークスペースは、その同じ文書に共同編集者と権限と履歴、そして公開ウェブ上の住所が与えられたときの姿です。
ページはブロックの並び
ブロックは四つのフィールドでできています。id、型、その型が定める data、そしてブロックに適用された調整です。段落の data は表の data とは形が違い、どの形を期待すべきかを教えるのが型です。だから保存された文書は、ただ解析されるのではなく検証できます。ページ全体は、タイムスタンプとバージョンと順に並んだブロックであり、自分の目で読み通せる程度に小さく、プルリクエストで確認もできます。そこにはページがどう見えるべきかを述べる記述は一つもありません。それは描く側の領分であり、だからこそ一つの文書が、三つの複製を持つことなく、ウェブページにもメールにもモバイル画面にもなれるのです。
ブラウザーなしで文書を描く
レンダラーがブラウザーへ直接書き込むことはありません。薄い層を通して描き、その背後には二つの裏付けがあります。一つは本物のページ要素を組み立て、もう一つは文字列を組み立てる。そして同じブロックのコードが両方で動きます。公開ページがブラウザーの存在しないサーバー上で描けるのはこのためであり、サーバーの出力が、エディターが見せたはずの文書そのものになる理由でもあります。やがてずれていく二つ目の実装ではないのです。文字列側の裏付けはサニタイザーを必須の引数として取り、既定値をあえて持ちません。このパッケージの通常のサニタイザーは解析のためにページを組み立てるので、そこでは動きません。黙ってエスケープに切り替えれば、どの文書からも文中の書式を、何も告げずに剥ぎ取ってしまいます。だから欠落は既定値の中に隠さず、使う場所で見えるまま残してあります。
読むために JavaScript は要らない
React アダプターは二つの半分を別々に提供します。求めるものが正反対だからです。コンテンツ側のコンポーネントはサーバーで動き、ページが組み立てられるあいだに仕上がったマークアップを吐き出します。読み手は最初の応答で文書を受け取ります。エディター側のコンポーネントはクライアント専用です。エディターのライフサイクルを引き受けるものであり、ブラウザーがなければ引き受けるものが存在しないからです。したがって Clepit の文書を読むのに JavaScript は一切要りません。ランタイムが現れるのは、書くときです。
ページに入れられるもの
パッケージには二十六種類のブロックが同梱されています。多くはどんなエディターにも要るものです。見出し、段落、リスト、チェックリスト、引用、コード、表、画像、音声、動画、ファイル、注意書き、区切り。残りが存在するのは、文書づくりが、書くための道具がふつう気に留めないものを求めるからです。文書の見出しから自分で組み上がり、そのそれぞれへ結びつく目次。折りたためる節と段組み。別のページの身代わりになるカード。手描きのスケッチ。そして、どの文書を見ておくかを保存し、その活動の写しは持たない活動ブロック。だから挿入された日で凍りつかず、いま起きていることを示し続けます。ブロックの中の書式は、太字、斜体、下線、打ち消し線、文中コード、マーカー、リンクといった通常の記号に加えて、ツールチップ、状態のしるし、メンションを扱います。パッケージ自体には実行時の依存関係が一つもありません。
数式と図は、パッケージの中で描く
そのうち二つのブロックが LaTeX と Mermaid を表示し、どちらも仕事のすべてをパッケージの中で行います。ソースを解析し、レイアウトを計算し、結果を描く。下敷きになる描画ライブラリはなく、数式やフローチャートを絵に変えるためにサービスを呼ぶこともありません。これは依存関係の好みというより、文字列側の裏付けから来る帰結です。ブラウザーにしかないものへ、あるいはネットワークへ手を伸ばすブロックは、公開ページを配るサーバー上では描けません。そうなれば同じページが、誰が求めたかによって違って見えることになります。
ページの中に住む API リファレンス
OpenAPI ブロックに仕様を渡してください。貼り付けても、住所で指し示してもかまいません。すると、その仕様が述べるものを描きます。操作、そのパスとパラメーター、リクエストとレスポンスのスキーマ、そして認証の方式です。操作ごとに、cURL、TypeScript、Dart、Python でのリクエスト例も組み立てます。仕様から生成されたものであって、更新を忘れる書き手が打ち込んだものではありません。埋め込みブロックも、外の世界を同じ目で見ます。本当に表示できる少数のサービスだけを見分け、それ以外については素のリンクを失敗ではなく真っ当な結果として扱い、信用しない住所は描くことをきっぱり拒みます。
同じ段落にいる二人
いま編集中のページは、サーバー上の一つのタスクが受け持ちます。ページごとに一つで、更新はすべて順にそこを通ります。同時編集を筋道立てて考えられるのはこのためです。先を行く書き手と競り合う二人目の書き手が存在しません。文書そのものは CRDT なので、同じ段落に打ち込む二人は互いを上書きせずに併合され、遅れたクライアントは互いに欠けているものを交換して追いつきます。更新は誰かに配られる前に必ず先行書き込みログへ追記されます。したがって文書にいる他の人が見ているものは、単に中継されたのではなく、すでに永続的に記録されたものです。権限は画面ではなくサーバーが行使します。編集権を持たずに参加した相手は読み取りへ降格され、文書が開いているあいだ、セッションはその権限を定期的に再確認します。だから取り上げられた権限は、再読み込みを待つのではなく、いま打っている本人にその場で及びます。
書き込みはすべて一つの扉を通る
文書は、そこに打ち込む人によっても、API を呼ぶプログラムによっても変わります。かつてはその二つの経路が、同じページへ別々に書き込めました。いまはできません。API からの書き込みは、その生きた文書を抱えているのと同じセッションへ回され、進行中の編集と並んで一つのトランザクションとして適用されます。ですから出来事の順序は一つだけで、ページの内容について別々の見解を持つ書き手が二人いることにはなりません。文書を書き戻すときブロックの id は保たれます。コメントがそこに錨を下ろしているからで、新しい id を作り直す突き合わせは、あらゆるコメントを何もない場所へ向けたまま残してしまいます。そして出来上がったブロックの集合が保存済みのものと同一であれば、何も書きません。
機械の鍵だけが届かない経路
個人の API キーは、REST、GraphQL、GraphQL の購読ソケット、そして MCP に対して使えます。共同編集のソケットに対しては使えません。これは意図したものです。共同編集の更新には、それを行った人の刻印が押され、その刻印がページの履歴に残る著者になります。機械の主体がそこで編集すれば、誰一人書いていない著者を書き込むことになり、それを後から取り消すとは、一行を消すことではなく、履歴を書き換えることです。境界は WebSocket と HTTP のあいだにはありません。その経路が著者つきの履歴を書くかどうかにあります。この規則は記憶ではなくコードの形が守ります。鍵を受け入れるには別の認証呼び出しへ意図して切り替える必要があり、ある経路がそれをすればテストが落ちるからです。
自分の住所を持つワークスペース
ワークスペースはどれも、作られたその瞬間から自分のサブドメインを持つテナントであり、テナントはリクエストが届いた住所から解決されます。したがって、あなたがどのテナントにいるかは、あなたのデータが一つも読まれないうちに決まっています。あとから付け足す、誰かが忘れうるフィルターではありません。その下では、データベース自身が行レベルのセキュリティで境界を守ります。リクエストごとに接続を借り、呼び出した人の身元をそこへ刻み、接続が返るときプールがその状態を消し去ります。ですから、あるリクエストの身元が次のリクエストの問い合わせへ漏れ出すことはありません。
ドメインを名乗ることと、証明することは別
エンタープライズ契約のワークスペースは、自分のドメインからページを配れます。ドメインを名乗ることと、そこから配ることは、意図して別の手順に分けてあります。ドメインは未検証のまま保存され、DNS に検証用のレコードが現れるまで、リゾルバはそれを完全に無視します。他社の住所をフォームに打ち込むことは誰にでもできます。それを生かすレコードを公開できるのは、そのドメインを実際に握っている人だけです。
そのページが持ってきたすべての版
Clepit は、ただ一つの現在の状態ではなく、版を残します。人が作業しているあいだ、自動でスナップショットが取られますが、ふつうに打っているだけで何百も生まれないよう抑えてあります。十分が経つか、十個のブロックが変わるか、先に来たほうで新しい一つが書かれます。復元は一つのトランザクションです。古いスナップショットを適用し、ブロックを突き合わせ、その復元自体を新しい版として書きます。ですから、後戻りは黙って取り消されるのではなく記録されます。突き合わせは元のブロック id を意図して保ちます。コメントはブロックに錨を下ろしており、新しい id でページを戻せば、その上のコメントはどれも錨を失うからです。
もう一度見つける
検索はページの投影の上で走り、問い合わせは手で SQL に組み立てられるのではなく、Postgres 自身のウェブ検索パーサーを通ります。だから引用符でもマイナス記号でも打ってよく、そのどれもが注入の入口にはなりません。ただし共有のワークスペースで効いてくるのは、権限の確認がどこに置かれているかです。検索はページの表と結合し、その表の行レベルのセキュリティが結合そのものに効きます。ですから結果は、尋ねた人が見てよいページにあらかじめ絞られています。絞り込み、つまりページ階層の一部分、最後に改訂した人、最後に編集された時期は、その上に条件として重なります。どれも範囲を狭めます。広げられるものは一つもありません。すべてが同じ確認の後ろに置かれているからです。
公開は凍らせる、共有は凍らせない
この二つは別物で、Clepit は意図して別々に扱います。ページを公開すると、いまの文書が版として凍結され、ページはそこを指すようになり、公になります。訪問者が clepit.space で、acme.clepit.space/handbook のような住所で読むのは、その凍結された版であって、その後に加えられた編集ではありません。公開を取り消すとその指し先は消えますが、公開用の住所は残ります。ですから後日あらためて公開すれば同じ URL に戻り、そこを指していたリンクをすべて壊すことにはなりません。共有リンクはその逆で、生きた文書を配ります。受け取った人が見るものは、ページが変わるにつれて変わります。
取り消せるリンク
共有リンクは取り消せるトークンで、発行のときに有効期限を付けられます。保存されるのはトークンのハッシュだけです。したがってリンクは作成時に一度だけ表示され、そのあとはデータベースから復元できません。私たちにも、そこへ辿り着いた誰にもです。これらのリンクが与えるのは読むことであって、コメントすることではありません。コメントには著者が要り、リンクを持っている人は著者ではないからです。
自社のディレクトリからサインインする
ワークスペースは、認証を自社の ID プロバイダーに委ねられます。ビジネス契約なら OpenID Connect、エンタープライズ契約なら SAML、その隣にディレクトリ同期のための SCIM です。SCIM が扱うのは、Okta や Entra が実際に動かすユーザーリソースであり、規格の素直な読み方から一点だけ、意図して外しています。削除はメンバーを消し去るのではなく、無効にします。仕様はそれを許しており、そうしない場合の姿は、誰かをグループから外しただけでワークスペースの中身を壊せるディレクトリ同期です。
話しかける四つの方法
REST は /v1 の下に四十四の操作を持ち、それらを記述するのは、ルートそのものから生成される OpenAPI 文書です。傍らに書き添えるものではありません。継続的インテグレーションはその出力をリポジトリのものと突き合わせるので、登録を飛ばしたルート変更が黙って入り込むことはできません。GraphQL はアプリケーションのモデルを覆い、購読は専用のソケットで運びます。リアルタイムは別のプロセスです。だからゲートウェイを再起動しても、リクエストの面まで道連れにはなりません。しかも許可は部屋単位ではなくソケット単位です。出来事ごとに、テナント内のすべての接続が一度のまとめた確認で評価され、見てよい相手だけが受け取ります。MCP は同じ操作を AI エージェントへ道具として差し出しますが、どの道具も、自分がどのワークスペースで動いているかを決めるのに呼び出し側の id を信用しません。書き込みは画面が使うのと同じサービスを通るので、権限の確認も監査の記録も同一のものです。
対象となる方
自分たちで制御できるエディターを必要とするチームと、構造化コンテンツを自社製品に組み込む開発者に。
サイトを見る Clepit: clepit.com