isorite 0.11.0 → 0.12.0

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 (57) hide show
  1. package/README.md +2 -5
  2. package/dist/core.js +91 -7
  3. package/dist/main.js +163 -179
  4. package/docs/setup-for-agents.md +11 -36
  5. package/docs/setup.md +20 -61
  6. package/docs/terminal.md +28 -80
  7. package/package.json +1 -1
  8. package/web/_app/immutable/assets/0.BXPxx6Q0.css +1 -0
  9. package/web/_app/immutable/assets/{5.DbDKXCoO.css → 5.rBvyRuST.css} +1 -1
  10. package/web/_app/immutable/assets/{7.ljiu9bn5.css → 7.C00vyVPo.css} +1 -1
  11. package/web/_app/immutable/assets/Drawing.Q7J9MyIo.css +1 -0
  12. package/web/_app/immutable/assets/{NoteList.F579Zvj_.css → NoteList.E6jC-AtZ.css} +1 -1
  13. package/web/_app/immutable/assets/Timeline.LsRXYIBv.css +1 -0
  14. package/web/_app/immutable/assets/ground.hxi5N5fC.css +1 -0
  15. package/web/_app/immutable/chunks/{DGmSCGD3.js → 4kgFUGOH.js} +1 -1
  16. package/web/_app/immutable/chunks/8SS1q0nk.js +7 -0
  17. package/web/_app/immutable/chunks/{CfL6O_ia.js → BK6pLgdi.js} +1 -1
  18. package/web/_app/immutable/chunks/{DuLysVkb.js → Bk_JinGf.js} +1 -1
  19. package/web/_app/immutable/chunks/CFEI5lV9.js +1 -0
  20. package/web/_app/immutable/chunks/{BgT6ZdzK.js → CiMp12cC.js} +1 -1
  21. package/web/_app/immutable/chunks/{mLFVM17H.js → D4YEq54N.js} +1 -1
  22. package/web/_app/immutable/chunks/{CMeq8te_.js → DDCg82xL.js} +1 -1
  23. package/web/_app/immutable/chunks/DThNJvmp.js +1 -0
  24. package/web/_app/immutable/chunks/{DNjLZcwq.js → D_jbSWJl.js} +1 -1
  25. package/web/_app/immutable/chunks/DbeMVOH4.js +1 -0
  26. package/web/_app/immutable/chunks/{CODXTnUW.js → DsQj0LyB.js} +4 -4
  27. package/web/_app/immutable/chunks/{DktGnzDy.js → Uo6irDQW.js} +80 -79
  28. package/web/_app/immutable/chunks/{DaulBP5z.js → jTXVas70.js} +1 -1
  29. package/web/_app/immutable/entry/app.CvK8zypr.js +2 -0
  30. package/web/_app/immutable/entry/start.Dcgm6sQd.js +1 -0
  31. package/web/_app/immutable/nodes/0.0TdRBEoR.js +26 -0
  32. package/web/_app/immutable/nodes/{1.C-RxYNx3.js → 1.Dchqgt4j.js} +1 -1
  33. package/web/_app/immutable/nodes/2.C0CMUdSu.js +1 -0
  34. package/web/_app/immutable/nodes/3.MjtWDMWd.js +1 -0
  35. package/web/_app/immutable/nodes/4.hhS0SQta.js +2 -0
  36. package/web/_app/immutable/nodes/5.C33_cw2J.js +9 -0
  37. package/web/_app/immutable/nodes/6.owNfwwRl.js +1 -0
  38. package/web/_app/immutable/nodes/7.BpxHVHoY.js +1 -0
  39. package/web/_app/version.json +1 -1
  40. package/web/index.html +20 -19
  41. package/web/_app/immutable/assets/0.DcsDj0O1.css +0 -1
  42. package/web/_app/immutable/assets/Timeline.KTc3LKuK.css +0 -1
  43. package/web/_app/immutable/assets/drawn.CHbcoujQ.css +0 -1
  44. package/web/_app/immutable/chunks/BYSDTLqw.js +0 -1
  45. package/web/_app/immutable/chunks/DDVefAkE.js +0 -7
  46. package/web/_app/immutable/chunks/Db_gdTNI.js +0 -1
  47. package/web/_app/immutable/chunks/F7HCRtmu.js +0 -1
  48. package/web/_app/immutable/chunks/wxBqjpRy.js +0 -1
  49. package/web/_app/immutable/entry/app.wp4GfiBT.js +0 -2
  50. package/web/_app/immutable/entry/start.PPXyd7_0.js +0 -1
  51. package/web/_app/immutable/nodes/0.JerS9yOA.js +0 -26
  52. package/web/_app/immutable/nodes/2.Bbkruoyi.js +0 -1
  53. package/web/_app/immutable/nodes/3.BkpGKa9k.js +0 -1
  54. package/web/_app/immutable/nodes/4.Bj25nsxG.js +0 -2
  55. package/web/_app/immutable/nodes/5.D9sfzyBX.js +0 -9
  56. package/web/_app/immutable/nodes/6.Di1re0aR.js +0 -1
  57. package/web/_app/immutable/nodes/7.MWEn-qPC.js +0 -1
