@cueloop/client 0.1.0-alpha.101 → 0.1.0-alpha.103

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 (122) hide show
  1. package/package.json +5 -5
  2. package/src/annotations/annotation-palette.ts +1 -0
  3. package/src/annotations/components/AnnotationCards.tsx +14 -1
  4. package/src/annotations/components/DiscussionMarkerRail.tsx +3 -0
  5. package/src/annotations/discussions.ts +1 -0
  6. package/src/annotations/thread-selection.ts +6 -0
  7. package/src/annotations/use-annotation-surface.tsx +154 -19
  8. package/src/app/App.deleted-scroll.test.tsx +3 -0
  9. package/src/app/App.harness-settings.test.tsx +77 -0
  10. package/src/app/App.plan-render.test.tsx +2 -0
  11. package/src/app/App.plan-review.test.tsx +1 -0
  12. package/src/app/App.test.tsx +1 -0
  13. package/src/app/App.tsx +72 -6
  14. package/src/app/App.visual.test.tsx +1 -0
  15. package/src/app/App.walk.test.tsx +1 -0
  16. package/src/app/App.workbench.test.tsx +1 -0
  17. package/src/app/app-screens.tsx +1 -0
  18. package/src/app/app-view-model.ts +7 -0
  19. package/src/app/components/WorkspacePanels.tsx +1 -0
  20. package/src/app/intent-dispatch.test.ts +1 -0
  21. package/src/app/intent-dispatch.ts +26 -0
  22. package/src/app/ready-signal.ts +2 -0
  23. package/src/app/run.ts +2 -0
  24. package/src/app/serve.test.ts +4 -0
  25. package/src/diff/components/AnnotatableFileView.tsx +3 -2
  26. package/src/diff/components/DiffContentView.scroll.test.tsx +9 -0
  27. package/src/diff/components/DiffContentView.syntax.test.tsx +1 -0
  28. package/src/diff/components/DiffContentView.tsx +28 -3
  29. package/src/diff/components/diff-content-view-layout.ts +3 -0
  30. package/src/diff/diff-fold.ts +4 -0
  31. package/src/diff/diff-hunk-curate.ts +3 -0
  32. package/src/diff/diff-intraline.ts +6 -0
  33. package/src/diff/diff-syntax.ts +8 -0
  34. package/src/diff/split-diff.ts +6 -0
  35. package/src/diff/view-diff.ts +18 -0
  36. package/src/diff/walk.ts +3 -0
  37. package/src/integrations/attribution.ts +2 -0
  38. package/src/integrations/client-extension-registry.ts +4 -0
  39. package/src/integrations/clipboard.ts +1 -0
  40. package/src/integrations/components/ShareDialog.agent.test.tsx +2 -0
  41. package/src/integrations/components/ShareDialog.tsx +28 -0
  42. package/src/integrations/editor.ts +3 -0
  43. package/src/integrations/github-identity.test.ts +1 -0
  44. package/src/integrations/github-identity.ts +1 -0
  45. package/src/integrations/herdr.ts +2 -0
  46. package/src/integrations/pasted-image.ts +2 -0
  47. package/src/integrations/share.ts +4 -0
  48. package/src/keyboard/components/HandleChipsInput.tsx +4 -0
  49. package/src/keyboard/components/SlashComposer.tsx +3 -0
  50. package/src/keyboard/key-bindings.ts +3 -0
  51. package/src/keyboard/keymap.ts +51 -0
  52. package/src/keyboard/skills.ts +2 -0
  53. package/src/keyboard/slash-palette.ts +8 -0
  54. package/src/keyboard/thread-chords.ts +5 -0
  55. package/src/keyboard/use-shared-keyboard.ts +1 -0
  56. package/src/markdown/components/MarkdownThreadEditor.tsx +3 -0
  57. package/src/markdown/components/ThreadView.selection.test.tsx +3 -0
  58. package/src/markdown/components/ThreadView.tsx +16 -3
  59. package/src/markdown/mark-runs.ts +4 -0
  60. package/src/markdown/markdown-editor-syntax-style.ts +1 -0
  61. package/src/markdown/markdown-grid.ts +6 -0
  62. package/src/markdown/markdown-highlight.ts +1 -0
  63. package/src/markdown/thread-code-syntax.ts +3 -0
  64. package/src/markdown/view-plan.ts +52 -0
  65. package/src/performance/perf-report.ts +1 -0
  66. package/src/performance/perf-timings.ts +1 -0
  67. package/src/prototype/components/PrototypeContentView.tsx +17 -0
  68. package/src/prototype/prototype-browser.ts +11 -0
  69. package/src/settings/components/SettingsDialog.tsx +3 -0
  70. package/src/settings/config.test.ts +41 -0
  71. package/src/settings/config.ts +44 -0
  72. package/src/settings/use-settings-dialog.test.tsx +98 -0
  73. package/src/settings/use-settings-dialog.tsx +38 -1
  74. package/src/settings/use-thread-harness-setting.test.tsx +87 -0
  75. package/src/settings/use-thread-harness-setting.ts +86 -0
  76. package/src/stories/stories.test.tsx +4 -0
  77. package/src/stories/story.ts +6 -0
  78. package/src/terminal/ansi-screen.ts +5 -0
  79. package/src/terminal/components/terminal-pane.ts +12 -0
  80. package/src/terminal/ghostty-terminal.ts +10 -0
  81. package/src/terminal/kitty-image.ts +3 -0
  82. package/src/terminal/pty.ts +9 -0
  83. package/src/testing/test-support.test.ts +2 -0
  84. package/src/testing/test-support.ts +16 -0
  85. package/src/thread/agent-continuation.test.ts +2 -0
  86. package/src/thread/agent-transcript.ts +18 -10
  87. package/src/thread/components/AgentConfigControls.tsx +1 -0
  88. package/src/thread/components/AgentThreadPane.test.tsx +257 -1
  89. package/src/thread/components/AgentThreadPane.tsx +48 -16
  90. package/src/thread/components/ThreadTree.tsx +1 -0
  91. package/src/thread/components/thread-tree.test.ts +1 -0
  92. package/src/thread/thread-controller.curate.test.ts +2 -0
  93. package/src/thread/thread-controller.ts +123 -0
  94. package/src/thread/tree-view.ts +4 -0
  95. package/src/thread/use-thread-agent.test.tsx +1 -0
  96. package/src/thread/use-thread-agent.ts +5 -0
  97. package/src/ui/components/OverlayScrollbar.test.tsx +3 -0
  98. package/src/ui/components/OverlayScrollbar.tsx +5 -0
  99. package/src/ui/components/PromptDialog.tsx +2 -0
  100. package/src/ui/components/RootOverlay.tsx +1 -0
  101. package/src/ui/components/ScrollArea.tsx +2 -0
  102. package/src/ui/components/primitives/Button.tsx +1 -0
  103. package/src/ui/components/primitives/Tabs.tsx +1 -0
  104. package/src/ui/components/primitives/Tree.tsx +4 -0
  105. package/src/ui/components/primitives/tree-model.ts +7 -0
  106. package/src/ui/components/syntax-highlight.ts +5 -0
  107. package/src/ui/components/truncate-title.ts +1 -0
  108. package/src/ui/use-frame-measure.ts +3 -0
  109. package/src/ui/use-terminal-virtualizer.ts +6 -0
  110. package/src/workbench/components/ChangesColumn.tsx +7 -0
  111. package/src/workbench/components/ChangesFileTree.test.tsx +3 -0
  112. package/src/workbench/components/EditorGrid.tsx +8 -0
  113. package/src/workbench/components/FileContentsView.tsx +2 -0
  114. package/src/workbench/components/GridTabContent.tsx +2 -0
  115. package/src/workbench/components/ProjectTreeView.test.tsx +3 -0
  116. package/src/workbench/components/ProjectTreeView.tsx +8 -0
  117. package/src/workbench/components/TreePane.tsx +2 -0
  118. package/src/workbench/components/editor-grid.ts +3 -0
  119. package/src/workbench/components/file-tree.ts +2 -0
  120. package/src/workbench/use-changes-workbench.ts +5 -0
  121. package/src/workbench/use-remember-layout.ts +2 -0
  122. package/src/workbench/use-repo-changes.ts +2 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cueloop/client",
