@filipc77/cowrite 0.6.10 → 0.6.12

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.
@@ -1104,7 +1104,7 @@ function createPreviewServer(store, projectDir, port, initialFile) {
1104
1104
  // bin/cowrite.ts
1105
1105
  import updateNotifier from "update-notifier";
1106
1106
  import "module";
1107
- var version = true ? "0.6.10" : createRequire(import.meta.url)("../package.json").version;
1107
+ var version = true ? "0.6.12" : createRequire(import.meta.url)("../package.json").version;
1108
1108
  var USAGE = `
1109
1109
  cowrite \u2014 Live commenting plugin for coding agent sessions
1110
1110
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@filipc77/cowrite",
3
- "version": "0.6.10",
3
+ "version": "0.6.12",
4
4
  "description": "Live commenting and inline editing plugin for coding agent sessions",
5
5
  "type": "module",
6
6
  "bin": {
package/ui/index.html CHANGED
@@ -91,7 +91,8 @@
91
91
  <button data-format="bold" title="Bold (Cmd+B)"><strong>B</strong></button>
92
92
  <button data-format="italic" title="Italic (Cmd+I)"><em>I</em></button>
93
93
  <button data-format="strikethrough" title="Strikethrough (Cmd+Shift+S)"><s>S</s></button>
94
- <button data-format="code" title="Code (Cmd+E)"><code>&lt;/&gt;</code></button>
94
+ <button data-format="code" title="Inline code (Cmd+E)"><code>&lt;/&gt;</code></button>
95
+ <button data-format="codeBlock" title="Code block"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2"/><polyline points="8 8 6 10 8 12"/><polyline points="16 8 18 10 16 12"/><line x1="11" y1="7" x2="13" y2="13"/></svg></button>
95
96
  <button data-format="link" title="Link (Cmd+K)"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></button>
96
97
  <button data-format="blockquote" title="Quote"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 21c3 0 7-1 7-8V5c0-1.25-.756-2.017-2-2H4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2 1 0 1 0 1 1v1c0 1-1 2-2 2s-1 .008-1 1.031V21"/><path d="M15 21c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2h-4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2h.75c0 2.25.25 4-2.75 4v3"/></svg></button>
97
98
  <button data-format="bulletList" title="Bullet list"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="8" y1="6" x2="21" y2="6"/><line x1="8" y1="12" x2="21" y2="12"/><line x1="8" y1="18" x2="21" y2="18"/><line x1="3" y1="6" x2="3.01" y2="6"/><line x1="3" y1="12" x2="3.01" y2="12"/><line x1="3" y1="18" x2="3.01" y2="18"/></svg></button>
@@ -234,14 +234,33 @@ function wrapRange(textNodes, start, end, comment) {
234
234
 
235
235
  /**
236
236
  * Initialize comment highlight click behavior.
237
+ * Clicking a highlight scrolls to & highlights the matching sidebar card.
237
238
  */
238
239
  export function initCommentHighlights() {
239
240
  const commentListEl = $('#commentList');
241
+
240
242
  document.addEventListener('mousedown', (e) => {
241
- if (!e.target.closest('.comment-highlight')) {
243
+ const highlight = e.target.closest('.comment-highlight');
244
+
245
+ // Clear active state when clicking outside highlights
246
+ if (!highlight) {
242
247
  for (const card of commentListEl.querySelectorAll('.comment-card.active')) {
243
248
  card.classList.remove('active');
244
249
  }
250
+ return;
251
+ }
252
+
253
+ // Scroll sidebar to the matching comment card
254
+ const commentId = highlight.dataset?.commentId;
255
+ if (!commentId) return;
256
+ const card = commentListEl.querySelector(`.comment-card[data-id="${commentId}"]`);
257
+ if (!card) return;
258
+
259
+ // Clear previous active states
260
+ for (const c of commentListEl.querySelectorAll('.comment-card.active')) {
261
+ c.classList.remove('active');
245
262
  }
263
+ card.classList.add('active');
264
+ card.scrollIntoView({ behavior: 'smooth', block: 'center' });
246
265
  });
247
266
  }
@@ -124,10 +124,18 @@ export function renderComments() {
124
124
  `;
125
125
  }).join("");
126
126
 
127
- // Click to scroll to highlight
127
+ // Click to scroll to highlight and mark card active
128
128
  for (const card of commentListEl.querySelectorAll(".comment-card")) {
129
129
  card.addEventListener("click", (e) => {
130
130
  if (e.target.tagName === "BUTTON" || e.target.tagName === "TEXTAREA") return;
131
+
132
+ // Mark this card active
133
+ for (const c of commentListEl.querySelectorAll(".comment-card.active")) {
134
+ c.classList.remove("active");
135
+ }
136
+ card.classList.add("active");
137
+
138
+ // Scroll to and flash the in-content highlight
131
139
  const id = card.dataset.id;
132
140
  const highlight = fileContentEl.querySelector(`[data-comment-id="${id}"]`);
133
141
  if (highlight) {
@@ -105,6 +105,7 @@ function applyTipTapFormat(editor, format) {
105
105
  case 'italic': editor.chain().focus().toggleItalic().run(); break;
106
106
  case 'strikethrough': editor.chain().focus().toggleStrike().run(); break;
107
107
  case 'code': editor.chain().focus().toggleCode().run(); break;
108
+ case 'codeBlock': editor.chain().focus().toggleCodeBlock().run(); break;
108
109
  case 'link': {
109
110
  const url = prompt('Link URL:', 'https://');
110
111
  if (url) editor.chain().focus().setLink({ href: url }).run();
@@ -153,6 +154,12 @@ function applyMarkdownFormat(format) {
153
154
  return;
154
155
  }
155
156
 
157
+ if (format === "codeBlock") {
158
+ send({ type: "edit_apply", offset, length, newText: "```\n" + selectedText + "\n```" });
159
+ hideTrigger();
160
+ return;
161
+ }
162
+
156
163
  const { prefix, suffix } = FORMAT_SYNTAX[format];
157
164
 
158
165
  // Toggle detection: check if selection is already wrapped