package/README.md CHANGED
@@ -9,8 +9,7 @@ npm install -g isorite
9
9
  isorite guide # the guide: a knowledge base about isorite, with things to do, in ~/isorite-guide
10
10
  ```
11
11
 
12
- On your own notes, a folder of Markdown files (`isorite new <notes>` starts one). They're drawn as you write them:
13
- maths, code coloured by its language, and Mermaid diagrams.
12
+ On your own notes, a folder of Markdown files (`isorite new <notes>` starts one). They're drawn as you write them: maths, code coloured by its language, and Mermaid diagrams.
14
13
 
15
14
  ```sh
16
15
  isorite serve <notes> # the browser, at http://localhost:4767/; set up Iso's provider in Iso's settings
@@ -19,9 +18,7 @@ isorite model # optional: search by meaning (fetches a 53 MB model
19
18
  isorite memory # optional: the agent's memory, a base of its own lent to every session
20
19
  ```
21
20
 
22
- Setting it up, at work too (a company's gateway, a client certificate, a proxy): `docs/setup.md` in this package.
23
- When something fails, `isorite doctor` says what to change; `isorite doctor --report` gives it as one block, its
24
- secrets hidden, to paste to someone helping. For an AI helping you: `isorite help setup`.
21
+ Setting it up, at work too (a company's gateway, a client certificate, a proxy): `docs/setup.md` in this package. When something fails, `isorite doctor` says what to change; `isorite doctor --report` gives it as one block, its secrets hidden, to paste to someone helping. For an AI helping you: `isorite help setup`.
25
22
 
26
23
  The guide in a browser alone: https://lachlanjs.github.io/isorite/
27
24
 
package/dist/core.js CHANGED
@@ -1201,6 +1201,76 @@ function spliceText(before, changes, body) {
1201
1201
  return bom + head + newBody;
1202
1202
  }
1203
1203
  //#endregion
1204
+ //#region packages/core/src/unwrap.ts
1205
+ const ITEM = /^\s*([-*+]|\d+[.)])\s+/;
1206
+ const APART = /^\s*(#{1,6}\s|\||<|```|~~~|\$\$|>|---\s*$|\*\*\*\s*$|___\s*$|\[[^\]]+\]:\s)/;
1207
+ const QUOTED = /^\s*>\s?\S/;
1208
+ function unwrap(text) {
1209
+ const lines = text.split("\n"), out = [];
1210
+ let i = 0, fence = "", maths = false;
1211
+ /** What the last line written may be continued by: prose, a quoted line, or nothing. */
1212
+ let open = "";
1213
+ if (lines[0] === "---") {
1214
+ const end = lines.indexOf("---", 1);
1215
+ if (end > 0) {
1216
+ out.push(...lines.slice(0, end + 1));
1217
+ i = end + 1;
1218
+ }
1219
+ }
1220
+ for (; i < lines.length; i++) {
1221
+ const l = lines[i], t = l.trim();
1222
+ if (fence) {
1223
+ out.push(l);
1224
+ if (t.startsWith(fence)) fence = "";
1225
+ continue;
1226
+ }
1227
+ if (maths) {
1228
+ out.push(l);
1229
+ if (t.endsWith("$$")) maths = false;
1230
+ continue;
1231
+ }
1232
+ if (t.startsWith("```") || t.startsWith("~~~")) {
1233
+ fence = t.slice(0, 3);
1234
+ out.push(l);
1235
+ open = "";
1236
+ continue;
1237
+ }
1238
+ if (t.startsWith("$$") && !t.slice(2).includes("$$")) {
1239
+ maths = true;
1240
+ out.push(l);
1241
+ open = "";
1242
+ continue;
1243
+ }
1244
+ if (!t) {
1245
+ out.push(l);
1246
+ open = "";
1247
+ continue;
1248
+ }
1249
+ const hard = /( {2}|\\)$/.test(out.at(-1) ?? "");
1250
+ if (APART.test(l)) {
1251
+ if (open === "quote" && QUOTED.test(l) && !/^\s*>\s*([-*+]|\d+[.)]|#)/.test(l) && !hard) {
1252
+ out[out.length - 1] += " " + l.replace(/^\s*>\s?/, "").trim();
1253
+ continue;
1254
+ }
1255
+ out.push(l);
1256
+ open = QUOTED.test(l) ? "quote" : "";
1257
+ continue;
1258
+ }
1259
+ if (ITEM.test(l)) {
1260
+ out.push(l);
1261
+ open = "prose";
1262
+ continue;
1263
+ }
1264
+ if (open === "prose" && !hard) {
1265
+ out[out.length - 1] += " " + t;
1266
+ continue;
1267
+ }
1268
+ out.push(l);
1269
+ open = open === "" && /^( {4}|\t)/.test(l) ? "" : "prose";
1270
+ }
1271
+ return out.join("\n");
1272
+ }
1273
+ //#endregion
1204
1274
  //#region packages/core/src/search.ts
