Real-time index of opencode sessions
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Refresh README for zero-copy staged tree flow and papaya-backed registries

Update consumer documentation to reflect the implemented Option C direction:
- tree stages are now plan -> resolve -> hydrate
- resolve stage exposes mmap-backed MappedSpan leaves
- hydration is explicit and layered

Rewrite the decomposed flow example to use plan_session_tree, resolve_session_tree, and hydrate_session_tree, including an example of reading raw bytes directly from a mapped leaf.

Also document that registry internals now use papaya for index/cache maps.

rektide 0b149a5f ec6e1993

+17 -10
+17 -10
README.md
··· 6 6 7 7 - Detects opencode storage paths (`$XDG_DATA_HOME/opencode/storage` by default). 8 8 - Builds an in-memory index of projects, sessions, messages, and parts. 9 - - Loads session/message/part JSON lazily through a memory-mapped file cache. 10 - - Lets you run workflows at different levels: index-only, per-entity load, or full session tree materialization. 9 + - Resolves session/message/part leaves as memory-mapped spans before hydration. 10 + - Lets you run workflows at different levels: index-only, reference tree, or hydrated tree. 11 11 12 12 The primary high-level entrypoint is [`SessionMaterializer`](/src/materializer.rs). 13 13 ··· 93 93 94 94 ### 5. Decomposed flow execution (Bon builder) 95 95 96 - Use staged planning + execution when you want control over how much gets loaded. 96 + Use staged planning + resolve + hydrate when you want full control and zero-copy leaves. 97 97 98 98 ```rust 99 99 use opencode_session::{SessionFlowOptions, SessionId, SessionMaterializer}; ··· 107 107 .part_limit_per_message(5) 108 108 .build(); 109 109 110 - let scope = materializer.plan_session_flow(&options)?; 111 - let message_scopes = materializer.plan_message_flows(&options, &scope)?; 112 - let result = materializer.run_session_flow(&options)?; 110 + let plan = materializer.plan_session_tree(&options)?; 111 + let ref_tree = materializer.resolve_session_tree(&plan.value)?; 112 + let hydrated = materializer.hydrate_session_tree(&ref_tree.value)?; 113 + 114 + // zero-copy leaf access before hydration 115 + let first_message = &ref_tree.value.session.messages[0]; 116 + let raw_bytes = first_message.span.as_bytes(); 113 117 114 118 println!( 115 - "planned_messages={} loaded_messages={}", 116 - message_scopes.len(), 117 - result.messages.len(), 119 + "planned_messages={} hydrated_messages={} first_message_bytes={}", 120 + plan.value.messages.len(), 121 + hydrated.value.messages.len(), 122 + raw_bytes.len(), 118 123 ); 119 124 ``` 120 125 ··· 124 129 - [`SessionMaterializer`](/src/materializer.rs): high-level indexed read API 125 130 - [`SessionLoader`](/src/loader.rs): lower-level loader over `FileReader` 126 131 - [`FileReader`](/src/storage/reader.rs): path-based typed JSON reads + listing helpers 127 - - [`MappedFileCache`](/src/storage/mmap.rs): memory-mapped file cache 132 + - [`MappedSpan`](/src/storage/reader.rs): file-backed byte range leaf for zero-copy tree stages 133 + - [`MappedFileCache`](/src/storage/mmap.rs): memory-mapped file cache (papaya registry) 128 134 129 135 ## Notes 130 136 131 137 - This crate is pre-1.0 and API shaping is active. 132 138 - Backward compatibility between minor revisions is not guaranteed yet. 133 139 - `watch` and `watch-fallback` features are reserved for live change tracking integration. 140 + - Registry internals use `papaya` concurrent hash maps for index and mmap caches.