@firstpick/pi-package-webui 0.3.6 → 0.3.8

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/public/index.html CHANGED
@@ -12,7 +12,7 @@
12
12
  <link rel="manifest" href="/manifest.webmanifest" />
13
13
  <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
14
14
  <link rel="apple-touch-icon" href="/apple-touch-icon.png" />
15
- <link rel="stylesheet" href="/styles.css?v=39" />
15
+ <link rel="stylesheet" href="/styles.css?v=43" />
16
16
  </head>
17
17
  <body>
18
18
  <button id="sidePanelExpandButton" class="side-panel-expand-button" type="button" aria-controls="sidePanel" aria-expanded="false" aria-label="Expand side panel" title="Expand side panel">
@@ -144,8 +144,8 @@
144
144
  type="button"
145
145
  hidden
146
146
  title="Guided Git workflow"
147
- aria-label="Start guided Git workflow: git add dot, run git-staged-msg, preview messages, commit short or long, then git push. Cancel is available at each step."
148
- data-tooltip="GitHub workflow:&#10;1. Run git add .&#10;2. Run /git-staged-msg&#10;3. Preview short + long messages&#10;4. Commit with short or long message&#10;5. Run git push&#10;Cancel is available at each step."
147
+ aria-label="Start guided Git workflow: stage all changes, generate and preview staged commit messages, optionally create a PR branch, commit short or long, then push or create a pull request. Cancel is available at each step."
148
+ data-tooltip="Guided Git workflow:&#10;1. Stage all changes with git add .&#10;2. Generate and preview staged commit messages.&#10;3. Optional: create or type a PR branch before committing.&#10;4. Commit with the short or long message.&#10;5. Push normally, or push the PR branch, generate/review /pr, and create the PR.&#10;Cancel is available at each step."
149
149
  ><svg class="composer-icon composer-icon-github" viewBox="0 0 16 16" aria-hidden="true" focusable="false"><path fill="currentColor" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27s1.36.09 2 .27c1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8Z"/></svg></button>
150
150
  <div class="composer-publish-menu" hidden>
151
151
  <button
@@ -495,6 +495,24 @@
495
495
  </form>
496
496
  </dialog>
497
497
 
498
+ <dialog id="gitChangesDialog" class="extension-dialog git-changes-dialog">
499
+ <form method="dialog">
500
+ <div class="git-changes-header">
501
+ <div>
502
+ <span class="git-changes-kicker">Git diff</span>
503
+ <h2 id="gitChangesTitle">Uncommitted Changes</h2>
504
+ <p id="gitChangesSubtitle" class="muted">Current tab git diff</p>
505
+ </div>
506
+ <button id="gitChangesRefreshButton" type="button">Refresh</button>
507
+ </div>
508
+ <p id="gitChangesStatus" class="git-changes-status muted" role="status" aria-live="polite"></p>
509
+ <div id="gitChangesBody" class="git-changes-body"></div>
510
+ <menu>
511
+ <button id="gitChangesCloseButton" type="button">Close</button>
512
+ </menu>
513
+ </form>
514
+ </dialog>
515
+
498
516
  <dialog id="pathPickerDialog" class="extension-dialog path-picker-dialog">
499
517
  <form method="dialog">
500
518
  <h2 id="pathPickerTitle">Choose working directory</h2>
@@ -598,6 +616,6 @@
598
616
  </form>
599
617
  </dialog>
600
618
 
601
- <script type="module" src="/app.js?v=38"></script>
619
+ <script type="module" src="/app.js?v=43"></script>
602
620
  </body>
603
621
  </html>
@@ -1,4 +1,4 @@
1
- const CACHE_NAME = "pi-webui-pwa-v25";
1
+ const CACHE_NAME = "pi-webui-pwa-v26";
2
2
  const APP_SHELL = [
3
3
  "/",
4
4
  "/index.html",
@@ -37,6 +37,26 @@ self.addEventListener("notificationclick", (event) => {
37
37
  );
38
38
  });
39
39
 