1205
1275
  const TOKEN = /[a-z0-9]+(?:['’][a-z]+)?/g;
1206
1276
  const STOP = new Set("a an and are as at be by for from has have in is it its of on or that the this to was were will with not but if then than so do does did can could should would into about".split(" "));
@@ -1647,6 +1717,8 @@ const KINDS$1 = [
1647
1717
  ];
1648
1718
  const SNAPSHOT_EVERY = 40;
1649
1719
  const SESSION_GAP_MS = 18e5;
1720
+ /** Your edits in a row are one moment, one layer of a note's history (M24, T), until 10 minutes pass with none. */
1721
+ const LAYER_IDLE_MS = 6e5;
1650
1722
  const hashText = (text) => sha256(text).slice(0, 16);
1651
1723
  /** A stamp for a new entry. `last` is the newest entry anywhere in the study base, which decides the session. */
1652
1724
  function stamp(who, device, last, now = Date.now()) {
@@ -1999,16 +2071,21 @@ function insertAt(note, line) {
1999
2071
  before: prev + 1 < all.length ? anchorOf(all, prev + 1) : null
2000
2072
  };
2001
2073
  }
2002
- /** The journal as the timeline shows it. Your own edits in a row within a session are one moment; a proposal is
2003
- * one moment whose `what` says how it ended. Revisions are not moments. */
2074
+ /** The journal as the timeline shows it. Your own edits in a row within a session are one moment, until ten minutes
2075
+ * pass with none (LAYER_IDLE_MS); a proposal is one moment whose `what` says how it ended. Revisions are not
2076
+ * moments. */
2004
2077
  function moments(entries) {
2005
2078
  const out = [], offered = /* @__PURE__ */ new Map(), asked = /* @__PURE__ */ new Map();
2079
+ /** Lines a change put in and took out: a note's first entry, all of its text. */
2080
+ const size = (c) => c.why === "start" || !c.hunks.length && c.before === null ? [(c.text ?? "").split("\n").length, 0] : [c.hunks.reduce((n, h) => n + h.ins.length, 0), c.hunks.reduce((n, h) => n + h.del.length, 0)];
2006
2081
  for (const e of entries) {
2007
2082
  const base = {
2008
2083
  ids: [e.id],
2009
2084
  at: e.at,
2010
2085
  session: e.session,
2011
- who: e.who
2086
+ who: e.who,
2087
+ added: 0,
2088
+ removed: 0
2012
2089
  };
2013
2090
  if (e.kind === "proposal") {
2014
2091
  const m = {
@@ -2027,22 +2104,29 @@ function moments(entries) {
2027
2104
  }
2028
2105
  } else if (e.kind === "change") {
2029
2106
  const m = e.proposal ? offered.get(e.proposal) : void 0;
2107
+ const [added, removed] = size(e);
2030
2108
  if (e.why === "keep" && m) {
2031
2109
  m.what = "kept";
2032
2110
  m.ids.push(e.id);
2033
2111
  m.at = e.at;
2112
+ m.added += added;
2113
+ m.removed += removed;
2034
2114
  continue;
2035
2115
  }
2036
2116
  const last = out[out.length - 1];
2037
- if (e.why === "edit" && last && last.what === "edited" && last.who === e.who && last.session === e.session) {
2117
+ if (e.why === "edit" && last && last.what === "edited" && last.who === e.who && last.session === e.session && Date.parse(e.at) - Date.parse(last.at) <= 6e5) {
2038
2118
  last.ids.push(e.id);
2039
2119
  last.at = e.at;
2120
+ last.added += added;
2121
+ last.removed += removed;
2040
2122
  continue;
2041
2123
  }
2042
2124
  const what = e.why === "start" ? e.who === "external" ? "found" : "wrote" : e.why === "edit" ? "edited" : e.why === "restore" ? "restored" : e.why === "keep" ? "kept" : e.why === "move" ? "moved" : "changed elsewhere";
2043
2125
  out.push({
2044
2126
  ...base,
2045
2127
  what,
2128
+ added,
2129
+ removed,
2046
2130
  ...e.asked ? { asked: e.asked } : {}
2047
2131
  });
2048
2132
  }
@@ -2137,8 +2221,8 @@ function checkId(id) {
2137
2221
  if (!SAFE.test(id) || id.startsWith("/") || id.split("/").some((part) => part === ".." || part === "." || !part)) throw new Error(`not a note's id: ${JSON.stringify(id)}`);
2138
2222
  return id;
2139
2223
  }
2140
- /** Where a note's journal is. Drafts and Understanding notes are journalled under their `@draft/` and
2141
- * `@understanding/` ids. */
2224
+ /** Where a note's journal is. Drafts are journalled under their `@draft/` ids (and Understanding notes were, before
2225
+ * M24, under `@understanding/`). */
2142
2226
  const journalPath = (noteId) => `journal/${checkId(noteId)}.jsonl`;
2143
2227
  /** This device's record of usage: what was cleared from Iso's context, and what each turn cost (record.ts). */
2144
2228
  const recordPath = (device) => `record/${checkId(device)}.jsonl`;
@@ -2377,4 +2461,4 @@ function ago(at, now = Date.now()) {
2377
2461
  /** A moment is named by its last entry: the one the note is shown at. */
2378
2462
  const momentKey = (m) => m.ids.at(-1);
2379
2463
  //#endregion
2380
- export { ABOUT, AGENTS_FILE, Bundle, CONFIG_FILE, Concept, DEVICE_RE, DONE, DiffError, Directory, FrontmatterError, GITATTRIBUTES, ID_RE, KINDS, LearnerError, MAX_EVENT_BYTES, OKF_VERSION, OWN_DIR, OWN_FORMAT, RATINGS, SESSION_GAP_MS, SETTINGS_FILE, SNAPSHOT_EVERY, STRENGTH, STUDY_DIR, STUDY_FORMAT, SearchIndex, StudyError, agentName, ago, anchorOf, applyHunks, authors, blocks, change, citeKind, cleanEvent, cmp, cmpTuple, codeTarget, contentHash, describe, diffLines, doneOf, dumpFrontmatter, editFrontmatter, embedFor, embedRefs, fileType, findAnchor, findPassage, floatRepr, frontmatterText, hashText, headings, idsOf, impliedLinks, insertAt, isFileRef, iso, journalLine, journalPath, kindOf, legacyId, linkRefs, linkTexts, locate, mapModel, mergeRecords, momentKey, moments, newId, noteIds, outwardLinks, pagerank, parseSettings, parseStudyConfig, parseYaml, passageOf, pending, pictureSize, pictureType, pyRepr, rating, reach, readJournal, readRecord, reconcile, recordPath, replay, round3, section, sessionMoments, settingsText, sha256, slugify, snippet, spliceText, splitFrontmatter, splitSource, stamp, strengthEdges, strip, stronglyConnected, text, textAt, toTime, tokenize, touched, wordAuthors, written };
2464
+ export { ABOUT, AGENTS_FILE, Bundle, CONFIG_FILE, Concept, DEVICE_RE, DONE, DiffError, Directory, FrontmatterError, GITATTRIBUTES, ID_RE, KINDS, LAYER_IDLE_MS, LearnerError, MAX_EVENT_BYTES, OKF_VERSION, OWN_DIR, OWN_FORMAT, RATINGS, SESSION_GAP_MS, SETTINGS_FILE, SNAPSHOT_EVERY, STRENGTH, STUDY_DIR, STUDY_FORMAT, SearchIndex, StudyError, agentName, ago, anchorOf, applyHunks, authors, blocks, change, citeKind, cleanEvent, cmp, cmpTuple, codeTarget, contentHash, describe, diffLines, doneOf, dumpFrontmatter, editFrontmatter, embedFor, embedRefs, fileType, findAnchor, findPassage, floatRepr, frontmatterText, hashText, headings, idsOf, impliedLinks, insertAt, isFileRef, iso, journalLine, journalPath, kindOf, legacyId, linkRefs, linkTexts, locate, mapModel, mergeRecords, momentKey, moments, newId, noteIds, outwardLinks, pagerank, parseSettings, parseStudyConfig, parseYaml, passageOf, pending, pictureSize, pictureType, pyRepr, rating, reach, readJournal, readRecord, reconcile, recordPath, replay, round3, section, sessionMoments, settingsText, sha256, slugify, snippet, spliceText, splitFrontmatter, splitSource, stamp, strengthEdges, strip, stronglyConnected, text, textAt, toTime, tokenize, touched, unwrap, wordAuthors, written };