| name | grasp |
| description | ユーザが指定した Scrapbox/Cosense JSON export、または既に import 済みの grasp local store を CLI から調べるスキル。ページ本文だけでなく、行レベル逆リンク、2-hop related、未解決 target を 近傍同梱で読む。ユーザが「この JSON を読んで」「自分の Cosense export から探して」 「この概念への言及はどこか」「関連ページは何か」「本文のない概念ハブを見たい」などと依頼した時に使う。 |
grasp Skill 手順書
grasp CLI で、ユーザが指定した Scrapbox/Cosense JSON export から作った local グラフストアを読む。source JSON / hosted project に対しては read-only。import は SQLite index を作るだけで、元 JSON は変更しない。Markdown-backed project だけは authoring fast path として append-log / write-page / rename-page の alpha write surface があり、明示的な file-back / dogfood 目的で使う。
各 verb の引数・戻り値スキーマ・例は、使う直前に grasp <cmd> --help を読む(このファイルには列挙しない)。
最初にデータソースを確定する
-
ユーザが JSON export path を指定している場合は、その JSON を使う。特定ユーザ名・固定パス・固定 project URL を仮定しない。
-
既に store がある前提の依頼なら grasp stats で store の状態を確認してから読む。
-
read / search / backlinks / related / path / unresolved は、--project が無ければ whole-store default。複数 project を跨ぐ発見を期待する依頼では project を先に絞らない。単一 project 指定がユーザ意図や安全上必要な時だけ --project <name>(または $GRASP_PROJECT)を付ける。
-
一回限りの JSON 調査では、既定 store を上書きしないよう task-local store を使う:
grasp --store /tmp/grasp-task.sqlite import --cosense "/path/to/export.json"
grasp --store /tmp/grasp-task.sqlite read "ページタイトル"
-
ユーザが「自分の通常 store に取り込んでよい」と分かる場合だけ、既定 store へ import する:
grasp import --cosense "/path/to/export.json"
grasp read "ページタイトル"
-
store が無い、または指定 JSON が見つからない場合は、勝手な別データで代用せず、JSON export path か store path を確認する。
-
ユーザが Markdown folder、またはこの repo の wiki/ を調べたい場合は、必要に応じて task-local store へ read-only mirror として index する:
grasp --store /tmp/grasp-wiki.sqlite import --markdown wiki --project grasp-wiki
grasp --store /tmp/grasp-wiki.sqlite read grasp-v1-implemented
最小 Markdown mirror は frontmatter title / id / aliases / tags を読み、title が無い場合は first H1、さらに無ければ file stem を title にする。[[...]] と #tag を grasp 内 edge にする。duplicate title / alias は import 全体を止めず、read <handle> の ambiguity 候補として返る。backlinks <ambiguous handle> は handle 自体への incoming lines を主に返し、候補 page ごとの確定 backlinks も分けて返す。related <ambiguous handle> は handle 自体への source pages と候補 page ごとの related を分けて返す。ambiguities は store 全体または selected project の曖昧 handle を一覧する。duplicate frontmatter id は identity 衝突なので error。バックティックのプレーン名(親 llm-wiki への cross-wiki 参照)は edge にしない。既存 Markdown folder へは書き戻さない。重い raw/generated directory を避けたい時は --markdown-exclude-dir raw のように directory basename を指定する。再 import は content-only 変更なら差分更新し、title / id / aliases / graph role / exclude dirs / file set が変わった時は安全に full rebuild する。index.md / log.md など navigation/log artifact は本文検索対象に残しつつ、既定 content graph では outgoing edges を除外する。Obsidian block refs はまだ未実装。
-
ユーザが wikis.yaml のような Markdown wiki registry 全体を読みたい場合は、task-local store へ import-forest で一括 index する。各 entry は project <name> として <path>/<wiki-dir> を import し、entry ごとの missing/failure/skipped diagnostics と forest-level ambiguities summary を返す:
grasp --store /tmp/grasp-forest.sqlite import-forest /path/to/wikis.yaml --markdown-exclude-dir raw
import 後は grasp --store /tmp/grasp-forest.sqlite unresolved で、複数 wiki に出る未本文概念ハブを whole-store に探せる。JSON では project / projects / project_count と、example edge の source_project / target_project / link_kind / connection_strength を見る。
grasp とはどういう物か
- Scrapbox/Cosense の JSON export、または Markdown folder mirror を取り込み、SQLite graph store にしたもの。
- ページは行ベース。Cosense では
[ページ名](単角括弧)と #tag、Markdown mirror では [[ページ名]] と #tag を edge にする。read 出力は元の行テキストのまま。
- 結果は project label 付きで読む。明示 link は
connection_strength=strong、cross-project normalized-title 推論は connection_strength=weak / link_kind=inferred-normalized-title として返るので、weak は発見ヒントとして扱う。
- 中核は read=近傍同梱:
grasp read <title> 一発で、本文 + 行レベル逆リンク + related(2-hop) + そのページから出る未解決 target が一緒に返る。--related-snippets を付けると related/source ページの先頭行を同梱でき、--related-snippet-mode edge なら related/source item を導いたリンク行を同梱できる。
- オフライン・即時(store があれば各コマンド sub-second)。
グラフの読み解き方(Tips)
- キーワード検索だけに頼らず、関連リスト・逆リンクを眺めて辿る。単独ページでは見えない文脈が浮かぶ。
- 被リンク数(read の
links_to_this / link-stats)が大きいページや target は、実質カテゴリ的ハブとして機能している。
- 本文の無い(page なし)観念的タイトルでも、意味は他ページの文脈に宿る。
read/backlinks/related は page が無い target でも、それを参照している source pages を返す。「本文なし=無意味」ではない。
- 例: 本文ページが無い target でも、多数のページから参照されていれば
grasp read <target> で参照側の文脈を読める。
こういう時はこうする
タイトルが分かっている / そのページを軸に調べたい
→ grasp read <title>。本文+逆リンク+related+未解決を一括取得。これが基本。related の見出しだけでは足りず冒頭本文も同時に見たい時は --related-snippets(既定 5 行、--related-snippet-lines N で調整)。related/source item がなぜ出たかを見たい時は --related-snippet-mode edge を足して根拠リンク行を同梱する。逆リンクや related が切れていたら --backlinks-limit 等で広げる。
テーマ・問いから探す(タイトル未確定)
→ grasp search <query> で本文行を検索(行レベル hit)し、良さそうな source_title を grasp read で開く。タイトルの当たりが付くなら grasp suggest <partial>(タイトル補完)。suggest の既定は fuzzy で、長文タイトルに対し空白区切り断片や詰めた文字順序でも候補を返す。厳密な部分一致だけにしたい時は --mode substring。
search の既定は、空白も含めて入力文字列そのものを探す literal line substring 検索。英文 phrase や空白入り query はまずこの既定でよい。
- 複数語を論理条件として探したい時は
--mode boolean を付ける。AND / OR / NOT、括弧、quoted phrase、隣接 term の implicit AND が使える。例: grasp search "KJ法 AND 表札" --mode boolean --scope page。
--scope line は1行内で式を評価し、--scope page は同一ページ内の全行で式を評価してから該当行を返す。旧「空白区切り page AND」は --mode boolean --scope page "alpha beta" で明示的に再現する。
- 該当行の前後も必要なら
--context N を付ける。JSON では各 hit に context_lines[] と context_window が入り、text では hit 直下に周辺行が出る。
- literal で0件の時は、NFKC と長音ゆれ(例:
ユーザテスト / ユーザーテスト / ユーザテスト)を緩く合わせる normalized fallback が走る。text 出力では該当行に [normalized] が付き、JSON では match_mode: "normalized" になる。大規模 store では完全なかな/カナ変換 scan は行わない。normalized fallback は literal mode 用。
長大ページ・ログページを読む
→ 親 conversation に長い read 出力を直接持ち込まない。まず探索用 subagent / Explore agent に任せ、subagent 側で search / peek / limit 付き read を使って読む。
- 親に返すのは、結論・根拠ページ・該当
line_id・必要な短い引用/要約だけにする。中間の大量 stdout、長大本文、網羅的検索結果は subagent context に閉じ込める。
- CLI 側は要約しない。grasp は LLM 依存の summarizer ではなく、行 ID 付きの deterministic graph reader。要約と取捨選択は Skill / subagent の責務。
- 長大ページを直接開く必要がある時も、先に
grasp search <query> --context 2 --json で hit line と短い周辺を読む。さらに広げる必要がある時だけ、完全 line_id を使って grasp read --around-line <line-id> --line-context 5 で追加の周辺行を読む。ページ本文を順に見るだけなら grasp peek <title> --line-offset N --line-limit M でページングする。ページ先頭だけで足りる時は grasp read <title> --line-limit <N> で範囲を絞る。親へ戻す時は再アクセスできる source_title と完全 line_id を残す。
「この概念にどこで言及したか」
→ grasp backlinks <title>((source_title, line-id, 行テキスト))。read の Backlinks 節と同じものを単体で。page が無い概念にも効く。
「この概念と関連するページ」
→ grasp related <title>。existing page なら 2-hop ページ、page なし target ならそれを参照する source pages。
「この概念とこの概念はどう繋がるか」
→ grasp path <A> <B> --max-depth 4。pages と page なし target をどちらも node として扱い、materialized internal links を無向 edge として短い経路を返す。経路の edge には根拠 line が付くので、bridge が意味的に妥当かを確認する。密な hub では展開が大きくなるため、まず --max-depth 4 --limit 1 で見る。端点は見つかったが経路が無い時も recovery_hints.path に次に試す depth、related、backlinks、link-stats が入るので、単なる不在として扱わない。
巨大 hub / 裸言及を扱う
→ grasp gather <query> を最初に見る。link stats、裸言及 summary、co-link slice、representative mentions、backlinks、次に実行する recipe が bounded に返る。returned_counts / total_counts / omitted_counts は row 単位(mentions=bare mention lines、co_links=targets、backlinks=link rows)なので、足りなければ個別 verb で広げる。--budget は厳密 token packing ではなく row limit selector。
- 裸言及の監査:
grasp mentions <query>。既定は parsed internal-link span 外の bare occurrence がある行だけ返す。各行は exact-link-page / query-link-page / unlinked-page に分類され、summary に come_from_candidate(初期 heuristic score / signals / rationale)が入る。page に query 系 link handle が無い行だけ見たい時は --unlinked、全 occurrence が link 内の行も見たい時は --include-linked。
- slice handle 探索:
grasp co-links <query>。query を含む行で同時に出る internal links を rank する。既定 --rank slice は target title 自体が query を含むものを query-containing-title として後ろへ回し、narrower handle を先に出す。raw count order が必要なら --rank raw。
- 重要:
mentions の裸言及は「全部リンク化すべき漏れ」ではない。bulk link 化は hub を悪化させることがある。come-from 昇格候補や、用途別 handle への分岐を考えるための観測値として扱う。
被リンクの濃さだけ知りたい / その概念が既出か
→ grasp link-stats <title>。incoming link_count と 0/1/N(none/single/multi)。
まだ本文の無い「概念ハブ」を見渡したい
→ grasp unresolved。多くのページから参照されるのに本文ページが無い target を rank。
- これは「書くべき TODO リスト」ではない。多参照の未解決 target は、本文が無くても他ページの文脈で既に意味を持つ概念ノード。「次に書く候補」や調査の起点として眺めるのはよいが、全部を埋めるべき穴と解釈しない。
本文だけ見たい(近傍は不要)
→ grasp peek <title>。長大ページでは --line-offset N --line-limit M で本文行だけをページングする。
AI に渡す 1 ファイルの近傍 bundle が欲しい
→ grasp export-ai <title>。Cosense の "Export for AI" 風に main page + 1-hop pages を 1 テキストへ展開する。default は --depth 1 かつ limit なし。2-hop まで欲しい時は --depth 2、ファイルへ保存する時は --output <path>。
hosted の最新を取り込みたい(保守作業)
→ ユーザが指定した project URL で grasp sync <project-url>(cosense CLI 経由で最近更新ページのみ差分 upsert。--dry-run あり)。@helpfeel/cosense-cli の cosense binary が PATH にあり、対象 project に認証済みであることが必要。通常の JSON 調査では不要。
管理者 export が無い hosted project を部分取得したい
→ grasp acquire <project-url>。これは full seed 済み project の freshness path である sync とは別で、読めるページだけを local store の project namespace に取り込む初回 seed。
- 特定文字列を含む slice:
grasp --project <project:slice> acquire <url> --search <query> --limit N
- 自分の icon / 編集 page slice:
grasp --project <project:mine> acquire <url> --filter <name> --limit N
- 起点 page から link crawl:
grasp --project <project:crawl> acquire <url> --from-page <title-or-url> --depth N --limit N
- URL/title リスト:
grasp --project <project:seed> acquire <url> --seed-file pages.txt
acquire は対象 project namespace を置き換える(append しない)。既存 full export を誤って潰さないよう、--project 省略時の local namespace は <remote-project>:acquire になる。partial corpus の backlinks / related / unresolved は「取得済み subset 内」の結果であり、hosted project 全体の事実として答えない。grasp stats の Acquisition 節で coverage と前回 acquisition criteria / candidate updated range / remote_fetched / reused を確認する。
同じ acquisition criteria で再実行すると、前回 page manifest と hosted metadata の updated が一致するページは local store から再利用し、不要な readPage を避ける。searchFullText や seed-file など hosted updated metadata が無い候補は stale を避けるため従来通り読む。
取得候補が全て失敗しても partial acquisition report として exit 0 で返ることがある。diagnostic.type=all_failed、failed_pages[].error_class、diagnostic.next_actions を見て、cosense binary / node PATH / login / seed title を切り分ける。
既存 store 内の [/project/page] refs を外部 project acquisition の seed bibliography として使う時は grasp cross-project-refs を先に見る。これは search "[/" ではなく parsed link target extraction なので、.icon / project root / self-project / semantic page ref を target 単位で分けられる。
grasp --project <source-project> cross-project-refs --semantic-only --limit 20
grasp --project <source-project> cross-project-refs --semantic-only --limit 20 --seed-dir /tmp/grasp-seeds
grasp --project <source-project> cross-project-acquire --limit 5 --seed-limit 10 --dry-run
--semantic-only は .icon、project root、自 projectへの refs を除き、外部 project の page refs だけを rank する。--seed-dir を付けると target project ごとに seed file を書き、対応する grasp --project <project>:semantic acquire ... --seed-file ... command も返す。raw な混在を見たい時は --exclude-icons や --include-self を使い分ける。
実取得まで行う時は cross-project-acquire を使う。これは cross-project-refs --semantic-only の seed titles を使って target project を <project>:semantic namespace に順に partial acquire し、各 project の fetched / failed / diagnostic / reciprocal refs / top internal links を bounded summary として返す。store を更新するので、まず --dry-run で計画を確認する。
verb 一覧(snapshot — 詳細は各 grasp <cmd> --help)
| verb | 用途 |
|---|
read <title> | 本文+逆リンク+related+未解決を近傍同梱で(--related-snippets で related/source ページ冒頭、--related-snippet-mode edge で根拠リンク行も同梱) |
search <query> | 本文行を検索。既定は literal line substring、--mode boolean で AND/OR/NOT、`--scope line |
suggest <partial> | タイトル補完。既定 fuzzy は長文タイトルの断片語・文字順序近似を拾う。--mode substring で厳密部分一致 |
backlinks <title> | 行レベル逆リンク(page なし target も) |
related <title> | 2-hop ページ / page なし target の source pages / ambiguous handle の source pages + candidate related |
path <A> <B> | pages / page なし target 間の短いリンク経路(no-path 時も recovery hints) |
mentions <query> | literal query の裸言及を link span 外 occurrence として数え、page-level link status と come-from 昇格候補 score を返す。--unlinked で no-link-handle page に絞る |
co-links <query> | query を含む行で同時に出る internal links を rank し、hub の slice handle を返す。target_relation と `--rank slice |
cross-project-spread <title> | normalized title が project 群にどれだけ広がるかを見る weak signal。materialized / ambiguous / unresolved / incoming counts を project label 付きで返し、page identity は merge しない |
cross-project-spreads | seed title なしに normalized handle の project spread を rank する。structural-name / numeric-only / artifact-only は label して下位 band に回す |
cross-project-refs | Cosense shorthand [/project/page] を target-aware に抽出し、semantic / .icon / project root / self-project に分類して project 別に rank。--seed-dir で acquire seed files / commands を生成 |
cross-project-acquire | cross-project-refs --semantic-only の seed titles から複数 hosted project を <project>:semantic に一括 partial acquire。--dry-run あり。実行後は reciprocal refs / top internal links も返す |
gather <query> | link stats・裸言及 summary・co-link slices・backlinks・next recipes の bounded bundle。row 単位の returned / total / omitted counts 付き |
adopt-markdown <folder> | 既存 Markdown wiki を store + JSONL journal に採用する authoring fast-path 入口。log page sections と type: log-entry files は log_entry_import record にも split する |
import-log-records <folder> | 既存 journal に対し、Markdown log sections / type: log-entry files から未記録または更新された log_entry_import records を追記する |
log-records | JSONL journal の log_entry_import records を SQLite なしで検索・一覧する event-stream surface。--query(空白 term AND)/ --subject / --op / --source-path / --since / --until / --include-superseded あり。record は subjects[]、record version、later same-subject events を返す |
history <query> | read <page> と分けて log event stream を subject で検索する surface。query は extracted subjects[] に一致し、同 subject の later events を同梱する |
export-markdown --output <folder> --check | SQLite store を authority とする Markdown projection freshness gate。差分があれば exit 1。JSON は projection_policy(authority=sqlite, base=stored_markdown_lines, output_role=git_tracked_projection)を返す。明示 alpha overlay として --regenerate-index / --regenerate-log も持つ。--regenerate-log は既定で SQLite events から log page events と latest record-per-file records を primary log page へ生成し、--journal <events.jsonl> は legacy/ad hoc audit source に切り替える |
append-log | Markdown-backed log page に dated entry を追記し、SQLite index / SQLite event / Markdown projection を更新する alpha write surface。既定では compatibility JSONL journal も更新し、--no-journal で省略できる。projection export が event write 後に失敗した場合は SQLite state を event_revert で自動 rollback し、--json では stderr に diagnostic.type=projection_export_rollback を返す |
write-page <title> | Markdown-backed page の本文行を全置換し、page_update event と projection を更新する alpha write surface。既定では compatibility JSONL journal も更新し、--no-journal で省略できる。projection export が event write 後に失敗した場合は SQLite state を event_revert で自動 rollback し、--json では stderr に diagnostic.type=projection_export_rollback を返す |
rename-page <target> <new-title> | Markdown-backed page の page id を保ったまま title / optional source path を変更し、旧 title を alias として残す alpha write surface。title / current file stem から導出できない旧名 alias を fresh import 後も保つ必要がある時は projection に id / title / aliases frontmatter を出す。既定では compatibility JSONL journal も更新し、--no-journal で省略できる。projection export が event write 後に失敗した場合は SQLite state を event_revert で自動 rollback し、--json では stderr に diagnostic.type=projection_export_rollback を返す |
write-status | alpha write 用に journal 件数・log record 件数・last event・Markdown projection check を返す。journal がある場合は primary log page を journal 由来 projection と比較し、journal_log_stale / journal_log_changed_files も返す。log page がある Markdown project では SQLite events 由来の semantic log projection も check し、semantic_log_projection / semantic_log_stale / semantic_log_changed_files を返す。SQLite events が selected-project JSONL journal events 内に順序を保って現れるかを event_streams_match / event_stream_mismatch で返す。--strict は projection dirty / journal missing / event stream mismatch / stale log / semantic log drift / log regeneration error で exit 1。--no-journal --strict は JSONL guards を省き、SQLite-authority projection と semantic log projection を strict check する |
revert-plan <event-id> | SQLite event stream から read-only rollback plan を返す。--scope log-batch は anchor event を含む file-back 風の作業単位を、前後の log_append 境界から推定する。--scope same-page-dependents は log-batch 境界が無い時に、anchor と後続 active same-page reversible events を rollback candidate として返す。--scope event-window --before/--after は semantic boundary が無い小さな multi-page 連続 event_sequence window を明示的に候補化する。--scope subject-log は closing log_append の wikilink/Markdown path subjects で広すぎる log-batch を絞る。--scope log-page-subjects は legacy/direct Markdown history のように closing log entry が log.md の page_update として入った場合、追加 log lines の subjects で候補を絞る。--scope content-subjects は page content の changed lines から抽出した wikilink/Markdown path subjects と event target の overlap で候補を絞り、changed lines に subject がない場合は anchor target を fallback subject にする。--scope version-bump は同じ log-bounded slice 内で anchor と複数 events に共有される semver token を使い、release/file-back version update を候補化する。推論 plan は選ばれた page event を戻すために必要な後続 same-page dependents も dependent_event_ids として候補に足す。--scope time-burst --max-gap-seconds は anchor 周辺の隣接 events を created_at gap で明示的に束ね、log_append 境界は越えない。--scope session は non-empty session_id が同じ events を metadata から候補化する。いずれも revert-events に渡す candidate event ids / reverse order / revertible を返し、mutation なし |
revert-event <event-id> | page_create / section_append / log_append / page_update / page_rename を current state 一致時だけ取り消し、SQLite event_revert を記録する。--dry-run は同じ safety check を mutation なしで返す。SQLite target では --include-dependents で後続 active same-page reversible events を逆順に先に revert できる。既定では compatibility JSONL journal も更新し、--no-journal で省略できる |
revert-events <event-id...> | 明示した複数 SQLite events を reverse event_sequence order で1 transaction rollback する。multi-page file-back など、rollback 対象 event ids が分かっている時に使う。--dry-run あり |
replay-journal | JSONL journal だけから Markdown projection を再構築・check する alpha recovery surface。log_entry_import は projection を変えない record event として読む。page guard は line_index + text を比較し、direct re-import 由来の line_id drift では止めない |
link-stats <title> | incoming link count と 0/1/N |
unresolved | 未解決 target の rank view(TODO ではない) |
peek <title> | 本文行のみ。--line-offset N --line-limit M でページング |
stats | store の状態・件数 |
import --cosense <json> / import --markdown <folder> | Cosense JSON / Markdown folder mirror の取り込み・再構築 |
import-forest <wikis.yaml> | Markdown wiki registry の複数 entries を 1 store の複数 project namespace に一括 import。entry diagnostics と ambiguity summary 付き |
export-ai <title> | Export for AI 風の単一テキスト bundle(alias export-for-ai) |
sync <url> | hosted 差分取り込み(保守) |
acquire <url> | admin export なしの hosted 部分取得 seed |
実行方法
- 形式:
grasp <verb> ...。store は既定では home に1個 ~/.grasp/grasp.sqlite(global default)。
- 1つの store に複数 project namespace を保持できる。
grasp import --cosense <json> は export JSON の name を、grasp import --markdown <folder> は folder 名を project 名として使い、同名 project だけを置き換える。project 名を明示する時は grasp import --project <name> --cosense <json> / grasp import --project <name> --markdown <folder>。
- 一回限りのユーザ指定 JSON を読む時は、必要に応じて
--store <task-local.sqlite> を使い、既定 store に project を増やさない。
- 未インストール環境では grasp repository root から
python3 -m grasp <verb>(pip install -e <grasp-repo> 済みなら grasp が PATH)。
grasp import --cosense <json> で Cosense JSON export、grasp import --markdown <folder> で read-only Markdown mirror、grasp import-forest <wikis.yaml> で registry 配下の複数 Markdown wiki を import する。authoring fast path では grasp adopt-markdown <folder> --journal <events.jsonl>、grasp import-log-records <folder> --journal <events.jsonl>、grasp log-records --journal <events.jsonl>、grasp history <query> --journal <events.jsonl>、grasp export-markdown --output <folder> --check、grasp append-log ... --output <folder>、grasp write-page ... --from-file <file> --output <folder>、grasp rename-page <target> <new-title> --new-path <path.md> --output <folder>、grasp write-status --output <folder>、grasp revert-plan <event-id>、grasp revert-event <event-id> --output <folder>、grasp revert-events <event-id...> --output <folder>、grasp replay-journal --journal <events.jsonl> --output <folder> --check を使う。write 系は Markdown-backed project の unique handle / page-id / path に限る alpha surface。append-log / write-page / rename-page / revert-event / revert-events は既定では compatibility JSONL journal も更新し、--no-journal では SQLite events と Markdown projection だけを更新する。append-section public CLI は 1.8.70 で削除済みで、既存 section_append event は replay/revert 互換としてだけ残る。global --actor / --session-id(env GRASP_ACTOR / GRASP_SESSION_ID)は write/revert/import-log/adopt path の SQLite event metadata に入る。write 系 command が SQLite event write 後に projection export で失敗した場合、state を戻す event_revert を SQLite events に記録し、journal あり mode では compatibility JSONL にも追記する。--json 失敗時 stderr は diagnostic.type=projection_export_rollback、target_event_id、rollback_event_id、journal_written、original_error を返す。write-status --no-journal --strict は JSONL guards を省き、SQLite-authority projection と SQLite events 由来の semantic log projection を strict check する。adopt-markdown と import-log-records は log.md の ## [YYYY-MM-DD HH:MM] op | summary sections と type: log-entry files を stable record_id 付き log_entry_import event に split する。section record は body の [[wikilink]] と Markdown path から subjects[] を推定し、file record は page identity を record_id にして frontmatter subjects / pages を explicit subjects として優先し、body 由来は heuristic_subjects[] に分ける。record payload は content_fingerprint を持ち、import-log-records は同じ record_id の fingerprint が変わった時に新 version event を append する。log-records / history は SQLite log_entry_import rows を優先し、無い場合だけ legacy JSONL journal records に fallback する。既定では superseded version を隠し、監査時は --include-superseded を使う。log-records --query は heading/body/source への空白 term AND search、log-records --subject と history <query> は extracted subjects[] に一致させ、返した record には同 subject の later events を同梱する。write-page は title / aliases / source path を変えず本文行だけ全置換し、1.8.32 以降の page_update event payload は source_path / graph_role も持つ。rename-page は page id を保ち、旧 title を alias にして incoming [[旧名]] の surface text を書き換えない。rename 後に path / H1 から page identity が推論できても、title / current file stem から導出できない旧名 alias がある場合は projection が id / title / aliases frontmatter を生成するため、direct re-import でも page id と旧名 alias が残る。export-markdown は SQLite store を authority とする Markdown projection writer/checker で、JSON result の projection_policy に authority / base / output_role / write_mode / generated_overlays を返す。export-markdown --regenerate-index は primary index.md を catalog projection に、--regenerate-log は既定で SQLite events から primary log page を log page events + latest record-per-file records で生成し、--journal <events.jsonl> を付けた場合だけ legacy JSONL stream を読む。write-status は通常 projection check に加え、journal がある場合は primary log page と journal 由来 projection を比較し journal_log_record_count / journal_log_stale / journal_log_changed_files を返す。log page がある project では SQLite events 由来の semantic log projection も check し、semantic_log_projection / semantic_log_stale / semantic_log_changed_files を返す。clean な generated log projection がある場合、stored log lines と generated log の差だけでは strict failure にしない。ship loop では write-status --strict を使い、projection dirty / journal missing / event stream mismatch / stale log / semantic log drift / log regeneration error を exit 1 にする。revert-plan --scope log-batch は anchor event を含む file-back 風作業単位を前後の log_append 境界から推定し、revert-plan --scope subject-log は closing log の subjects に一致する page events と closing log だけを候補化し、revert-plan --scope log-page-subjects は log.md の page_update に追加された log lines の subjects に一致する page events と closing log page update だけを候補化し、revert-plan --scope content-subjects は anchor event の changed lines から抽出した subjects と changed subjects / event target overlap で page events を候補化し、changed lines に subject がない場合は anchor target を fallback subject にし、revert-plan --scope same-page-dependents は log-batch 境界なしで anchor と後続 active same-page reversible events を候補化し、revert-plan --scope event-window --before/--after は semantic boundary が無い小さな multi-page 連続 event_sequence window を明示的に候補化し、revert-plan --scope time-burst --max-gap-seconds は anchor 周辺の隣接 events を created_at gap で明示的に候補化し非 anchor log_append 境界は越えず、revert-plan --scope session は non-empty session_id が同じ events を metadata から候補化し、candidate event ids / reverse order / revertible を read-only で返す。revert-event --dry-run は同じ safety check を rollback-only transaction で評価する。actual revert は append event の inserted lines が現在も page tail にある時、page_update の current lines が一致する時、page_rename の current lines / title / path が一致する時、または --include-dependents で後続 active same-page reversible events を逆順で先に戻せる時だけ動く。revert-events は明示した複数 SQLite events を reverse event_sequence order で1 transaction rollback する。replay-journal は page_create / page_update / page_rename / section_append / log_append / log_entry_import / event_revert の strict replay に対応し、page guard は line_index + text を比較するため line_id drift だけでは止めない。broader generated projection policy はまだ無い。以降は sub-second。別パスは --store / $GRASP_STORE、別 home は $GRASP_HOME。
1.8.37 以降、revert-plan の推論 plan は選ばれた page event を戻すために必要な後続 same-page dependents も dependent_event_ids として候補に足し、read-only plan がそのまま revert-events へ渡せるかを検査する。
1.8.38 以降、revert-plan --scope version-bump は anchor の changed lines にある semver token のうち同じ log-bounded slice 内の複数 events に共有されるものを使い、release/file-back version update を read-only rollback candidate set として返す。
- この repo の file-back dogfood では、gitignored store
.grasp/file-back.sqlite、project grasp-wiki、output wiki を既定の組として使い、通常編集は --no-journal path にする。repo default store/output pair は .grasp/file-back.sqlite + wiki で、temp dogfood は temp store + temp output を使い、default store と temp output を混在させない。tracked wiki.grasp/events.jsonl は 1.8.18 で退役・削除済みで、通常 file-back は repo に JSONL を作らない。通常編集の authority は SQLite store 側に置き、各 file-back に一意な GRASP_SESSION_ID を設定し、必要なら claim-page で同じ session の active page_claim を記録してから git fetch origin と python3 scripts/check_file_back_preflight.py(no-journal default)を通す。preflight は current upstream(なければ origin/main)を基準にして、未使用 session id(preflight 前の same-session active page_claim は許可) / fresh store は gitignored .grasp/file-back-adopt.jsonl へ bootstrap / remote 分岐なし / wiki dirty なし / 退役済み JSONL path の再作成なし / write-status --no-journal --strict / SQLite authority projection を検査し、gitignored preflight stamp に session/head/base と latest SQLite event_sequence を記録し、gitignored file-back lock .grasp/file-back.lock.json を取得する。最初の write command 直前に python3 scripts/check_file_back_write_start.py(no-journal default)を通し、preflight 後に projection / stamp / lock / store status が動いていないことと latest SQLite event_sequence が preflight 時点から増えていないことを import なしで検査する。全 write command には同じ session metadata を残す。postwrite は同じ session id を要求し、preflight stamp の session/head/base 一致と file-back lock の session 一致も要求し、write 後に python3 scripts/check_file_back_postwrite.py(no-journal default)で preflight 後に増えた全 SQLite events の session_id / latest event session / strict status / projection policy / SQLite events 由来の semantic log projection / wiki lint / diff whitespace をまとめて検査し、clean な時だけ lock を解放する。ship loop では python3 scripts/check_file_back_runbook.py で runbook が no-journal default と retired journal policy から drift していないことを検査し、commit 後・push 前に python3 scripts/check_push_ownership.py で dirty worktree / behind branch / 通常の protected branch push を止める。--journal / --with-journal は CLI の legacy/ad hoc audit 用には残るが、repo runbook では使わない。grasp alpha が安全に表現できない変更だけ fallback する。
- Mode2 Markdown 直接編集は既定 reject。mode2 write / cutover / export の前には
python3 scripts/check_mode2_markdown_readonly.py を走らせ、Markdown projection が SQLite authority として clean / strict green であることを確認する。失敗時は Markdown を authority と扱わず、直接編集・fallback patch・remote merge が意図的なものならまず reconcile-markdown --dry-run で採用可能性を見る。dry-run に blocker が無い時だけ fresh GRASP_SESSION_ID で明示的に reconcile する。unsupported blocker は自動 merge せず、real dogfood で必要が出てから purpose-named merge surface を作る。generic merge / queue は先に足さない。
- import 済み JSON は store 横の
<store>.imports/ に復旧用コピーとして保持される。通常 command が古い schema の store を見つけた時は、復旧用コピーからサイレントに current schema へ再構築して続行する。stats は診断用なので自動再構築しない。hosted の最新差分は復旧後も sync の責務。
- 複数 project がある store で読む時は
grasp --project <name> read "ページタイトル" のように project を指定する。project が1つだけなら省略可。
- text 出力の
line_id は既定で P1:0 のような実行内ローカル別名に短縮され、先頭付近に P1=<page-id> の legend が出る。親へ根拠として返す時は、必要なら source_title とこの alias ではなく --json の完全 line_id を使う。
- 機械可読が要る時は
--json。root option だが verb 後にも置ける: grasp --project <name> read "ページタイトル" --backlinks-limit 3 --json。text のまま完全 line id を見たい時は --full-ids(これも verb 後可)。--store / --project は verb の前。
- 空白・記号を含む title / query は shell でクォートする(
'...')。
回答の形式
- 情報源(ページタイトル)を示しながらユーザーの問いに直接答える。
- 本文の無い概念について答える時は「本文なし、関連 N ページの文脈から」と限界を明示する。
- 回答言語はユーザの言語に合わせる。nishio/grasp の開発 wiki や
/ship-next 運用について答える時は、特に指定がなければ日本語で簡潔に返す。
- 固定テンプレートは規定しない。
hosted Cosense との使い分け
| grasp(このスキル) | hosted Cosense / cosense CLI |
|---|
| データ | ユーザ指定 JSON / Markdown folder から作った local snapshot / local store(オフライン・即時) | hosted の生の最新状態 |
| 強み | 行レベル逆リンク・未解決 target 列挙・近傍同梱を1コール | hosted project の最新取得・編集 |
| 向く時 | export 済みデータをグラフで辿る/逆リンク・関連を厚く見る | 最新の hosted 状態が要る/hosted project に書き込む |
最新性が要らず「逆リンク・関連・未解決をグラフごと厚く読む」なら grasp。生の最新や hosted への書き込みが要るなら hosted 側の手段を使う。