40
+ // Network-first keeps the app shell fresh after deploys regardless of
41
+ // CACHE_NAME or ?v= cache-buster drift; the cache only serves offline clients.
42
+ function fetchThenCache(request) {
43
+ return fetch(request).then((response) => {
44
+ if (response.ok) {
45
+ const copy = response.clone();
46
+ caches.open(CACHE_NAME).then((cache) => cache.put(request, copy));
47
+ }
48
+ return response;
49
+ });
50
+ }
51
+
52
+ // ignoreSearch lets precached bare paths satisfy ?v= cache-busted requests offline.
53
+ function cachedAppShell(request, fallbackPath) {
54
+ return caches.match(request, { ignoreSearch: true }).then((cached) => {
55
+ if (cached || !fallbackPath) return cached;
56
+ return caches.match(fallbackPath, { ignoreSearch: true });
57
+ });
58
+ }
59
+
40
60
  self.addEventListener("fetch", (event) => {
41
61
  const { request } = event;
42
62
  if (request.method !== "GET") return;
@@ -45,16 +65,10 @@ self.addEventListener("fetch", (event) => {
45
65
  if (url.origin !== self.location.origin || url.pathname.startsWith("/api/")) return;
46
66
 
47
67
  if (request.mode === "navigate") {
48
- event.respondWith(fetch(request).catch(() => caches.match("/index.html")));
68
+ event.respondWith(fetchThenCache(request).catch(() => cachedAppShell(request, "/index.html")));
49
69
  return;
50
70
  }
51
71
 
52
72
  if (!APP_SHELL.includes(url.pathname)) return;
53
- event.respondWith(
54
- caches.match(request).then((cached) => cached || fetch(request).then((response) => {
55
- const copy = response.clone();
56
- caches.open(CACHE_NAME).then((cache) => cache.put(request, copy));
57
- return response;
58
- })),
59
- );
73
+ event.respondWith(fetchThenCache(request).catch(() => cachedAppShell(request)));
60
74
  });
package/public/styles.css CHANGED
@@ -1878,6 +1878,7 @@ button.footer-tui-item {
1878
1878
  padding: 0.28rem 0.52rem;
1879
1879
  border-radius: 0.7rem;
1880
1880
  }
1881
+ button.footer-metric,
1881
1882
  button.footer-meta {
1882
1883
  appearance: none;
1883
1884
  color: inherit;
@@ -1885,18 +1886,26 @@ button.footer-meta {
1885
1886
  text-align: left;
1886
1887
  cursor: pointer;
1887
1888
  }
1889
+ .footer-metric-action,
1888
1890
  .footer-meta-action {
1889
1891
  position: relative;
1890
1892
  border-color: rgba(148, 226, 213, 0.26);
1891
1893
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.045), inset 0 0 0 1px rgba(148, 226, 213, 0.055), 0 0.45rem 1rem rgba(0, 0, 0, 0.10);
1892
1894
  transition: border-color 140ms ease, box-shadow 140ms ease, transform 140ms ease;
1893
1895
  }
1896
+ .footer-metric-action:hover,
1897
+ .footer-metric-action:focus-visible,
1894
1898
  .footer-meta-action:hover,
1895
1899
  .footer-meta-action:focus-visible {
1896
1900
  border-color: rgba(166, 227, 161, 0.46);
1897
1901
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.055), 0 0 1rem rgba(166, 227, 161, 0.16);
1898
1902
  outline: none;
1899
1903
  }
1904
+ .footer-metric-action[aria-busy="true"],
1905
+ .footer-meta-action[aria-busy="true"] {
1906
+ cursor: progress;
1907
+ opacity: 0.9;
1908
+ }
1900
1909
  .footer-workspace.footer-meta-action .footer-meta-value {
1901
1910
  color: var(--ctp-green);
1902
1911
  }
@@ -1950,6 +1959,9 @@ button.footer-meta {
1950
1959
  .footer-thinking.footer-meta-action {
1951
1960
  border-color: rgba(203, 166, 247, 0.24);
1952
1961
  }
1962
+ .footer-branch.footer-meta-action {
1963
+ border-color: rgba(245, 194, 231, 0.24);
1964
+ }
1953
1965
  .footer-model-picker {
1954
1966
  position: absolute;
1955
1967
  left: var(--footer-model-picker-left, auto);
@@ -1996,6 +2008,22 @@ button.footer-meta {
1996
2008
  .footer-model-picker-empty strong {
1997
2009
  color: var(--ctp-yellow);
1998
2010
  }
2011
+ .footer-model-picker-empty.error {
2012
+ border-color: rgba(243, 139, 168, 0.24);
2013
+ }
2014
+ .footer-model-picker-empty.error strong {
2015
+ color: var(--ctp-red);
2016
+ }
2017
+ .footer-branch-picker {
2018
+ width: min(28rem, calc(100vw - 2rem));
2019
+ border-color: rgba(245, 194, 231, 0.30);
2020
+ background:
2021
+ radial-gradient(circle at 8% 0%, rgba(245, 194, 231, 0.12), transparent 12rem),
2022
+ linear-gradient(145deg, rgba(var(--ctp-crust-rgb), 0.98), rgba(var(--ctp-base-rgb), 0.96));
2023
+ }
2024
+ .footer-branch-picker .footer-model-picker-title {
2025
+ color: var(--ctp-pink);
2026
+ }
1999
2027
  .footer-model-option {
2000
2028
  display: grid;
2001
2029
  grid-template-columns: minmax(0, 1fr);
@@ -2009,6 +2037,21 @@ button.footer-meta {
2009
2037
  border-color: rgba(166, 227, 161, 0.46);
2010
2038
  box-shadow: inset 3px 0 0 var(--ctp-green), 0 0 1rem rgba(166, 227, 161, 0.14);
2011
2039
  }
2040
+ .footer-branch-option.active {
2041
+ border-color: rgba(245, 194, 231, 0.36);
2042
+ box-shadow: inset 3px 0 0 var(--ctp-pink), 0 0 1rem rgba(245, 194, 231, 0.12);
2043
+ }
2044
+ .footer-branch-option:disabled {
2045
+ cursor: default;
2046
+ opacity: 0.78;
2047
+ }
2048
+ .footer-branch-create-option {
2049
+ border-color: rgba(166, 227, 161, 0.34);
2050
+ box-shadow: inset 3px 0 0 var(--ctp-green), 0 0 1rem rgba(166, 227, 161, 0.10);
2051
+ }
2052
+ .footer-branch-create-option .footer-model-option-main {
2053
+ color: var(--ctp-green);
2054
+ }
2012
2055
  .footer-model-option-main,
2013
2056
  .footer-model-option-name {
2014
2057
  min-width: 0;
@@ -2032,6 +2075,32 @@ button.footer-meta {
2032
2075
  border-color: rgba(249, 226, 175, 0.36);
2033
2076
  background: transparent;
2034
2077
  }
2078
+ .footer-changes-with-files {
2079
+ position: relative;
2080
+ cursor: default;
2081
+ }
2082
+ .footer-changes-with-files:hover,
2083
+ .footer-changes-with-files:focus,
2084
+ .footer-changes-with-files:focus-within {
2085
+ z-index: 50;
2086
+ }
2087
+ .footer-changes-with-files:focus-visible {
2088
+ outline: 1px solid rgba(249, 226, 175, 0.48);
2089
+ outline-offset: 2px;
2090
+ }
2091
+ .footer-changes-with-files::after {
2092
+ content: "";
2093
+ position: absolute;
2094
+ left: 0;
2095
+ right: 0;
2096
+ bottom: 100%;
2097
+ display: none;
2098
+ height: 0.62rem;
2099
+ }
2100
+ .footer-changes-with-files:hover::after,
2101
+ .footer-changes-with-files:focus-within::after {
2102
+ display: block;
2103
+ }
2035
2104
  .footer-changes .footer-meta-label {
2036
2105
  color: rgba(249, 226, 175, 0.88);
2037
2106
  text-shadow: 0 0 0.52rem rgba(249, 226, 175, 0.20);
@@ -2042,6 +2111,82 @@ button.footer-meta {
2042
2111
  letter-spacing: 0.01em;
2043
2112
  text-shadow: 0 0 0.72rem rgba(249, 226, 175, 0.28);
2044
2113
  }
2114
+ .footer-changed-files-popover {
2115
+ position: absolute;
2116
+ left: 0;
2117
+ bottom: calc(100% + 0.48rem);
2118
+ z-index: 60;
2119
+ display: none;
2120
+ gap: 0.44rem;
2121
+ width: min(32rem, calc(100vw - 2rem));
2122
+ max-height: min(42dvh, 28rem);
2123
+ overflow: auto;
2124
+ padding: 0.68rem;
2125
+ border: 1px solid rgba(249, 226, 175, 0.32);
2126
+ border-radius: 0.85rem;
2127
+ background:
2128
+ radial-gradient(circle at 8% 0%, rgba(249, 226, 175, 0.13), transparent 12rem),
2129
+ linear-gradient(145deg, rgba(var(--ctp-crust-rgb), 0.98), rgba(var(--ctp-base-rgb), 0.96));
2130
+ box-shadow: 0 1rem 2.4rem rgba(var(--ctp-crust-rgb), 0.64), 0 0 1.2rem rgba(249, 226, 175, 0.12), inset 0 1px 0 rgba(255,255,255,0.055);
2131
+ }
2132
+ .footer-changes-with-files:hover .footer-changed-files-popover,
2133
+ .footer-changes-with-files:focus .footer-changed-files-popover,
2134
+ .footer-changes-with-files:focus-within .footer-changed-files-popover {
2135
+ display: grid;
2136
+ }
2137
+ .footer-changed-files-title,
2138
+ .footer-changed-files-heading {
2139
+ color: var(--ctp-yellow);
2140
+ font-size: 0.7rem;
2141
+ font-weight: 950;
2142
+ letter-spacing: 0.12em;
2143
+ text-transform: uppercase;
2144
+ }
2145
+ .footer-changed-files-group {
2146
+ display: grid;
2147
+ gap: 0.28rem;
2148
+ }
2149
+ .footer-changed-files-list {
2150
+ display: grid;
2151
+ gap: 0.22rem;
2152
+ }
2153
+ .footer-changed-file {
2154
+ display: grid;
2155
+ grid-template-columns: auto minmax(0, 1fr);
2156
+ align-items: center;
2157
+ gap: 0.42rem;
2158
+ width: 100%;
2159
+ padding: 0.34rem 0.45rem;
2160
+ border: 1px solid rgba(180, 190, 254, 0.15);
2161
+ border-radius: 0.52rem;
2162
+ color: rgba(var(--ctp-text-rgb), 0.92);
2163
+ background: rgba(var(--ctp-crust-rgb), 0.42);
2164
+ font: inherit;
2165
+ text-align: left;
2166
+ cursor: pointer;
2167
+ }
2168
+ .footer-changed-file:hover,
2169
+ .footer-changed-file:focus-visible {
2170
+ border-color: rgba(249, 226, 175, 0.44);
2171
+ background: rgba(249, 226, 175, 0.10);
2172
+ outline: none;
2173
+ }
2174
+ .footer-changed-file-status {
2175
+ color: rgba(var(--ctp-subtext-rgb), 0.72);
2176
+ font-weight: 950;
2177
+ }
2178
+ .footer-changed-file-path {
2179
+ min-width: 0;
2180
+ overflow: hidden;
2181
+ color: rgba(var(--ctp-text-rgb), 0.94);
2182
+ font-weight: 760;
2183
+ text-overflow: ellipsis;
2184
+ white-space: nowrap;
2185
+ }
2186
+ .footer-changed-file.modified .footer-changed-file-status { color: var(--ctp-yellow); }
2187
+ .footer-changed-file.staged .footer-changed-file-status { color: var(--ctp-green); }
2188
+ .footer-changed-file.untracked .footer-changed-file-status { color: var(--ctp-blue); }
2189
+ .footer-changed-file.conflicted .footer-changed-file-status { color: var(--ctp-red); }
2045
2190
  .footer-git-extra {
2046
2191
  border-color: rgba(137, 180, 250, 0.34);
2047
2192
  background: transparent;
@@ -2066,6 +2211,284 @@ button.footer-meta {
2066
2211
  .tone-green .footer-metric-icon { background: linear-gradient(135deg, var(--ctp-green), var(--ctp-teal)); }
2067
2212
  .tone-teal .footer-metric-icon { background: linear-gradient(135deg, var(--ctp-teal), var(--ctp-sky)); }
2068
2213
 
2214
+ .extension-dialog.git-changes-dialog {
2215
+ --git-changes-dialog-size: min(96rem, calc(100vw - 1.5rem), calc(var(--visual-viewport-height, 100dvh) - 1.5rem));
2216
+ width: var(--git-changes-dialog-size);
2217
+ height: var(--git-changes-dialog-size);
2218
+ max-width: var(--git-changes-dialog-size);
2219
+ max-height: var(--git-changes-dialog-size);
2220
+ aspect-ratio: 1 / 1;
2221
+ overflow: hidden;
2222
+ }
2223
+ .git-changes-dialog form {
2224
+ display: grid;
2225
+ grid-template-rows: auto auto minmax(0, 1fr) auto;
2226
+ gap: 0.72rem;
2227
+ height: 100%;
2228
+ min-height: 0;
2229
+ max-height: none;
2230
+ }
2231
+ .git-changes-header {
2232
+ display: flex;
2233
+ align-items: flex-start;
2234
+ justify-content: space-between;
2235
+ gap: 1rem;
2236
+ }
2237
+ .git-changes-header > div:first-child {
2238
+ min-width: 0;
2239
+ }
2240
+ .git-changes-kicker {
2241
+ display: block;
2242
+ color: var(--ctp-yellow);
2243
+ font-size: 0.72rem;
2244
+ font-weight: 950;
2245
+ letter-spacing: 0.16em;
2246
+ text-transform: uppercase;
2247
+ text-shadow: 0 0 0.9rem rgba(249, 226, 175, 0.28);
2248
+ }
2249
+ .git-changes-dialog h2 {
2250
+ margin: 0.1rem 0 0;
2251
+ color: var(--ctp-text);
2252
+ }
2253
+ .git-changes-dialog p {
2254
+ margin: 0.22rem 0 0;
2255
+ }
2256
+ .git-changes-status.error,
2257
+ .git-changes-empty.error {
2258
+ color: var(--ctp-red);
2259
+ }
2260
+ .git-changes-empty.success {
2261
+ color: var(--ctp-green);
2262
+ }
2263
+ .git-changes-body {
2264
+ display: grid;
2265
+ gap: 0.82rem;
2266
+ min-height: min(32rem, 52dvh);
2267
+ overflow: auto;
2268
+ padding: 0.72rem;
2269
+ border: 1px solid rgba(180, 190, 254, 0.18);
2270
+ border-radius: 0.95rem;
2271
+ background:
2272
+ radial-gradient(circle at 12% 0%, rgba(249, 226, 175, 0.08), transparent 20rem),
2273
+ linear-gradient(145deg, rgba(var(--ctp-crust-rgb), 0.72), rgba(var(--ctp-base-rgb), 0.58));
2274
+ box-shadow: inset 0 1px 0 rgba(255,255,255,0.04);
2275
+ }
2276
+ .git-current-file-header {
2277
+ position: sticky;
2278
+ top: -0.72rem;
2279
+ z-index: 8;
2280
+ display: flex;
2281
+ align-items: center;
2282
+ gap: 0.58rem;
2283
+ min-width: 0;
2284
+ margin: 0 -0.72rem;
2285
+ padding: 0.48rem 0.72rem;
2286
+ border-top: 1px solid rgba(180, 190, 254, 0.12);
2287
+ border-bottom: 1px solid rgba(180, 190, 254, 0.18);
2288
+ background: rgba(var(--ctp-crust-rgb), 0.94);
2289
+ box-shadow: 0 0.55rem 1rem rgba(var(--ctp-crust-rgb), 0.36), inset 0 1px 0 rgba(255,255,255,0.04);
2290
+ backdrop-filter: blur(12px) saturate(140%);
2291
+ }
2292
+ .git-current-file-label {
2293
+ flex: 0 0 auto;
2294
+ color: rgba(var(--ctp-subtext-rgb), 0.68);
2295
+ font-size: 0.62rem;
2296
+ font-weight: 950;
2297
+ letter-spacing: 0.12em;
2298
+ text-transform: uppercase;
2299
+ }
2300
+ .git-current-file-name {
2301
+ min-width: 0;
2302
+ overflow: hidden;
2303
+ color: var(--ctp-yellow);
2304
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
2305
+ font-weight: 900;
2306
+ text-overflow: ellipsis;
2307
+ white-space: nowrap;
2308
+ }
2309
+ .git-changes-empty {
2310
+ display: grid;
2311
+ place-items: center;
2312
+ min-height: 10rem;
2313
+ padding: 1rem;
2314
+ color: rgba(var(--ctp-subtext-rgb), 0.76);
2315
+ font-weight: 800;
2316
+ text-align: center;
2317
+ }
2318
+ .git-changes-overview {
2319
+ display: grid;
2320
+ grid-template-columns: repeat(5, minmax(7rem, 1fr));
2321
+ gap: 0.5rem;
2322
+ }
2323
+ .git-changes-chip {
2324
+ min-width: 0;
2325
+ padding: 0.48rem 0.58rem;
2326
+ border: 1px solid rgba(180, 190, 254, 0.18);
2327
+ border-radius: 0.72rem;
2328
+ background: rgba(var(--ctp-crust-rgb), 0.42);
2329
+ }
2330
+ .git-changes-chip.wide {
2331
+ grid-column: span 2;
2332
+ }
2333
+ .git-changes-chip-label {
2334
+ display: block;
2335
+ color: rgba(var(--ctp-subtext-rgb), 0.64);
2336
+ font-size: 0.62rem;
2337
+ font-weight: 950;
2338
+ letter-spacing: 0.12em;
2339
+ text-transform: uppercase;
2340
+ }
2341
+ .git-changes-chip-value {
2342
+ display: block;
2343
+ min-width: 0;
2344
+ overflow: hidden;
2345
+ color: var(--ctp-text);
2346
+ font-weight: 850;
2347
+ text-overflow: ellipsis;
2348
+ white-space: nowrap;
2349
+ }
2350
+ .git-changes-chip.success .git-changes-chip-value { color: var(--ctp-green); }
2351
+ .git-changes-chip.warning .git-changes-chip-value { color: var(--ctp-yellow); }
2352
+ .git-changes-chip.danger .git-changes-chip-value { color: var(--ctp-red); }
2353
+ .git-changes-chip.muted .git-changes-chip-value { color: rgba(var(--ctp-subtext-rgb), 0.76); }
2354
+ .git-diff-section {
2355
+ display: grid;
2356
+ gap: 0.55rem;
2357
+ }
2358
+ .git-diff-section-heading,
2359
+ .git-diff-file-summary {
2360
+ display: flex;
2361
+ align-items: center;
2362
+ justify-content: space-between;
2363
+ gap: 0.75rem;
2364
+ min-width: 0;
2365
+ }
2366
+ .git-diff-section-heading {
2367
+ padding: 0.1rem 0.1rem 0;
2368
+ }
2369
+ .git-diff-section-title {
2370
+ color: var(--ctp-yellow);
2371
+ font-weight: 950;
2372
+ letter-spacing: 0.08em;
2373
+ text-transform: uppercase;
2374
+ }
2375
+ .git-diff-section-meta,
2376
+ .git-diff-file-stats {
2377
+ color: rgba(var(--ctp-subtext-rgb), 0.66);
2378
+ font-size: 0.72rem;
2379
+ font-weight: 760;
2380
+ white-space: nowrap;
2381
+ }
2382
+ .git-diff-file {
2383
+ overflow: hidden;
2384
+ margin: 0;
2385
+ padding: 0;
2386
+ border: 1px solid rgba(180, 190, 254, 0.16);
2387
+ border-radius: 0.78rem;
2388
+ background: rgba(var(--ctp-mantle-rgb), 0.62);
2389
+ }
2390
+ .git-diff-file-summary {
2391
+ cursor: pointer;
2392
+ padding: 0.52rem 0.66rem;
2393
+ color: inherit;
2394
+ border-bottom: 1px solid rgba(180, 190, 254, 0.14);
2395
+ background: rgba(var(--ctp-crust-rgb), 0.42);
2396
+ }
2397
+ .git-untracked-full-file {
2398
+ border-color: rgba(166, 227, 161, 0.22);
2399
+ }
2400
+ .git-untracked-full-file .git-diff-file-summary {
2401
+ background: linear-gradient(90deg, rgba(166, 227, 161, 0.11), rgba(var(--ctp-crust-rgb), 0.44));
2402
+ }
2403
+ .git-diff-file-name {
2404
+ min-width: 0;
2405
+ overflow: hidden;
2406
+ color: var(--ctp-text);
2407
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
2408
+ font-weight: 850;
2409
+ text-overflow: ellipsis;
2410
+ white-space: nowrap;
2411
+ }
2412
+ .git-diff-grid {
2413
+ display: grid;
2414
+ grid-template-columns: 3.8rem minmax(22rem, 1fr) 3.8rem minmax(22rem, 1fr);
2415
+ min-width: 56rem;
2416
+ overflow-x: auto;
2417
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
2418
+ font-size: 0.82rem;
2419
+ line-height: 1.45;
2420
+ }
2421
+ .git-diff-row {
2422
+ display: contents;
2423
+ }
2424
+ .git-diff-line-number,
2425
+ .git-diff-line {
2426
+ min-height: 1.45rem;
2427
+ padding: 0.08rem 0.46rem;
2428
+ border-top: 1px solid rgba(180, 190, 254, 0.055);
2429
+ }
2430
+ .git-diff-line-number {
2431
+ color: rgba(var(--ctp-subtext-rgb), 0.56);
2432
+ background: rgba(var(--ctp-crust-rgb), 0.44);
2433
+ font-variant-numeric: tabular-nums;
2434
+ text-align: right;
2435
+ user-select: none;
2436
+ }
2437
+ .git-diff-line-number.new {
2438
+ border-left: 1px solid rgba(180, 190, 254, 0.24);
2439
+ }
2440
+ .git-diff-line {
2441
+ overflow-wrap: anywhere;
2442
+ white-space: pre-wrap;
2443
+ }
2444
+ .git-diff-row.hunk .git-diff-line,
2445
+ .git-diff-row.hunk .git-diff-line-number,
2446
+ .git-diff-row.meta .git-diff-line,
2447
+ .git-diff-row.meta .git-diff-line-number {
2448
+ color: rgba(var(--ctp-subtext-rgb), 0.78);
2449
+ background: rgba(137, 180, 250, 0.08);
2450
+ }
2451
+ .git-diff-row.removed .git-diff-line.old,
2452
+ .git-diff-row.changed .git-diff-line.old {
2453
+ color: #ffd6dd;
2454
+ background: rgba(243, 139, 168, 0.18);
2455
+ }
2456
+ .git-diff-row.added .git-diff-line.new,
2457
+ .git-diff-row.changed .git-diff-line.new {
2458
+ color: #d8ffd0;
2459
+ background: rgba(166, 227, 161, 0.18);
2460
+ }
2461
+ .git-diff-row.removed .git-diff-line-number.old,
2462
+ .git-diff-row.changed .git-diff-line-number.old {
2463
+ color: var(--ctp-red);
2464
+ background: rgba(243, 139, 168, 0.12);
2465
+ }
2466
+ .git-diff-row.added .git-diff-line-number.new,
2467
+ .git-diff-row.changed .git-diff-line-number.new {
2468
+ color: var(--ctp-green);
2469
+ background: rgba(166, 227, 161, 0.12);
2470
+ }
2471
+ .git-diff-raw {
2472
+ margin: 0;
2473
+ padding: 0.72rem;
2474
+ overflow: auto;
2475
+ color: rgba(var(--ctp-subtext-rgb), 0.82);
2476
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
2477
+ white-space: pre-wrap;
2478
+ }
2479
+ .git-untracked-list {
2480
+ display: grid;
2481
+ gap: 0.35rem;
2482
+ }
2483
+ .git-untracked-file {
2484
+ padding: 0.45rem 0.58rem;
2485
+ border: 1px solid rgba(137, 180, 250, 0.18);
2486
+ border-radius: 0.62rem;
2487
+ background: rgba(var(--ctp-crust-rgb), 0.38);
2488
+ color: var(--ctp-sky);
2489
+ overflow-wrap: anywhere;
2490
+ }
2491
+
2069
2492
  .git-workflow-panel[hidden] { display: none; }
2070
2493
  .git-workflow-panel {
2071
2494
  flex: 0 0 auto;
@@ -6101,6 +6524,37 @@ button.composer-skill-tag:focus-visible {
6101
6524
  background: linear-gradient(180deg, transparent, rgba(var(--ctp-crust-rgb), 0.96) 35%);
6102
6525
  }
6103
6526
  .extension-dialog menu button { flex: 1 1 9rem; }
6527
+ .extension-dialog.git-changes-dialog {
6528
+ inset: 0;
6529
+ margin: auto;
6530
+ border-radius: 1rem;
6531
+ }
6532
+ .git-changes-dialog form {
6533
+ max-height: 100%;
6534
+ }
6535
+ .git-changes-header {
6536
+ flex-direction: column;
6537
+ gap: 0.62rem;
6538
+ }
6539
+ .git-changes-header button {
6540
+ width: 100%;
6541
+ }
6542
+ .git-changes-body {
6543
+ min-height: min(24rem, 54dvh);
6544
+ padding: 0.55rem;
6545
+ }
6546
+ .git-changes-overview {
6547
+ grid-template-columns: repeat(2, minmax(0, 1fr));
6548
+ }
6549
+ .git-changes-chip.wide {
6550
+ grid-column: 1 / -1;
6551
+ }
6552
+ .git-diff-section-heading,
6553
+ .git-diff-file-summary {
6554
+ align-items: flex-start;
6555
+ flex-direction: column;
6556
+ gap: 0.25rem;
6557
+ }
6104
6558
  .composer-row button[data-tooltip]:not(.tooltip-open)::before,
6105
6559
  .composer-row button[data-tooltip]:not(.tooltip-open)::after { display: none; }
6106
6560
  .composer-row button[data-tooltip].tooltip-open::before,
package/start-webui.sh CHANGED
@@ -196,6 +196,8 @@ http_ok() {
196
196
  curl -fsS --max-time 2 "$url" >/dev/null 2>&1
197
197
  elif command -v wget >/dev/null 2>&1; then
198
198
  wget -q --timeout=2 --tries=1 --spider "$url" >/dev/null 2>&1
199
+ elif command -v node >/dev/null 2>&1; then
200
+ node -e 'fetch(process.argv[1], { signal: AbortSignal.timeout(2000) }).then((r) => process.exit(r.ok ? 0 : 1), () => process.exit(1));' "$url" >/dev/null 2>&1
199
201
  else
200
202
  return 1
201
203
  fi
@@ -214,6 +216,8 @@ http_get() {
214
216
  curl -fsS --max-time 5 "$url"
215
217
  elif command -v wget >/dev/null 2>&1; then
216
218
  wget -q --timeout=5 --tries=1 -O - "$url"
219
+ elif command -v node >/dev/null 2>&1; then
220
+ node -e 'fetch(process.argv[1], { signal: AbortSignal.timeout(5000) }).then(async (r) => { if (!r.ok) process.exit(1); process.stdout.write(await r.text()); }, () => process.exit(1));' "$url"
217
221
  else
218
222
  return 1
219
223
  fi
@@ -225,6 +229,8 @@ http_post_json() {
225
229
 
226
230
  if command -v curl >/dev/null 2>&1; then
227
231
  curl -fsS --max-time 10 -X POST "$url" -H "Content-Type: application/json" --data "$body"
232
+ elif command -v node >/dev/null 2>&1; then
233
+ node -e 'fetch(process.argv[1], { method: "POST", headers: { "Content-Type": "application/json" }, body: process.argv[2], signal: AbortSignal.timeout(10000) }).then(async (r) => { if (!r.ok) process.exit(1); process.stdout.write(await r.text()); }, () => process.exit(1));' "$url" "$body"
228
234
  else
229
235
  return 1
230
236
  fi
@@ -336,11 +342,6 @@ wait_until_ready() {
336
342
  local url="$1"
337
343
  local pid="$2"
338
344
 
339
- if ! command -v curl >/dev/null 2>&1 && ! command -v wget >/dev/null 2>&1; then
340
- sleep 1
341
- return 0
342
- fi
343
-
344
345
  for _ in {1..50}; do
345
346
  if ! kill -0 "$pid" 2>/dev/null; then
346
347
  return 2