pi-studio 0.9.47 → 0.9.49

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.
@@ -43,10 +43,62 @@
43
43
  return { attempted: images.length, resolved };
44
44
  }
45
45
 
46
+ function buildStudioPdfVersionSignature(headers) {
47
+ if (!headers || typeof headers.get !== "function") return "";
48
+ const etag = String(headers.get("etag") || "").trim();
49
+ const modified = String(headers.get("last-modified") || "").trim();
50
+ const length = String(headers.get("content-length") || "").trim();
51
+ if (!etag && !modified && !length) return "";
52
+ return [etag, modified, length].join("\n");
53
+ }
54
+
55
+ function createStudioPdfVersionObservationState() {
56
+ return {
57
+ baseline: "",
58
+ candidate: "",
59
+ candidateCount: 0,
60
+ };
61
+ }
62
+
63
+ function observeStudioPdfVersion(previousState, signature, stableObservations) {
64
+ const state = previousState && typeof previousState === "object"
65
+ ? previousState
66
+ : createStudioPdfVersionObservationState();
67
+ const nextSignature = String(signature || "").trim();
68
+ const required = Math.max(2, Number.parseInt(String(stableObservations || "2"), 10) || 2);
69
+ if (!nextSignature) return { state, changed: false };
70
+ if (!state.baseline) {
71
+ return {
72
+ state: { baseline: nextSignature, candidate: "", candidateCount: 0 },
73
+ changed: false,
74
+ };
75
+ }
76
+ if (nextSignature === state.baseline) {
77
+ return {
78
+ state: { baseline: state.baseline, candidate: "", candidateCount: 0 },
79
+ changed: false,
80
+ };
81
+ }
82
+ const candidateCount = nextSignature === state.candidate ? state.candidateCount + 1 : 1;
83
+ if (candidateCount < required) {
84
+ return {
85
+ state: { baseline: state.baseline, candidate: nextSignature, candidateCount },
86
+ changed: false,
87
+ };
88
+ }
89
+ return {
90
+ state: { baseline: nextSignature, candidate: "", candidateCount: 0 },
91
+ changed: true,
92
+ };
93
+ }
94
+
46
95
  globalThis.PiStudioPreviewResourceHelpers = Object.freeze({
47
96
  STUDIO_PREVIEW_LOCAL_IMAGE_LIMIT,
48
97
  areStudioPreviewResourceContextsEqual,
98
+ buildStudioPdfVersionSignature,
99
+ createStudioPdfVersionObservationState,
49
100
  hydrateStudioPreviewLocalImages,
50
101
  isResolvableStudioPreviewImageSource,
102
+ observeStudioPdfVersion,
51
103
  });
52
104
  })();
package/client/studio.css CHANGED
@@ -148,7 +148,7 @@
148
148
  background: var(--panel-2);
149
149
  }
150
150
 
