@freesyntax/notch-cli 0.5.20 → 0.5.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dist/{apply-patch-D5PDUXUC.js → apply-patch-U6K67CMT.js} +1 -0
  2. package/dist/auth-UAMMP5IJ.js +29 -0
  3. package/dist/chunk-4HPRBCSY.js +167 -0
  4. package/dist/chunk-6NKRMZTX.js +198 -0
  5. package/dist/{chunk-YBYF7L4A.js → chunk-EPSOOCNB.js} +1832 -1331
  6. package/dist/chunk-FZVPGJJW.js +511 -0
  7. package/dist/chunk-GFVLHUSS.js +155 -0
  8. package/dist/chunk-J66N6AFH.js +137 -0
  9. package/dist/chunk-JXQ4HZ47.js +544 -0
  10. package/dist/chunk-KCAR5DOB.js +52 -0
  11. package/dist/chunk-KFQGP6VL.js +33 -0
  12. package/dist/chunk-O6AKZ4OH.js +0 -0
  13. package/dist/{chunk-6M6CXXWR.js → chunk-PKZKVOAN.js} +209 -1
  14. package/dist/{chunk-FIFC4V2R.js → chunk-PPEBWOMJ.js} +91 -7
  15. package/dist/compression-YJLWEHCC.js +33 -0
  16. package/dist/config-set-3IWEVZQ4.js +110 -0
  17. package/dist/{edit-JEFEK43H.js → edit-6QYAXVNU.js} +1 -0
  18. package/dist/{git-5T5TSQTX.js → git-DNQ5EELH.js} +1 -0
  19. package/dist/{github-DWRGWX6U.js → github-34T4QQIH.js} +1 -0
  20. package/dist/{glob-BI3P4C7Q.js → glob-XT43LEJ4.js} +1 -0
  21. package/dist/{grep-VZ3I5GNW.js → grep-T2CXYNRI.js} +1 -0
  22. package/dist/index.js +2606 -960
  23. package/dist/{lsp-UPY6I3L7.js → lsp-JXQVU7NP.js} +1 -0
  24. package/dist/model-download-3NDKS3VM.js +176 -0
  25. package/dist/{notebook-FXJBTSPA.js → notebook-MFODW345.js} +1 -0
  26. package/dist/ollama-bench-5V5CCOCQ.js +194 -0
  27. package/dist/ollama-launch-P5KBK7AJ.js +22 -0
  28. package/dist/ollama-usage-3PROM2WC.js +70 -0
  29. package/dist/{plugins-OG2P75K5.js → plugins-PNGRZLFW.js} +1 -0
  30. package/dist/{read-OVJG2XKW.js → read-B64XE7N3.js} +1 -0
  31. package/dist/{server-W7FRCVRZ.js → server-IGOZHW52.js} +17 -15
  32. package/dist/session-index-7FWEVP6E.js +22 -0
  33. package/dist/{shell-4X545EVN.js → shell-BOZTHQUT.js} +1 -0
  34. package/dist/{task-OS3E5F3X.js → task-67G4KLYC.js} +1 -0
  35. package/dist/{tools-Q7CDHB4K.js → tools-XWKCW4RN.js} +4 -1
  36. package/dist/{web-fetch-KNIV3Z3W.js → web-fetch-OTNDICGJ.js} +1 -0
  37. package/dist/{write-NNHLOTYK.js → write-ZOSB7I4J.js} +1 -0
  38. package/package.json +2 -1
  39. package/dist/auth-JQX6MHJG.js +0 -16
  40. package/dist/compression-UTB2Y4BB.js +0 -16
@@ -5,6 +5,7 @@ import {
5
5
  applyPatchTool,
6
6
  parsePatch
7
7
  } from "./chunk-C4CPDDMN.js";
