feat(ai-tools): omp shared + OpenCode/omp sessions, tokens, subagents; Grok hooks; resume by id
- omp-usage.js / opencode-usage.js: poll each CLI's own session store into sessions (tool omp/opencode), token_usage per model and subagent agents; transcript routes read them (omp journals, OpenCode's opencode.db). - Grok runs the Claude hooks in ~/.claude/settings.json: its hooks are now recognised (hookEventName + workspaceRoot), tagged tool=grok, and their transcript_path dropped instead of being parsed as a Claude transcript. - Catalog `resumeById`: omp/Grok/Cursor `--resume <id>`, OpenCode `--session <id>`; session ids may carry `_`. The client offers Resume for any tool that resumes by id. - Kimi Code and GitHub Copilot leave the catalog (their session stores could not be verified).
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* @file Reads what an append-only JSONL journal gained since a byte offset —
|
||||
* the incremental read a session-journal poller does (omp-usage.js). Only
|
||||
* complete lines are returned: one still being written
|
||||
* stays for the next pass. Every open goes through `openSafeAsync`, so a
|
||||
* member's journal (S3) is read only when it is a regular file they own,
|
||||
* never through a link.
|
||||
* @author Nguyễn Ngọc Trí Vĩ <vinnt@smartgift.vn>
|
||||
*/
|
||||
|
||||
const CHUNK = 8 * 1024 * 1024; // read per file per pass; the rest waits for the next
|
||||
|
||||
/**
|
||||
* The complete lines written between `offset` and `size`: `{lines, offset}`.
|
||||
* A chunk with no newline at all (one line over CHUNK) is skipped whole.
|
||||
*/
|
||||
async function readNew(file, offset, size, { chunk = CHUNK } = {}) {
|
||||
const fh = await require("./run-as").openSafeAsync(file);
|
||||
try {
|
||||
const len = Math.min(size - offset, chunk);
|
||||
if (len <= 0) return { lines: [], offset };
|
||||
const buf = Buffer.alloc(len);
|
||||
let got = 0;
|
||||
for (let n; got < len; got += n) {
|
||||
({ bytesRead: n } = await fh.read(buf, got, len - got, offset + got));
|
||||
if (!n) break;
|
||||
}
|
||||
const end = got ? buf.lastIndexOf(0x0a, got - 1) : -1;
|
||||
if (end === -1) return { lines: [], offset: got === chunk ? offset + got : offset };
|
||||
return { lines: buf.toString("utf8", 0, end).split("\n"), offset: offset + end + 1 };
|
||||
} finally {
|
||||
await fh.close();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { readNew };
|
||||
Reference in New Issue
Block a user