3
- "version": "0.1.0-alpha.101",
3
+ "version": "0.1.0-alpha.103",
4
4
  "description": "The cueloop review UI: projection renderer, keyboard grammar, review rail",
5
5
  "homepage": "https://github.com/mmurakaru/cueloop#readme",
6
6
  "bugs": {
@@ -27,10 +27,10 @@
27
27
  "access": "public"
28
28
  },
29
29
  "dependencies": {
30
- "@cueloop/daemon": "0.1.0-alpha.101",
31
- "@cueloop/extension-api": "0.1.0-alpha.101",
32
- "@cueloop/integration-obsidian": "0.1.0-alpha.101",
33
- "@cueloop/schema": "0.1.0-alpha.101",
30
+ "@cueloop/daemon": "0.1.0-alpha.103",
31
+ "@cueloop/extension-api": "0.1.0-alpha.103",
32
+ "@cueloop/integration-obsidian": "0.1.0-alpha.103",
33
+ "@cueloop/schema": "0.1.0-alpha.103",
34
34
  "@opentui/core": "^0.5.14",
35
35
  "@opentui/keymap": "0.5.14",
36
36
  "@opentui/react": "^0.5.14",
@@ -47,6 +47,7 @@ export function lighten(hex: string, amount = 0.25): string {
47
47
  const channels = hex.match(/^#(..)(..)(..)$/);
48
48
 
49
49
  if (!channels) return hex;
50
+
50
51
  const lifted = channels
51
52
  .slice(1)
52
53
  .map((channel) => {
@@ -79,6 +79,7 @@ export function Composer({
79
79
  const editor = editorRef.current;
80
80
 
81
81
  if (!editor || !editor.focused || !looksLikeBinaryPaste(event.bytes)) return;
82
+
82
83
  event.preventDefault();
83
84
  pastedImageCount.current += 1;
84
85
  editor.editBuffer.insertText(imagePlaceholder(pastedImageCount.current));
@@ -100,6 +101,7 @@ export function Composer({
100
101
  const editor = editorRef.current;
101
102
 
102
103
  if (!editor) return;
104
+
103
105
  editor.cursorOffset = seed.length;
104
106
  editor.editBuffer.setSyntaxStyle(referenceStyleFor(tokens).style);
105
107
  paintReferences(editor);
@@ -133,6 +135,7 @@ export function Composer({
133
135
  const editor = editorRef.current;
134
136
 
135
137
  if (!editor) return;
138
+
136
139
  paintReferences(editor);
137
140
  setRows(composeRowCount(editor.plainText, editor.width));
138
141
  onInput(editor.plainText, editor.cursorOffset);
@@ -317,12 +320,14 @@ export function CommentRow({
317
320
  tokens,
318
321
  authorLabel,
319
322
  action,
323
+ onFocus,
320
324
  }: {
321
325
  annotation: Annotation;
322
326
  tokens: Theme;
323
327
  /** The author's resolved display name, shown as a tooltip when the dot is hovered. */
324
328
  authorLabel?: string;
325
329
  action?: { label: string; run: () => void };
330
+ onFocus?: () => void;
326
331
  }): React.ReactNode {
327
332
  // own comments (no author) wear the filled dot, collaborators the outline
328
333
  const own = annotation.author === undefined;
@@ -337,7 +342,15 @@ export function CommentRow({
337
342
  : {};
338
343
 
339
344
  return (
340
- <box style={{ flexDirection: "column" }}>
345
+ <box
346
+ style={{ flexDirection: "column" }}
347
+ onMouseDown={(event) => {
348
+ if (!onFocus) return;
349
+
350
+ event.stopPropagation();
351
+ onFocus();
352
+ }}
353
+ >
341
354
  {annotation.body.split("\n").map((line, lineIndex) => (
342
355
  <box key={lineIndex} style={{ flexDirection: "row" }}>
343
356
  <box style={{ flexShrink: 0 }} {...(lineIndex === 0 ? dotHover : {})}>
@@ -56,6 +56,7 @@ function ScrollMarkers({
56
56
  const isActive = (index: number): boolean => index === hoveredIndex || index === focusedIndex;
57
57
  const colorFor = (index: number): string => {
58
58
  if (isActive(index)) return tokens.text;
59
+
59
60
  if (hoveredIndex >= 0 && discussions.length >= 5 && Math.abs(index - hoveredIndex) === 1) {
60
61
  return tokens.textMuted;
61
62
  }
@@ -126,9 +127,11 @@ export function DiscussionMarkerRail({
126
127
 
127
128
  const preview = (): React.ReactNode => {
128
129
  if (hovered === null) return null;
130
+
129
131
  const discussion = discussions.find((candidate) => candidate.key === hovered.key);
130
132
 
131
133
  if (!discussion) return null;
134
+
132
135
  const quote = spanQuote(discussion.span);
133
136
  const lastComment = discussion.annotations.at(-1)!;
134
137
 
@@ -34,6 +34,7 @@ export function discussionsFrom(session: Thread, marks: Map<number, Mark[]>): Di
34
34
  for (const [displayIndex, blockMarks] of marks) {
35
35
  for (const mark of blockMarks) {
36
36
  if (!mark.annotationId || spanOf.has(mark.annotationId)) continue;
37
+
37
38
  spanOf.set(
38
39
  mark.annotationId,
39
40
  mark.span ?? {
@@ -69,6 +69,7 @@ export function wordIndexAt(text: string, char: number): number {
69
69
 
70
70
  for (let index = 0; index < words.length; index++) {
71
71
  if (char < words[index]!.start) return Math.max(0, index - 1);
72
+
72
73
  if (char < words[index]!.end) return index;
73
74
  }
74
75
 
@@ -91,6 +92,7 @@ export function wordRangeAt(text: string, char: number): CharRange | null {
91
92
  */
92
93
  export function positionAt(lines: LineGeometry[], x: number, y: number): TextPosition | null {
93
94
  if (lines.length === 0) return null;
95
+
94
96
  const ordered = lines.toSorted((left, right) => left.y - right.y || left.x - right.x);
95
97
  const onRow = ordered.find((line) => line.y === y);
96
98
 
@@ -99,9 +101,11 @@ export function positionAt(lines: LineGeometry[], x: number, y: number): TextPos
99
101
 
100
102
  return { blockIndex: onRow.blockIndex, char: onRow.start + column };
101
103
  }
104
+
102
105
  const above = ordered.findLast((line) => line.y < y);
103
106
 
104
107
  if (above) return { blockIndex: above.blockIndex, char: above.end };
108
+
105
109
  const first = ordered[0]!;
106
110
 
107
111
  return { blockIndex: first.blockIndex, char: first.start };
@@ -156,6 +160,7 @@ export function spanRangeInBlock(
156
160
  textLength: number,
157
161
  ): CharRange | null {
158
162
  if (blockIndex < span.start.blockIndex || blockIndex > span.end.blockIndex) return null;
163
+
159
164
  const start = blockIndex === span.start.blockIndex ? span.start.char : 0;
160
165
  const end = blockIndex === span.end.blockIndex ? Math.min(span.end.char, textLength) : textLength;
161
166
 
@@ -189,6 +194,7 @@ export function snapSpanToWords(span: TextSpan, textOf: (blockIndex: number) =>
189
194
  end: { blockIndex: span.end.blockIndex, char: snapped.end },
190
195
  };
191
196
  }
197
+
192
198
  const startText = textOf(span.start.blockIndex);
193
199
  const endText = textOf(span.end.blockIndex);
194
200