8
+ import "./chunk-KFQGP6VL.js";
8
9
  export {
9
10
  PatchApplyError,
10
11
  PatchParseError,
@@ -0,0 +1,29 @@
1
+ import {
2
+ clearCredentials,
3
+ getByokSyncPath,
4
+ getConfigDir,
5
+ getCredentialsPath,
6
+ init_auth,
7
+ invalidateSyncedKeysCache,
8
+ loadCredentials,
9
+ loadSyncedByokKeys,
10
+ loadSyncedByokKeysSync,
11
+ login,
12
+ saveCredentials,
13
+ syncByokKeys
14
+ } from "./chunk-PPEBWOMJ.js";
15
+ import "./chunk-KFQGP6VL.js";
16
+ init_auth();
17
+ export {
18
+ clearCredentials,
19
+ getByokSyncPath,
20
+ getConfigDir,
21
+ getCredentialsPath,
22
+ invalidateSyncedKeysCache,
23
+ loadCredentials,
24
+ loadSyncedByokKeys,
25
+ loadSyncedByokKeysSync,
26
+ login,
27
+ saveCredentials,
28
+ syncByokKeys
29
+ };
@@ -0,0 +1,167 @@
1
+ import {
2
+ readIndex,
3
+ readRollout,
4
+ rolloutPath
5
+ } from "./chunk-6NKRMZTX.js";
6
+
7
+ // src/session/session-index.ts
8
+ import fsp from "fs/promises";
9
+ import path from "path";
10
+ import os from "os";
11
+ var INDEX_PATH = path.join(os.homedir(), ".notch", "sessions.index.json");
12
+ var INDEX_SCHEMA = 1;
13
+ async function ensureDir() {
14
+ await fsp.mkdir(path.dirname(INDEX_PATH), { recursive: true });
15
+ }
16
+ async function readIndexFile() {
17
+ try {
18
+ const raw = await fsp.readFile(INDEX_PATH, "utf-8");
19
+ const parsed = JSON.parse(raw);
20
+ if (parsed.schema !== INDEX_SCHEMA) {
21
+ return { schema: INDEX_SCHEMA, updatedAt: Date.now(), entries: {} };
22
+ }
23
+ return parsed;
24
+ } catch {
25
+ return { schema: INDEX_SCHEMA, updatedAt: Date.now(), entries: {} };
26
+ }
27
+ }
28
+ async function writeIndexFile(file) {
29
+ await ensureDir();
30
+ file.updatedAt = Date.now();
31
+ const tmp = INDEX_PATH + ".tmp";
32
+ await fsp.writeFile(tmp, JSON.stringify(file, null, 2));
33
+ await fsp.rename(tmp, INDEX_PATH);
34
+ }
35
+ async function deriveEntryFromRollout(id) {
36
+ let records;
37
+ try {
38
+ records = await readRollout(id);
39
+ } catch {
40
+ return null;
41
+ }
42
+ if (records.length === 0) return null;
43
+ const header = records[0];
44
+ const rolloutIdx = await readIndex(id).catch(() => null);
45
+ let firstUser = "";
46
+ let forkSourceId;
47
+ let forkFromSeq;
48
+ let branches = 0;
49
+ let cwd;
50
+ {
51
+ const headerPayload = header.payload;
52
+ if (headerPayload?.cwd) cwd = headerPayload.cwd;
53
+ if (headerPayload?.forkSourceId) {
54
+ forkSourceId = headerPayload.forkSourceId;
55
+ forkFromSeq = headerPayload.forkFromSeq;
56
+ }
57
+ }
58
+ for (const r of records) {
59
+ if (r.type === "user-message" && !firstUser) {
60
+ const payload = r.payload;
61
+ firstUser = (payload?.content ?? "").slice(0, 160);
62
+ }
63
+ if (r.type === "branch-fork") {
64
+ branches++;
65
+ }
66
+ }
67
+ const lastRecord = records[records.length - 1];
68
+ const lastTurnAt = lastRecord && typeof lastRecord.ts === "number" ? lastRecord.ts : Date.now();
69
+ const createdAtIso = header.payload?.createdAt ?? (/* @__PURE__ */ new Date()).toISOString();
70
+ const createdAt = new Date(createdAtIso).getTime();
71
+ const turnCount = rolloutIdx?.messageCount ?? records.filter((r) => r.type === "user-message" || r.type === "assistant-message").length;
72
+ return {
73
+ id,
74
+ project: header.payload?.project,
75
+ model: header.payload?.model,
76
+ createdAt: Number.isFinite(createdAt) ? createdAt : Date.now(),
77
+ lastTurnAt,
78
+ turnCount,
79
+ preview: firstUser,
80
+ cwd,
81
+ branches,
82
+ forkSourceId,
83
+ forkFromSeq,
84
+ hasActiveStream: !!rolloutIdx?.activeStream
85
+ };
86
+ }
87
+ async function upsertSessionIndexEntry(id, patch) {
88
+ const file = await readIndexFile();
89
+ const derived = await deriveEntryFromRollout(id);
90
+ if (!derived) return;
91
+ file.entries[id] = { ...derived, ...patch ?? {} };
92
+ await writeIndexFile(file);
93
+ }
94
+ async function rebuildIndex() {
95
+ await ensureDir();
96
+ const rolloutDir = path.dirname(rolloutPath("placeholder"));
97
+ let files;
98
+ try {
99
+ files = (await fsp.readdir(rolloutDir)).filter((f) => f.endsWith(".jsonl"));
100
+ } catch {
101
+ files = [];
102
+ }
103
+ const entries = {};
104
+ let skipped = 0;
105
+ for (const f of files) {
106
+ const id = f.replace(/\.jsonl$/, "");
107
+ const entry = await deriveEntryFromRollout(id);
108
+ if (entry) entries[id] = entry;
109
+ else skipped++;
110
+ }
111
+ await writeIndexFile({ schema: INDEX_SCHEMA, updatedAt: Date.now(), entries });
112
+ return { indexed: Object.keys(entries).length, skipped };
113
+ }
114
+ async function querySessions(opts = {}) {
115
+ const file = await readIndexFile();
116
+ const all = Object.values(file.entries);
117
+ const since = opts.since ? typeof opts.since === "number" ? opts.since : new Date(opts.since).getTime() : 0;
118
+ const search = opts.search?.toLowerCase();
119
+ const filtered = all.filter((e) => {
120
+ if (opts.project && e.project !== opts.project) return false;
121
+ if (opts.model && e.model !== opts.model) return false;
122
+ if (opts.cwd && e.cwd !== opts.cwd) return false;
123
+ if (since && e.lastTurnAt < since) return false;
124
+ if (opts.nonEmptyOnly && e.turnCount === 0) return false;
125
+ if (opts.interruptedOnly && !e.hasActiveStream) return false;
126
+ if (search) {
127
+ const hay = `${e.preview ?? ""} ${e.project ?? ""} ${e.model ?? ""} ${e.id}`.toLowerCase();
128
+ if (!hay.includes(search)) return false;
129
+ }
130
+ return true;
131
+ });
132
+ filtered.sort((a, b) => b.lastTurnAt - a.lastTurnAt);
133
+ return opts.limit ? filtered.slice(0, opts.limit) : filtered;
134
+ }
135
+ async function getSession(id) {
136
+ const file = await readIndexFile();
137
+ return file.entries[id] ?? null;
138
+ }
139
+ async function forgetSession(id) {
140
+ const file = await readIndexFile();
141
+ if (id in file.entries) {
142
+ delete file.entries[id];
143
+ await writeIndexFile(file);
144
+ }
145
+ }
146
+ async function tagSession(id, tags) {
147
+ const file = await readIndexFile();
148
+ const existing = file.entries[id];
149
+ if (!existing) return;
150
+ const merged = Array.from(/* @__PURE__ */ new Set([...existing.tags ?? [], ...tags]));
151
+ file.entries[id] = { ...existing, tags: merged };
152
+ await writeIndexFile(file);
153
+ }
154
+ function indexFilePath() {
155
+ return INDEX_PATH;
156
+ }
157
+
158
+ export {
159
+ deriveEntryFromRollout,
160
+ upsertSessionIndexEntry,
161
+ rebuildIndex,
162
+ querySessions,
163
+ getSession,
164
+ forgetSession,
165
+ tagSession,
166
+ indexFilePath
167
+ };
@@ -0,0 +1,198 @@
1
+ // src/session/rollout.ts
2
+ import fsp from "fs/promises";
3
+ import path from "path";
4
+ import os from "os";
5
+ import crypto from "crypto";
6
+ var ROLLOUT_DIR = path.join(os.homedir(), ".notch", "rollouts");
7
+ async function ensureDir() {
8
+ await fsp.mkdir(ROLLOUT_DIR, { recursive: true });
9
+ }
10
+ function rolloutPath(id) {
11
+ return path.join(ROLLOUT_DIR, `${id}.jsonl`);
12
+ }
13
+ function indexPath(id) {
14
+ return path.join(ROLLOUT_DIR, `${id}.idx.json`);
15
+ }
16
+ function generateSessionId() {
17
+ const d = /* @__PURE__ */ new Date();
18
+ const stamp = d.toISOString().slice(0, 10).replace(/-/g, "") + "-" + d.toISOString().slice(11, 16).replace(":", "");
19
+ const rand = crypto.randomBytes(3).toString("hex");
20
+ return `${stamp}-${rand}`;
21
+ }
22
+ var Rollout = class {
23
+ constructor(id) {
24
+ this.id = id;
25
+ }
26
+ id;
27
+ fd = null;
28
+ seq = 0;
29
+ idx = {
30
+ lastSeq: -1,
31
+ messageCount: 0,
32
+ branches: {},
33
+ activeStream: null
34
+ };
35
+ async openNew(header) {
36
+ await ensureDir();
37
+ this.fd = await fsp.open(rolloutPath(this.id), "a");
38
+ await this.writeRecord({
39
+ type: "header",
40
+ payload: { id: this.id, project: header.project, model: header.model, createdAt: (/* @__PURE__ */ new Date()).toISOString(), schema: 1 }
41
+ });
42
+ }
43
+ async openExisting() {
44
+ await ensureDir();
45
+ this.idx = await readIndex(this.id);
46
+ this.seq = this.idx.lastSeq + 1;
47
+ this.fd = await fsp.open(rolloutPath(this.id), "a");
48
+ }
49
+ async close() {
50
+ await this.saveIndex();
51
+ if (this.fd) {
52
+ await this.fd.close();
53
+ this.fd = null;
54
+ }
55
+ try {
56
+ const { upsertSessionIndexEntry } = await import("./session-index-7FWEVP6E.js");
57
+ await upsertSessionIndexEntry(this.id);
58
+ } catch {
59
+ }
60
+ }
61
+ async writeRecord(partial) {
62
+ if (!this.fd) throw new Error("rollout not open");
63
+ const rec = { seq: this.seq++, ts: Date.now(), ...partial };
64
+ const line = JSON.stringify(rec) + "\n";
65
+ await this.fd.write(line);
66
+ this.idx.lastSeq = rec.seq;
67
+ if (rec.type === "user-message" || rec.type === "assistant-message") {
68
+ this.idx.messageCount++;
69
+ if (rec.parent && rec.msgId) {
70
+ (this.idx.branches[rec.parent] ??= []).push(rec.msgId);
71
+ }
72
+ }
73
+ if (rec.type === "active-stream") {
74
+ this.idx.activeStream = rec.streamId ?? null;
75
+ } else if (rec.type === "turn-end" || rec.type === "error") {
76
+ this.idx.activeStream = null;
77
+ }
78
+ return rec;
79
+ }
80
+ append(record) {
81
+ return this.writeRecord(record);
82
+ }
83
+ async flush() {
84
+ if (this.fd) await this.fd.sync();
85
+ await this.saveIndex();
86
+ }
87
+ async saveIndex() {
88
+ await fsp.writeFile(indexPath(this.id), JSON.stringify(this.idx, null, 2));
89
+ }
90
+ get activeStream() {
91
+ return this.idx.activeStream;
92
+ }
93
+ get index() {
94
+ return this.idx;
95
+ }
96
+ };
97
+ async function readRollout(id) {
98
+ const raw = await fsp.readFile(rolloutPath(id), "utf-8");
99
+ const out = [];
100
+ for (const line of raw.split("\n")) {
101
+ if (!line.trim()) continue;
102
+ try {
103
+ out.push(JSON.parse(line));
104
+ } catch {
105
+ }
106
+ }
107
+ return out;
108
+ }
109
+ async function readIndex(id) {
110
+ try {
111
+ const raw = await fsp.readFile(indexPath(id), "utf-8");
112
+ return JSON.parse(raw);
113
+ } catch {
114
+ const records = await readRollout(id);
115
+ const idx = { lastSeq: -1, messageCount: 0, branches: {}, activeStream: null };
116
+ for (const r of records) {
117
+ idx.lastSeq = r.seq;
118
+ if (r.type === "user-message" || r.type === "assistant-message") {
119
+ idx.messageCount++;
120
+ if (r.parent && r.msgId) (idx.branches[r.parent] ??= []).push(r.msgId);
121
+ }
122
+ if (r.type === "active-stream") idx.activeStream = r.streamId ?? null;
123
+ else if (r.type === "turn-end" || r.type === "error") idx.activeStream = null;
124
+ }
125
+ await fsp.writeFile(indexPath(id), JSON.stringify(idx, null, 2)).catch(() => {
126
+ });
127
+ return idx;
128
+ }
129
+ }
130
+ async function listRollouts() {
131
+ try {
132
+ const entries = await fsp.readdir(ROLLOUT_DIR);
133
+ const files = entries.filter((e) => e.endsWith(".jsonl"));
134
+ const out = [];
135
+ for (const f of files) {
136
+ const id = f.replace(/\.jsonl$/, "");
137
+ const stat = await fsp.stat(path.join(ROLLOUT_DIR, f));
138
+ const idx = await readIndex(id).catch(() => ({ messageCount: 0 }));
139
+ let project;
140
+ let model;
141
+ try {
142
+ const first = (await fsp.readFile(path.join(ROLLOUT_DIR, f), "utf-8")).split("\n", 1)[0];
143
+ if (first) {
144
+ const header = JSON.parse(first);
145
+ project = header.payload?.project;
146
+ model = header.payload?.model;
147
+ }
148
+ } catch {
149
+ }
150
+ out.push({ id, updated: stat.mtimeMs, messageCount: idx.messageCount, project, model });
151
+ }
152
+ return out.sort((a, b) => b.updated - a.updated);
153
+ } catch {
154
+ return [];
155
+ }
156
+ }
157
+ function rebuildMessagesFromRollout(records) {
158
+ const msgs = [];
159
+ let current = null;
160
+ for (const r of records) {
161
+ if (r.type === "user-message") {
162
+ if (current) {
163
+ msgs.push(current);
164
+ current = null;
165
+ }
166
+ msgs.push({ role: "user", content: r.payload?.content ?? "" });
167
+ } else if (r.type === "text-delta") {
168
+ const delta = r.payload?.content ?? "";
169
+ if (!current) current = { role: "assistant", content: "" };
170
+ current.content += delta;
171
+ } else if (r.type === "assistant-message") {
172
+ if (current) {
173
+ msgs.push(current);
174
+ current = null;
175
+ }
176
+ msgs.push({ role: "assistant", content: r.payload?.content ?? "" });
177
+ } else if (r.type === "turn-end" && current) {
178
+ msgs.push(current);
179
+ current = null;
180
+ }
181
+ }
182
+ if (current) msgs.push(current);
183
+ return msgs;
184
+ }
185
+ function hasActiveStream(idx) {
186
+ return !!idx.activeStream;
187
+ }
188
+
189
+ export {
190
+ rolloutPath,
191
+ generateSessionId,
192
+ Rollout,
193
+ readRollout,
194
+ readIndex,
195
+ listRollouts,
196
+ rebuildMessagesFromRollout,
197
+ hasActiveStream
198
+ };