gitoriaLog in with ident

gitoria

All repositories: gitoria

ReadmeCodePull requestsReleasesTicketsSettings
Commit3dc431083dc43108antcolony#40: mission references point to the moved missionsmre3dc43108/docs/differ-from-custom-ide.md

6.4 KB

  1. # Differ from custom-ide — reuse assessment
  2. Research for ticket [gitoria.worldapi.org#2](https://tickets.worldapi.org/projects/gitoria.worldapi.org/2).
  3. Source inspected: `loreana:/media/STORAGE/projects/custom-ide` (renderer, vanilla JS + vendored
  4. CodeJar, no framework), specifically `renderer/src/features/{editor,diff-review,hybriel}` and
  5. `docs/editor-split-and-diff.md` (the design log for the diff feature, approved 2026-07-30).
  6. ## What the "differ" actually is
  7. Not one file — five pieces, ~3,400 LOC total, built up over several phases (see the design log):
  8. | Piece | File | LOC | DOM? |
  9. |---|---|---|---|
  10. | Diff algorithm | `editor/lineDiff.js` | 249 | **No** — pure, aligns two texts into rows (patience-diff anchors + LCS fallback, `MAX_LCS_CELLS` guard) |
  11. | Live gutter bars | `editor/editorChangeBars.js` | 75 | No — reuses `lineDiff` |
  12. | Diff widget shell | `diff-review/DiffReviewWidget.js` | 302 | Yes — two `EditorSurface`s side by side |
  13. | Editor surface (gutter, spacers, highlight, scroll) | `editor/EditorSurface.js` | 614 | Yes, heavily |
  14. | Canvas minimap | `editor/EditorMinimap.js` | 628 | Yes (canvas) |
  15. | Syntax highlighters (per language, regex-based) | `editor/editorHighlighter.js` | 1,027 | No |
  16. | Vendored editing library | `vendor/codejar.js` (npm `[email protected]`, MIT) | 499 | Yes |
  17. `EditorWidget.js` itself (2,770 LOC) is mostly file/LSP/dirty-tracking plumbing the differ doesn't
  18. need — excluded above.
  19. ## Reusability, piece by piece
  20. **`lineDiff.js` — yes, directly.** Zero DOM dependency (the code comments say so explicitly: kept
  21. separate *because* importing it into the widget would have dragged in CodeJar, which needs a
  22. `window`). It has its own Node smoke test. This is the actual "differ" and is the easiest, highest-value
  23. piece to make a shared component: a worldapi-wide `differ` module, callable from any project
  24. (gitoria diffs, but also e.g. a future review UI), with no browser coupling at all.
  25. **`editorHighlighter.js` — yes, and partly done already.** custom-ide already ships a **Hybriel
  26. syntax highlighter** at `renderer/src/features/hybriel/highlight.js` (regex tokenizer over
  27. Hybriel's keyword/type/operator set, ~70 LOC, no dependencies) — written for its own use, but
  28. directly reusable verbatim for `.hl` files in gitoria's diff/editor views.
  29. **CodeJar + `EditorSurface` + `EditorMinimap` — a large piece (not "easily rewritable") — to be ported natively.**
  30. This is where the ticket's premise ("codejar is quite simple and probably easily rewritable in
  31. hybriel") undersells the actual scope. CodeJar itself is small (499 LOC, MIT, plain
  32. `contenteditable` + `Range` API) and easy to read. But the feature built on top of it is not simple:
  33. the design log documents real trial-and-error to get there —
  34. - diff alignment uses `contenteditable="false"` DOM "spacer" elements inserted via `Range` (not
  35. blank text lines), so the editable side's `getCode()` stays byte-identical to the real file;
  36. - spacers must be re-inserted after **every** re-highlight because CodeJar rewrites `innerHTML`
  37. each time, or the two sides drift a line apart;
  38. - line-highlight bands are positioned from `getComputedStyle` line-height, deferred via
  39. `ResizeObserver` because a detached element reports no real metrics;
  40. - the minimap is a hand-rolled canvas renderer with its own tokenizer-output reuse, viewport slider,
  41. and marker ruler.
  42. None of that complexity is intrinsic to codejar — it's what "diff editor with a minimap, gutter,
  43. and an editable proposal side" costs regardless of implementation language.
  44. ## Would a native Hybriel rewrite work today?
  45. Judged against the open Hybriel tickets already known to this project (see the worker brief's list),
  46. several are direct blockers for exactly this feature, not incidental:
  47. - **hybriel#32** (`hl:webex` re-creates elements, incl. `script src`, when an `if` in the same View
  48. flips) — the diff widget's "changed only" toggle and the read-only/editable swap are precisely
  49. this pattern: conditional re-render of a live editing surface, which would blow away CodeJar's
  50. DOM/caret state on every toggle if View re-creates the node.
  51. - **hybriel#33** (no conditional boolean attributes) — `contenteditable`/`aria-readonly` are
  52. boolean-attribute toggles core to `EditorSurface.setReadOnly()`.
  53. - **hybriel#31** (no custom DOM event binding) — CodeJar communicates through its own `onUpdate`
  54. callback and native `input`/`keydown` handling, not a framework event system; a native port needs
  55. a way to hand webex an escape hatch into the raw DOM.
  56. - **hybriel#17** (`if (!member)` renders nothing) and **hybriel#9** (manifest statics unreadable in
  57. their own function routes) are the kind of "silent wrong render" bugs that are expensive to debug
  58. inside something this DOM-fiddly.
  59. None of these make a Hybriel differ *impossible* — but they make a **from-scratch native rewrite of
  60. the editing surface** premature until webex's conditional-rendering and DOM-event story is solid.
  61. The diff *algorithm* has no such dependency and is unaffected.
  62. ## Recommendation (final, after gitoria#4)
  63. The creator rejected the JS-asset route: no foreign bundle is embedded. The plan is native Hybriel only:
  64. 1. **Differ algorithm first** — port `lineDiff.js` (pure, 249 LOC, no DOM) as a native Hybriel module in
  65. layouts.worldapi.org (shared components live there, gitoria#3). Unblocked; needs a ticket in that project.
  66. 2. **Editing surface** — build natively (spacers, re-highlight, contenteditable toggling, custom DOM
  67. events). Blocked on hybriel#31/#32/#33/#17 (and #41); fix or work around those in Hybriel itself.
  68. The custom-ide code stays a reference for the behaviours to reproduce.
  69. (An earlier "tier 1: ship the existing JS as a client asset" recommendation was removed; it is rejected.)
  70. ## Questions
  71. - ~~Where should the `differ` module live?~~ Decided by the creator (gitoria#3): shared components
  72. (editor, differ, comments, design tokens) live in **layouts.worldapi.org**, not in gitoria and not
  73. in a separate project.
  74. - ~~Embed custom-ide's CodeJar bundle as a static JS asset for now?~~ **Rejected by the creator
  75. (gitoria#4):** the original ticket (#2) already answered it — editor and differ are to be built as
  76. reusable **native Hybriel components** in layouts.worldapi.org, not embedded as a foreign JS bundle.
  77. Do not build the JS-asset route.
  78. Remaining work is the native port (differ algorithm first — unblocked; editing surface — see the
  79. open Hybriel tickets #31/#32/#33/#17 above, which must be fixed or worked around in Hybriel itself).

Branches

Latest commits

  • 3dc43108antcolony#40: mission references point to the moved missionsmre
  • 8d9450fdantcolony#40: history (LOG.md), worker briefs (missions/) and reports moved here from antcolony, numbered per project; old numbers in antcolony docs/mission-map.mdmre
  • 205d5fe4gitoria: Hybriel master ff51cf46; ssh keys/tokens no double rows (session sync); gates follow #20mre
  • 9b27cb26gitoria#21: installable app (manifest, service worker, offline start page), own iconmre
  • 68dcb603deploy.sh: back up live storage/.sessions/.env before every deploy (newest 5 kept)mre
  • e2deed6dgitoria#20: "Add code" only on the Code page of an empty repository, no collapsiblemre
  • 8bb97ffddeploy.sh: never send .git or .gitignore to Byrodinmre
  • fd981932State of 2026-09-27; bin/ no longer tracked (Hybriel commit is in README)mre
  • 4a2d7125initial commitmre