pi-studio 0.5.48 → 0.5.50

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.
package/client/studio.css CHANGED
@@ -920,18 +920,19 @@
920
920
  position: absolute;
921
921
  top: 0;
922
922
  right: 0;
923
- z-index: 4;
923
+ z-index: 6;
924
924
  display: inline-flex;
925
925
  align-items: center;
926
926
  gap: 8px;
927
- transform: translateY(-0.38rem);
927
+ transform: translateY(-0.46rem);
928
928
  }
929
929
 
930
930
  .preview-comment-summary {
931
931
  display: none !important;
932
932
  }
933
933
 
934
- .preview-comment-add {
934
+ .preview-comment-add,
935
+ .preview-comment-jump {
935
936
  display: inline-flex;
936
937
  align-items: center;
937
938
  justify-content: center;
@@ -950,14 +951,17 @@
950
951
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);
951
952
  }
952
953
 
953
- .preview-comment-block.has-selection .preview-comment-add {
954
+ .preview-comment-block.has-selection .preview-comment-add,
955
+ .preview-comment-block.has-selection .preview-comment-jump {
954
956
  opacity: 1;
955
957
  pointer-events: auto;
956
958
  transform: translateY(0);
957
959
  }
958
960
 
959
961
  .preview-comment-add:hover,
960
- .preview-comment-add:focus-visible {
962
+ .preview-comment-add:focus-visible,
963
+ .preview-comment-jump:hover,
964
+ .preview-comment-jump:focus-visible {
961
965
  background: var(--accent-soft-strong);
962
966
  color: var(--accent);
963
967
  border-color: var(--accent);
package/index.ts CHANGED
@@ -19,6 +19,7 @@ import {
19
19
  replaceStudioInlineAnnotationMarkers,
20
20
  transformStudioMarkdownOutsideFences,
21
21
  } from "./shared/studio-annotation-scanner.js";
22
+ import { stripStudioMarkdownHtmlComments } from "./shared/studio-markdown-html-comments.js";
22
23
  import { escapeStudioPdfLatexTextFragment } from "./shared/studio-pdf-escape.js";
23
24
 
24
25
  type Lens = "writing" | "code";
@@ -2893,114 +2894,6 @@ function normalizeMathDelimiters(markdown: string): string {
2893
2894
  return out.join("\n");
2894
2895
  }
2895
2896
 
2896
- function stripStudioMarkdownHtmlCommentsInSegment(markdown: string): string {
2897
- const source = String(markdown ?? "");
2898
- let out = "";
2899
- let i = 0;
2900
- let codeSpanFenceLength = 0;
2901
- let inHtmlComment = false;
2902
-
2903
- while (i < source.length) {
2904
- if (inHtmlComment) {
2905
- if (source.startsWith("-->", i)) {
2906
- inHtmlComment = false;
2907
- i += 3;
2908
- continue;
2909
- }
2910
- const ch = source[i]!;
2911
- if (ch === "\n" || ch === "\r") out += ch;
2912
- i += 1;
2913
- continue;
2914
- }
2915
-
2916
- if (codeSpanFenceLength > 0) {
2917
- const fence = "`".repeat(codeSpanFenceLength);
2918
- if (source.startsWith(fence, i)) {
2919
- out += fence;
2920
- i += codeSpanFenceLength;
2921
- codeSpanFenceLength = 0;
2922
- continue;
2923
- }
2924
- out += source[i]!;
2925
- i += 1;
2926
- continue;
2927
- }
2928
-
2929
- const backtickMatch = source.slice(i).match(/^`+/);
2930
- if (backtickMatch) {
2931
- const fence = backtickMatch[0]!;
2932
- codeSpanFenceLength = fence.length;
2933
- out += fence;
2934
- i += fence.length;
2935
- continue;
2936
- }
2937
-
2938
- if (source.startsWith("<!--", i)) {
2939
- inHtmlComment = true;
2940
- i += 4;
2941
- continue;
2942
- }
2943
-
2944
- out += source[i]!;
2945
- i += 1;
2946
- }
2947
-
2948
- return out;
2949
- }
2950
-
2951
- function stripStudioMarkdownHtmlComments(markdown: string): string {
2952
- const lines = String(markdown ?? "").split("\n");
2953
- const out: string[] = [];
2954
- let plainBuffer: string[] = [];
2955
- let inFence = false;
2956
- let fenceChar: "`" | "~" | undefined;
2957
- let fenceLength = 0;
2958
-
2959
- const flushPlain = () => {
2960
- if (plainBuffer.length === 0) return;
2961
- out.push(stripStudioMarkdownHtmlCommentsInSegment(plainBuffer.join("\n")));
2962
- plainBuffer = [];
2963
- };
2964
-
2965
- for (const line of lines) {
2966
- const trimmed = line.trimStart();
2967
- const fenceMatch = trimmed.match(/^(`{3,}|~{3,})/);
2968
-
2969
- if (fenceMatch) {
2970
- const marker = fenceMatch[1]!;
2971
- const markerChar = marker[0] as "`" | "~";
2972
- const markerLength = marker.length;
2973
-
2974
- if (!inFence) {
2975
- flushPlain();
2976
- inFence = true;
2977
- fenceChar = markerChar;
2978
- fenceLength = markerLength;
2979
- out.push(line);
2980
- continue;
2981
- }
2982
-
2983
- if (fenceChar === markerChar && markerLength >= fenceLength) {
2984
- inFence = false;
2985
- fenceChar = undefined;
2986
- fenceLength = 0;
2987
- }
2988
-
2989
- out.push(line);
2990
- continue;
2991
- }
2992
-
2993
- if (inFence) {
2994
- out.push(line);
2995
- } else {
2996
- plainBuffer.push(line);
2997
- }
2998
- }
2999
-
3000
- flushPlain();
3001
- return out.join("\n");
3002
- }
3003
-
3004
2897
  const STUDIO_PREVIEW_PAGE_BREAK_SENTINEL_PREFIX = "PI_STUDIO_PAGE_BREAK__";
3005
2898
 
3006
2899
  function replaceStudioPreviewPageBreakCommands(markdown: string): string {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-studio",
3
- "version": "0.5.48",
3
+ "version": "0.5.50",
4
4
  "description": "Two-pane browser workspace for pi with prompt/response editing, annotations, critiques, prompt/response history, and live Markdown/LaTeX/code preview",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -0,0 +1,111 @@
1
+ export function stripStudioMarkdownHtmlCommentsInSegment(markdown) {
2
+ const source = String(markdown ?? "");
3
+ let out = "";
4
+ let index = 0;
5
+ let codeSpanFenceLength = 0;
6
+ let inHtmlComment = false;
7
+
8
+ while (index < source.length) {
9
+ if (inHtmlComment) {
10
+ if (source.startsWith("-->", index)) {
11
+ inHtmlComment = false;
12
+ index += 3;
13
+ continue;
14
+ }
15
+ const ch = source[index];
16
+ if (ch === "\n" || ch === "\r") out += ch;
17
+ index += 1;
18
+ continue;
19
+ }
20
+
21
+ if (codeSpanFenceLength > 0) {
22
+ const fence = "`".repeat(codeSpanFenceLength);
23
+ if (source.startsWith(fence, index)) {
24
+ out += fence;
25
+ index += codeSpanFenceLength;
26
+ codeSpanFenceLength = 0;
27
+ continue;
28
+ }
29
+ const ch = source[index];
30
+ out += ch;
31
+ index += 1;
32
+ if (ch === "\n" || ch === "\r") {
33
+ codeSpanFenceLength = 0;
34
+ }
35
+ continue;
36
+ }
37
+
38
+ const backtickMatch = source.slice(index).match(/^`+/);
39
+ if (backtickMatch) {
40
+ const fence = backtickMatch[0];
41
+ codeSpanFenceLength = fence.length;
42
+ out += fence;
43
+ index += fence.length;
44
+ continue;
45
+ }
46
+
47
+ if (source.startsWith("<!--", index)) {
48
+ inHtmlComment = true;
49
+ index += 4;
50
+ continue;
51
+ }
52
+
53
+ out += source[index];
54
+ index += 1;
55
+ }
56
+
57
+ return out;
58
+ }
59
+
60
+ export function stripStudioMarkdownHtmlComments(markdown) {
61
+ const lines = String(markdown ?? "").split("\n");
62
+ const out = [];
63
+ let plainBuffer = [];
64
+ let inFence = false;
65
+ let fenceChar;
66
+ let fenceLength = 0;
67
+
68
+ const flushPlain = () => {
69
+ if (plainBuffer.length === 0) return;
70
+ out.push(stripStudioMarkdownHtmlCommentsInSegment(plainBuffer.join("\n")));
71
+ plainBuffer = [];
72
+ };
73
+
74
+ for (const line of lines) {
75
+ const trimmed = line.trimStart();
76
+ const fenceMatch = trimmed.match(/^(`{3,}|~{3,})/);
77
+
78
+ if (fenceMatch) {
79
+ const marker = fenceMatch[1];
80
+ const markerChar = marker[0];
81
+ const markerLength = marker.length;
82
+
83
+ if (!inFence) {
84
+ flushPlain();
85
+ inFence = true;
86
+ fenceChar = markerChar;
87
+ fenceLength = markerLength;
88
+ out.push(line);
89
+ continue;
90
+ }
91
+
92
+ if (fenceChar === markerChar && markerLength >= fenceLength) {
93
+ inFence = false;
94
+ fenceChar = undefined;
95
+ fenceLength = 0;
96
+ }
97
+
98
+ out.push(line);
99
+ continue;
100
+ }
101
+
102
+ if (inFence) {
103
+ out.push(line);
104
+ } else {
105
+ plainBuffer.push(line);
106
+ }
107
+ }
108
+
109
+ flushPlain();
110
+ return out.join("\n");
111
+ }