151
- button, select, .file-label {
151
+ button, select {
152
152
  border: 1px solid var(--control-border);
153
153
  background: var(--panel);
154
154
  color: var(--text);
@@ -163,14 +163,12 @@
163
163
  }
164
164
 
165
165
  button:not(:disabled):hover,
166
- select:hover,
167
- .file-label:hover {
166
+ select:hover {
168
167
  background: var(--panel-2);
169
168
  }
170
169
 
171
170
  button:focus-visible,
172
- select:focus-visible,
173
- .file-label:focus-within {
171
+ select:focus-visible {
174
172
  outline: 2px solid var(--accent-soft-strong);
175
173
  outline-offset: 1px;
176
174
  }
@@ -229,15 +227,8 @@
229
227
  filter: none;
230
228
  }
231
229
 
232
- .file-label {
233
- cursor: pointer;
234
- display: inline-flex;
235
- align-items: center;
236
- gap: 6px;
237
- }
238
-
239
- .file-label input {
240
- display: none;
230
+ .file-input-hidden {
231
+ display: none !important;
241
232
  }
242
233
 
243
234
  main {
@@ -1749,6 +1740,7 @@
1749
1740
 
1750
1741
  .rendered-markdown .studio-pdf-card-header {
1751
1742
  display: flex;
1743
+ flex-wrap: wrap;
1752
1744
  align-items: center;
1753
1745
  justify-content: space-between;
1754
1746
  gap: 10px;
@@ -1777,10 +1769,13 @@
1777
1769
  }
1778
1770
 
1779
1771
  .rendered-markdown .studio-pdf-card-actions {
1780
- flex: 0 0 auto;
1772
+ flex: 0 1 auto;
1781
1773
  display: inline-flex;
1774
+ flex-wrap: wrap;
1775
+ justify-content: flex-end;
1782
1776
  align-items: center;
1783
1777
  gap: 8px;
1778
+ margin-left: auto;
1784
1779
  }
1785
1780
 
1786
1781
  .rendered-markdown .studio-pdf-card-link,
@@ -1827,6 +1822,20 @@
1827
1822
  border-color: var(--control-border);
1828
1823
  }
1829
1824
 
1825
+ .rendered-markdown button.studio-pdf-card-auto-refresh[aria-pressed="true"] {
1826
+ background: transparent;
1827
+ color: var(--accent);
1828
+ border-color: transparent;
1829
+ font-weight: 600;
1830
+ }
1831
+
1832
+ .rendered-markdown button.studio-pdf-card-auto-refresh[aria-pressed="true"]:not(:disabled):hover,
1833
+ .rendered-markdown button.studio-pdf-card-auto-refresh[aria-pressed="true"]:focus-visible {
1834
+ background: var(--panel);
1835
+ color: var(--accent);
1836
+ border-color: var(--control-border);
1837
+ }
1838
+
1830
1839
  .rendered-markdown button.studio-pdf-card-focus {
1831
1840
  width: 29px;
1832
1841
  min-width: 29px;
@@ -1907,6 +1916,7 @@
1907
1916
  .studio-pdf-focus-header {
1908
1917
  flex: 0 0 auto;
1909
1918
  display: flex;
1919
+ flex-wrap: wrap;
1910
1920
  align-items: center;
1911
1921
  justify-content: space-between;
1912
1922
  gap: 12px;
@@ -1934,10 +1944,13 @@
1934
1944
  }
1935
1945
 
1936
1946
  .studio-pdf-focus-actions {
1937
- flex: 0 0 auto;
1947
+ flex: 0 1 auto;
1938
1948
  display: inline-flex;
1949
+ flex-wrap: wrap;
1950
+ justify-content: flex-end;
1939
1951
  align-items: center;
1940
1952
  gap: 8px;
1953
+ margin-left: auto;
1941
1954
  }
1942
1955
 
1943
1956
  .studio-pdf-focus-link,
@@ -1984,6 +1997,20 @@
1984
1997
  color: var(--text);
1985
1998
  }
1986
1999
 
2000
+ .studio-pdf-focus-auto-refresh[aria-pressed="true"] {
2001
+ background: transparent;
2002
+ border-color: transparent;
2003
+ color: var(--accent);
2004
+ font-weight: 600;
2005
+ }
2006
+
2007
+ .studio-pdf-focus-auto-refresh[aria-pressed="true"]:not(:disabled):hover,
2008
+ .studio-pdf-focus-auto-refresh[aria-pressed="true"]:focus-visible {
2009
+ background: var(--panel);
2010
+ border-color: var(--control-border);
2011
+ color: var(--accent);
2012
+ }
2013
+
1987
2014
  .studio-pdf-focus-btn .studio-refresh-icon {
1988
2015
  width: 14px;
1989
2016
  height: 14px;
@@ -2909,6 +2936,10 @@
2909
2936
  font-style: italic;
2910
2937
  }
2911
2938
 
2939
+ .studio-latex-compatibility-warning {
2940
+ margin: 0 0 0.85em;
2941
+ }
2942
+
2912
2943
  .marker {
2913
2944
  display: inline-block;
2914
2945
  padding: 0 4px;
@@ -5362,13 +5393,13 @@
5362
5393
  }
5363
5394
 
5364
5395
  body.studio-ui-refresh > header button,
5365
- body.studio-ui-refresh > header .file-label,
5366
5396
  body.studio-ui-refresh #responseActions button,
5367
5397
  body.studio-ui-refresh #responseActions select {
5368
5398
  padding: 5px 7px;
5369
5399
  font-size: 12px;
5370
5400
  }
5371
5401
 
5402
+
5372
5403
  body.studio-ui-refresh main {
5373
5404
  gap: 0;
5374
5405
  padding: 9px;
@@ -6101,6 +6132,102 @@
6101
6132
  font-weight: 700;
6102
6133
  }
6103
6134
 
6135
+ .studio-decision-overlay {
6136
+ position: fixed;
6137
+ inset: 0;
6138
+ z-index: 13000;
6139
+ display: grid;
6140
+ place-items: center;
6141
+ padding: 20px;
6142
+ background: rgba(0, 0, 0, 0.58);
6143
+ backdrop-filter: blur(2px);
6144
+ }
6145
+
6146
+ .studio-decision-overlay[hidden] {
6147
+ display: none !important;
6148
+ }
6149
+
6150
+ .studio-decision-dialog {
6151
+ width: min(560px, calc(100vw - 32px));
6152
+ max-height: min(80vh, 680px);
6153
+ overflow: auto;
6154
+ padding: 20px;
6155
+ border: 1px solid var(--panel-border);
6156
+ border-radius: 14px;
6157
+ background: var(--panel);
6158
+ color: var(--text);
6159
+ box-shadow: 0 24px 70px rgba(0, 0, 0, 0.48);
6160
+ }
6161
+
6162
+ .studio-decision-title {
6163
+ margin: 0;
6164
+ color: var(--text);
6165
+ font-size: 17px;
6166
+ line-height: 1.3;
6167
+ }
6168
+
6169
+ .studio-decision-message {
6170
+ margin-top: 10px;
6171
+ color: var(--studio-info-text, var(--muted));
6172
+ font-size: 13px;
6173
+ line-height: 1.5;
6174
+ white-space: pre-wrap;
6175
+ overflow-wrap: anywhere;
6176
+ }
6177
+
6178
+ .studio-decision-input {
6179
+ width: 100%;
6180
+ margin-top: 16px;
6181
+ padding: 9px 10px;
6182
+ border: 1px solid var(--control-border);
6183
+ border-radius: 8px;
6184
+ background: var(--panel-2);
6185
+ color: var(--text);
6186
+ font-family: var(--font-mono);
6187
+ font-size: 13px;
6188
+ }
6189
+
6190
+ .studio-decision-input[hidden] {
6191
+ display: none !important;
6192
+ }
6193
+
6194
+ .studio-decision-input:focus {
6195
+ border-color: var(--accent);
6196
+ outline: 2px solid var(--accent-soft);
6197
+ outline-offset: 1px;
6198
+ }
6199
+
6200
+ .studio-decision-actions {
6201
+ display: flex;
6202
+ flex-wrap: wrap;
6203
+ justify-content: flex-end;
6204
+ gap: 8px;
6205
+ margin-top: 18px;
6206
+ }
6207
+
6208
+ .studio-decision-confirm:not(.is-destructive) {
6209
+ border-color: var(--accent);
6210
+ background: var(--accent);
6211
+ color: var(--accent-contrast);
6212
+ font-weight: 650;
6213
+ }
6214
+
6215
+ .studio-decision-confirm.is-destructive {
6216
+ border-color: var(--warn-border);
6217
+ background: color-mix(in srgb, var(--warn) 15%, var(--panel));
6218
+ color: var(--warn);
6219
+ font-weight: 650;
6220
+ }
6221
+
6222
+ .studio-decision-confirm.is-destructive:hover,
6223
+ .studio-decision-confirm.is-destructive:focus-visible {
6224
+ background: color-mix(in srgb, var(--warn) 24%, var(--panel));
6225
+ }
6226
+
6227
+ body.studio-decision-open {
6228
+ overflow: hidden;
6229
+ }
6230
+
6104
6231
  .studio-preview-link-menu {
6105
6232
  position: fixed;
6106
6233
  z-index: 12000;