dsh-ui-tweaks 0.10.1 → 0.10.3
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/LICENSE +21 -21
- package/cordis.patch.yml +12 -12
- package/lib/client.js +239 -118
- package/lib/client.js.map +1 -1
- package/lib/git-web.js +6 -1
- package/lib/git-web.js.map +1 -1
- package/lib/git.js +85 -95
- package/lib/git.js.map +1 -1
- package/lib/types/client/gitbar.d.ts +19 -2
- package/lib/types/client/gitbar.d.ts.map +1 -1
- package/lib/types/client/index.d.ts.map +1 -1
- package/lib/types/git-web.d.ts.map +1 -1
- package/lib/types/git.d.ts +5 -1
- package/lib/types/git.d.ts.map +1 -1
- package/package.json +2 -2
- package/vendor/addon-fit.js +1 -1
- package/vendor/xterm.css +218 -218
- package/vendor/xterm.js +1 -1
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 dsh-ui-tweaks contributors
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 dsh-ui-tweaks contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/cordis.patch.yml
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
# dsh-ui-tweaks bundle patch
|
|
2
|
-
#
|
|
3
|
-
# Declared by `dsh.bundle.patch` in package.json: when the plugin is installed
|
|
4
|
-
# through the official CLI —
|
|
5
|
-
#
|
|
6
|
-
# dsh plugin --profile <name> add dsh-ui-tweaks
|
|
7
|
-
#
|
|
8
|
-
# — the command appends `dsh-ui-tweaks` to the profile's bundle stack and this
|
|
9
|
-
# patch mounts the server-side plugin row.
|
|
10
|
-
- insert:
|
|
11
|
-
- id: ui-tweaks
|
|
12
|
-
name: 'dsh-ui-tweaks'
|
|
1
|
+
# dsh-ui-tweaks bundle patch
|
|
2
|
+
#
|
|
3
|
+
# Declared by `dsh.bundle.patch` in package.json: when the plugin is installed
|
|
4
|
+
# through the official CLI —
|
|
5
|
+
#
|
|
6
|
+
# dsh plugin --profile <name> add dsh-ui-tweaks
|
|
7
|
+
#
|
|
8
|
+
# — the command appends `dsh-ui-tweaks` to the profile's bundle stack and this
|
|
9
|
+
# patch mounts the server-side plugin row.
|
|
10
|
+
- insert:
|
|
11
|
+
- id: ui-tweaks
|
|
12
|
+
name: 'dsh-ui-tweaks'
|
package/lib/client.js
CHANGED
|
@@ -107,27 +107,27 @@ function relativeTime(ms, now, formatter) {
|
|
|
107
107
|
return formatter.format(Math.round(diffSeconds / 86400), 'day');
|
|
108
108
|
return formatter.format(Math.round(diffSeconds / 604800), 'week');
|
|
109
109
|
}
|
|
110
|
-
exports.ARCHIVE_CSS = `
|
|
111
|
-
.dut-arc{display:grid;gap:12px;max-width:680px;padding:6px 2px 36px}
|
|
112
|
-
.dut-arc-head{display:flex;align-items:center;gap:10px;padding:14px 16px 0}
|
|
113
|
-
.dut-arc-head h2{margin:0;font-size:15px;font-weight:600;letter-spacing:-.01em;color:var(--dsw-alias-label-primary)}
|
|
114
|
-
.dut-arc-count{font-size:11.5px;color:var(--dsw-alias-label-secondary);padding:2px 8px;border-radius:999px;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1)}
|
|
115
|
-
.dut-arc-spacer{flex:1}
|
|
116
|
-
.dut-arc-btn{display:inline-flex;align-items:center;height:28px;padding:0 12px;border-radius:999px;border:1px solid var(--dsw-alias-border-l1);background:transparent;color:var(--dsw-alias-label-secondary);font:inherit;font-size:12px;cursor:pointer;transition:background .15s ease,color .15s ease,border-color .15s ease}
|
|
117
|
-
.dut-arc-btn:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}
|
|
118
|
-
.dut-arc-btn:disabled{opacity:.5;cursor:default}
|
|
119
|
-
.dut-arc-btn.dut-arc-del:hover{border-color:color-mix(in srgb,var(--dsw-alias-state-error-primary) 55%,transparent);color:var(--dsw-alias-state-error-primary);background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 10%,transparent)}
|
|
120
|
-
.dut-arc-btn.dut-arc-confirm{border-color:color-mix(in srgb,var(--dsw-alias-state-error-primary) 55%,transparent);color:var(--dsw-alias-state-error-primary);font-weight:600}
|
|
121
|
-
.dut-arc-body{display:grid;gap:2px;margin-top:4px}
|
|
122
|
-
.dut-arc-row{display:flex;align-items:center;gap:8px;padding:10px 16px;border-radius:12px}
|
|
123
|
-
.dut-arc-row:hover{background:var(--dsw-alias-interactive-bg-hover)}
|
|
124
|
-
.dut-arc-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px;text-align:left;background:transparent;border:none;padding:0;cursor:default;color:var(--dsw-alias-label-primary);font:inherit}
|
|
125
|
-
.dut-arc-title{font-size:13.5px;font-weight:600;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}
|
|
126
|
-
.dut-arc-sub{font-size:11.5px;color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;overflow:hidden}
|
|
127
|
-
.dut-arc-empty{padding:32px 16px;text-align:center;font-size:12.5px;color:var(--dsw-alias-label-secondary)}
|
|
128
|
-
.dut-arc-alert{margin:8px 16px 0;padding:8px 12px;border-radius:10px;font-size:12px;line-height:1.5;background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 10%,transparent);color:var(--dsw-alias-state-error-primary)}
|
|
129
|
-
.dut-arc-off{padding:20px 16px;display:grid;gap:12px}
|
|
130
|
-
.dut-arc-off p{margin:0;font-size:12.5px;line-height:1.6;color:var(--dsw-alias-label-secondary)}
|
|
110
|
+
exports.ARCHIVE_CSS = `
|
|
111
|
+
.dut-arc{display:grid;gap:12px;max-width:680px;padding:6px 2px 36px}
|
|
112
|
+
.dut-arc-head{display:flex;align-items:center;gap:10px;padding:14px 16px 0}
|
|
113
|
+
.dut-arc-head h2{margin:0;font-size:15px;font-weight:600;letter-spacing:-.01em;color:var(--dsw-alias-label-primary)}
|
|
114
|
+
.dut-arc-count{font-size:11.5px;color:var(--dsw-alias-label-secondary);padding:2px 8px;border-radius:999px;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1)}
|
|
115
|
+
.dut-arc-spacer{flex:1}
|
|
116
|
+
.dut-arc-btn{display:inline-flex;align-items:center;height:28px;padding:0 12px;border-radius:999px;border:1px solid var(--dsw-alias-border-l1);background:transparent;color:var(--dsw-alias-label-secondary);font:inherit;font-size:12px;cursor:pointer;transition:background .15s ease,color .15s ease,border-color .15s ease}
|
|
117
|
+
.dut-arc-btn:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}
|
|
118
|
+
.dut-arc-btn:disabled{opacity:.5;cursor:default}
|
|
119
|
+
.dut-arc-btn.dut-arc-del:hover{border-color:color-mix(in srgb,var(--dsw-alias-state-error-primary) 55%,transparent);color:var(--dsw-alias-state-error-primary);background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 10%,transparent)}
|
|
120
|
+
.dut-arc-btn.dut-arc-confirm{border-color:color-mix(in srgb,var(--dsw-alias-state-error-primary) 55%,transparent);color:var(--dsw-alias-state-error-primary);font-weight:600}
|
|
121
|
+
.dut-arc-body{display:grid;gap:2px;margin-top:4px}
|
|
122
|
+
.dut-arc-row{display:flex;align-items:center;gap:8px;padding:10px 16px;border-radius:12px}
|
|
123
|
+
.dut-arc-row:hover{background:var(--dsw-alias-interactive-bg-hover)}
|
|
124
|
+
.dut-arc-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px;text-align:left;background:transparent;border:none;padding:0;cursor:default;color:var(--dsw-alias-label-primary);font:inherit}
|
|
125
|
+
.dut-arc-title{font-size:13.5px;font-weight:600;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}
|
|
126
|
+
.dut-arc-sub{font-size:11.5px;color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;overflow:hidden}
|
|
127
|
+
.dut-arc-empty{padding:32px 16px;text-align:center;font-size:12.5px;color:var(--dsw-alias-label-secondary)}
|
|
128
|
+
.dut-arc-alert{margin:8px 16px 0;padding:8px 12px;border-radius:10px;font-size:12px;line-height:1.5;background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 10%,transparent);color:var(--dsw-alias-state-error-primary)}
|
|
129
|
+
.dut-arc-off{padding:20px 16px;display:grid;gap:12px}
|
|
130
|
+
.dut-arc-off p{margin:0;font-size:12.5px;line-height:1.6;color:var(--dsw-alias-label-secondary)}
|
|
131
131
|
`;
|
|
132
132
|
/** Install the Archive stylesheet once (idempotent); returns the disposer. */
|
|
133
133
|
function installArchiveStyles() {
|
|
@@ -224,6 +224,8 @@ __modules["./gitbar.js"] = function(module, exports, require, __load_) {
|
|
|
224
224
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
225
225
|
exports.GITBAR_CSS = void 0;
|
|
226
226
|
exports.installGitBarStyles = installGitBarStyles;
|
|
227
|
+
exports.warmGitStatus = warmGitStatus;
|
|
228
|
+
exports.GitWarmup = GitWarmup;
|
|
227
229
|
exports.BranchChipEntry = BranchChipEntry;
|
|
228
230
|
exports.DiffPanel = DiffPanel;
|
|
229
231
|
exports.TerminalPanel = TerminalPanel;
|
|
@@ -884,6 +886,55 @@ function statusClass(status) {
|
|
|
884
886
|
* panel paint instantly instead of waiting for its own /status round-trip.
|
|
885
887
|
*/
|
|
886
888
|
const snapshotCache = new Map();
|
|
889
|
+
// A localStorage mirror of this cache existed briefly and was retired; sweep
|
|
890
|
+
// away any copy an older build left behind in this browser.
|
|
891
|
+
try {
|
|
892
|
+
window.localStorage.removeItem('dsh-ui-tweaks.git.snapshots.v1');
|
|
893
|
+
}
|
|
894
|
+
catch { /* storage unavailable */ }
|
|
895
|
+
/** In-flight warmups keyed by target, so the dock warmup and a mounting chip
|
|
896
|
+
* never double-fetch the same target. */
|
|
897
|
+
const warmInflight = new Map();
|
|
898
|
+
/**
|
|
899
|
+
* Fetch a target's status into the shared cache WITHOUT rendering anything.
|
|
900
|
+
*
|
|
901
|
+
* The session-header chips mount only after the conversation projection
|
|
902
|
+
* finishes loading — seconds on large inactive sessions — so their own fetch
|
|
903
|
+
* would start just as late. This warmup runs from the input dock, which mounts
|
|
904
|
+
* immediately on session switch: by the time the header chip appears it reads
|
|
905
|
+
* a warm cache and paints folder+branch instantly.
|
|
906
|
+
*/
|
|
907
|
+
function warmGitStatus(target) {
|
|
908
|
+
const key = target.session ?? target.ws ?? '';
|
|
909
|
+
if (key === '' || snapshotCache.has(key) || warmInflight.has(key))
|
|
910
|
+
return;
|
|
911
|
+
const flight = apiGet(`${GIT_ROUTE}/status?${targetQuery(target)}`)
|
|
912
|
+
.then(next => {
|
|
913
|
+
// An unresolved answer (host still starting up) must not poison the
|
|
914
|
+
// cache as a final "not a repo"; the mounting chip re-fetches anyway.
|
|
915
|
+
if (!next.unresolved)
|
|
916
|
+
snapshotCache.set(key, next);
|
|
917
|
+
})
|
|
918
|
+
.catch(() => {
|
|
919
|
+
// Warmup is best-effort; the mounting chip re-fetches anyway.
|
|
920
|
+
})
|
|
921
|
+
.finally(() => { warmInflight.delete(key); });
|
|
922
|
+
warmInflight.set(key, flight);
|
|
923
|
+
}
|
|
924
|
+
/** Input-dock seat for {@link warmGitStatus}: mounts immediately on session
|
|
925
|
+
* switch (long before the session header does) and kicks off the prefetch. */
|
|
926
|
+
function GitWarmup({ sessionId }) {
|
|
927
|
+
(0, react_1.useEffect)(() => {
|
|
928
|
+
warmGitStatus({ session: String(sessionId) });
|
|
929
|
+
}, [sessionId]);
|
|
930
|
+
return null;
|
|
931
|
+
}
|
|
932
|
+
/** Fast retry steps (ms) for the startup race: right after a restart the host
|
|
933
|
+
* has not materialized its session/workspace store yet, so the first /status
|
|
934
|
+
* answers `unresolved`. Without these the UI sat blank for a full POLL_MS. */
|
|
935
|
+
const RETRY_DELAYS_MS = [400, 800, 1600, 3200];
|
|
936
|
+
/** Upper bound on fast retries before falling back to the steady poll. */
|
|
937
|
+
const FAST_RETRY_MAX = 6;
|
|
887
938
|
/** Load the git snapshot on session change, then poll; returns [snapshot, refresh]. */
|
|
888
939
|
function useGitStatus(enabled, target) {
|
|
889
940
|
const key = target.session ?? target.ws ?? '';
|
|
@@ -897,27 +948,63 @@ function useGitStatus(enabled, target) {
|
|
|
897
948
|
// A remount (panel open) must not regress to blank when the cache is warm.
|
|
898
949
|
setSnapshot(snapshotCache.get(key) ?? null);
|
|
899
950
|
let cancelled = false;
|
|
900
|
-
let
|
|
901
|
-
|
|
951
|
+
let pollTimer;
|
|
952
|
+
let retryTimer;
|
|
953
|
+
let attempt = 0;
|
|
954
|
+
// Whether a resolved snapshot exists for this target (cache or fetched).
|
|
955
|
+
// Drives the cold-start chase: fast backoff only while it is false.
|
|
956
|
+
let haveGood = snapshotCache.has(key);
|
|
957
|
+
/** Store one fetch result. An `unresolved` answer is transient — never
|
|
958
|
+
* cached, never regressing an already-good snapshot. Returns whether a
|
|
959
|
+
* resolved answer landed. */
|
|
960
|
+
const apply = (next) => {
|
|
961
|
+
if (next.unresolved === true) {
|
|
962
|
+
if (!cancelled && !haveGood)
|
|
963
|
+
setSnapshot(null);
|
|
964
|
+
return false;
|
|
965
|
+
}
|
|
966
|
+
haveGood = true;
|
|
967
|
+
attempt = 0;
|
|
968
|
+
snapshotCache.set(key, next);
|
|
969
|
+
if (!cancelled)
|
|
970
|
+
setSnapshot(next);
|
|
971
|
+
return true;
|
|
972
|
+
};
|
|
973
|
+
const refreshOnce = async () => {
|
|
902
974
|
try {
|
|
903
|
-
|
|
904
|
-
snapshotCache.set(key, next);
|
|
905
|
-
if (!cancelled)
|
|
906
|
-
setSnapshot(next);
|
|
975
|
+
return apply(await apiGet(`${GIT_ROUTE}/status?${targetQuery(target)}`));
|
|
907
976
|
}
|
|
908
977
|
catch {
|
|
909
|
-
//
|
|
978
|
+
// Transport/transient git failure: chase it too while no good snapshot
|
|
979
|
+
// exists; afterwards keep showing the old one until the next poll.
|
|
980
|
+
return haveGood;
|
|
910
981
|
}
|
|
911
982
|
};
|
|
912
|
-
|
|
913
|
-
|
|
983
|
+
/** Cold-start chase: short backoff instead of idling a whole poll period. */
|
|
984
|
+
const scheduleRetry = () => {
|
|
985
|
+
if (cancelled || haveGood || attempt >= FAST_RETRY_MAX)
|
|
986
|
+
return;
|
|
987
|
+
const delay = RETRY_DELAYS_MS[Math.min(attempt, RETRY_DELAYS_MS.length - 1)] ?? 3200;
|
|
988
|
+
attempt += 1;
|
|
989
|
+
retryTimer = window.setTimeout(() => {
|
|
990
|
+
if (cancelled)
|
|
991
|
+
return;
|
|
992
|
+
void refreshOnce().then(settled => { if (!settled)
|
|
993
|
+
scheduleRetry(); });
|
|
994
|
+
}, delay);
|
|
995
|
+
};
|
|
996
|
+
void refreshOnce().then(settled => { if (!settled)
|
|
997
|
+
scheduleRetry(); });
|
|
998
|
+
pollTimer = window.setInterval(() => {
|
|
914
999
|
if (document.visibilityState === 'visible')
|
|
915
|
-
void
|
|
1000
|
+
void refreshOnce();
|
|
916
1001
|
}, POLL_MS);
|
|
917
1002
|
return () => {
|
|
918
1003
|
cancelled = true;
|
|
919
|
-
if (
|
|
920
|
-
clearInterval(
|
|
1004
|
+
if (pollTimer !== undefined)
|
|
1005
|
+
clearInterval(pollTimer);
|
|
1006
|
+
if (retryTimer !== undefined)
|
|
1007
|
+
clearTimeout(retryTimer);
|
|
921
1008
|
};
|
|
922
1009
|
}, [enabled, key]);
|
|
923
1010
|
const refresh = (0, react_1.useCallback)(async () => {
|
|
@@ -925,8 +1012,12 @@ function useGitStatus(enabled, target) {
|
|
|
925
1012
|
return;
|
|
926
1013
|
try {
|
|
927
1014
|
const next = await apiGet(`${GIT_ROUTE}/status?${targetQuery(target)}`);
|
|
928
|
-
|
|
929
|
-
|
|
1015
|
+
// Same rule as the hook body: an unresolved answer is transient and must
|
|
1016
|
+
// not evict a good snapshot or enter the cache.
|
|
1017
|
+
if (!next.unresolved) {
|
|
1018
|
+
snapshotCache.set(key, next);
|
|
1019
|
+
setSnapshot(next);
|
|
1020
|
+
}
|
|
930
1021
|
}
|
|
931
1022
|
catch {
|
|
932
1023
|
// Keep the previous snapshot on transient failures.
|
|
@@ -934,11 +1025,17 @@ function useGitStatus(enabled, target) {
|
|
|
934
1025
|
}, [target.session, target.ws]);
|
|
935
1026
|
return [snapshot, refresh];
|
|
936
1027
|
}
|
|
937
|
-
function BranchChipEntry({ sessionId, controller, t }) {
|
|
1028
|
+
function BranchChipEntry({ sessionId, sessionsService, controller, t }) {
|
|
938
1029
|
const settingsState = (0, react_1.useSyncExternalStore)(controller.subscribe, controller.getSnapshot, controller.getSnapshot);
|
|
939
1030
|
const enabled = settingsState.value?.gitBarEnabled ?? true;
|
|
940
1031
|
const sessionStr = String(sessionId);
|
|
941
1032
|
const target = { session: sessionStr };
|
|
1033
|
+
// Folder straight off the live sessions list feed (the same rows the left
|
|
1034
|
+
// sidebar shows) — zero network, correct from the very first paint even
|
|
1035
|
+
// before /status answers.
|
|
1036
|
+
const list = sessionsService.list;
|
|
1037
|
+
const subscribeList = (0, react_1.useMemo)(() => list.subscribe.bind(list), [list]);
|
|
1038
|
+
const feedCwd = (0, react_1.useSyncExternalStore)(subscribeList, () => list.getSnapshot().byId[sessionId]?.cwd, () => undefined);
|
|
942
1039
|
const [snapshot, refresh] = useGitStatus(enabled, target);
|
|
943
1040
|
const [branchOpen, setBranchOpen] = (0, react_1.useState)(false);
|
|
944
1041
|
const [branches, setBranches] = (0, react_1.useState)(null);
|
|
@@ -1110,10 +1207,23 @@ function BranchChipEntry({ sessionId, controller, t }) {
|
|
|
1110
1207
|
}, [branchOpen]);
|
|
1111
1208
|
if (!enabled || sessionStr === undefined)
|
|
1112
1209
|
return null;
|
|
1113
|
-
|
|
1210
|
+
// A genuine non-repo directory hides the chip entirely. An UNRESOLVED target
|
|
1211
|
+
// (host still materializing sessions right after a restart) is transient:
|
|
1212
|
+
// fall through to the folder-only paint below instead of going blank.
|
|
1213
|
+
if (snapshot !== null && snapshot.unresolved !== true && !snapshot.isRepo)
|
|
1114
1214
|
return null;
|
|
1215
|
+
// While the first /status round-trip is in flight — or while the host has
|
|
1216
|
+
// not resolved this session yet — paint the folder alone straight off the
|
|
1217
|
+
// sessions-list feed (the sidebar's own rows — zero network, so it appears
|
|
1218
|
+
// the moment the sidebar row does); the branch capsule joins as soon as the
|
|
1219
|
+
// backoff chase lands a real snapshot.
|
|
1220
|
+
if (snapshot === null || snapshot.unresolved === true) {
|
|
1221
|
+
if (feedCwd === undefined || feedCwd === '')
|
|
1222
|
+
return null;
|
|
1223
|
+
return ((0, jsx_runtime_1.jsx)("span", { className: "gbar", "data-slot-plugin": "dsh-ui-tweaks-gitbar", children: (0, jsx_runtime_1.jsxs)("span", { className: "gbar-fchip", title: feedCwd, children: [(0, jsx_runtime_1.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.3", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: (0, jsx_runtime_1.jsx)("path", { d: "M1.5 4A1.5 1.5 0 0 1 3 2.5h3l1.5 2H13A1.5 1.5 0 0 1 14.5 6v6A1.5 1.5 0 0 1 13 13.5H3A1.5 1.5 0 0 1 1.5 12V4Z" }) }), (0, jsx_runtime_1.jsx)("span", { className: "gbar-folder", children: basenameOf(feedCwd) })] }) }));
|
|
1224
|
+
}
|
|
1115
1225
|
const dirty = !snapshot.clean;
|
|
1116
|
-
return ((0, jsx_runtime_1.jsxs)("span", { className: "gbar", "data-slot-plugin": "dsh-ui-tweaks-gitbar", children: [(0, jsx_runtime_1.jsxs)("span", { className: "gbar-fchip", title: snapshot.cwd, children: [(0, jsx_runtime_1.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.3", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: (0, jsx_runtime_1.jsx)("path", { d: "M1.5 4A1.5 1.5 0 0 1 3 2.5h3l1.5 2H13A1.5 1.5 0 0 1 14.5 6v6A1.5 1.5 0 0 1 13 13.5H3A1.5 1.5 0 0 1 1.5 12V4Z" }) }), (0, jsx_runtime_1.jsx)("span", { className: "gbar-folder", children: basenameOf(snapshot.cwd) })] }), (0, jsx_runtime_1.jsxs)("span", { className: "gbar-bwrap", children: [(0, jsx_runtime_1.jsxs)("button", { type: "button", ref: branchRef, className: 'gbar-chip' + (branchOpen ? ' gbar-open' : ''), onClick: toggleBranch, title: dirty ? t('dirty') : t('clean'), "aria-expanded": branchOpen, children: [(0, jsx_runtime_1.jsxs)("svg", { viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.3", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [(0, jsx_runtime_1.jsx)("circle", { cx: "4.5", cy: "3.5", r: "1.8" }), (0, jsx_runtime_1.jsx)("circle", { cx: "4.5", cy: "12.5", r: "1.8" }), (0, jsx_runtime_1.jsx)("circle", { cx: "12", cy: "5.5", r: "1.8" }), (0, jsx_runtime_1.jsx)("path", { d: "M4.5 5.3v5.4" }), (0, jsx_runtime_1.jsx)("path", { d: "M12 7.3c0 3-3.5 4.8-7.5 3.4" })] }), (0, jsx_runtime_1.jsx)("span", { className: "gbar-bname", children: snapshot.branch ?? snapshot.detachedHead ?? '—' })] }), branchOpen ? ((0, jsx_runtime_1.jsxs)("div", { className: "gbar-pop", role: "menu", "aria-label": snapshot.branch ?? 'git', ref: branchPopRef, children: [(0, jsx_runtime_1.jsxs)("div", { className: "gbar-pop-head", children: [(0, jsx_runtime_1.jsxs)("span", { className: "gbar-curname", title: dirty ? t('dirty') : t('clean'), children: [(0, jsx_runtime_1.jsxs)("svg", { className: "gbar-bicon", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.3", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [(0, jsx_runtime_1.jsx)("circle", { cx: "4.5", cy: "3.5", r: "1.8" }), (0, jsx_runtime_1.jsx)("circle", { cx: "4.5", cy: "12.5", r: "1.8" }), (0, jsx_runtime_1.jsx)("circle", { cx: "12", cy: "5.5", r: "1.8" }), (0, jsx_runtime_1.jsx)("path", { d: "M4.5 5.3v5.4" }), (0, jsx_runtime_1.jsx)("path", { d: "M12 7.3c0 3-3.5 4.8-7.5 3.4" })] }), (0, jsx_runtime_1.jsx)("span", { children: snapshot.branch ?? snapshot.detachedHead ?? '—' })] }), (0, jsx_runtime_1.jsxs)("span", { className: "gbar-state", children: [(0, jsx_runtime_1.jsx)("span", { className: 'gbar-dot ' + (dirty ? 'gbar-dirty' : 'gbar-clean'), "aria-hidden": true }), snapshot.ahead > 0 ? (0, jsx_runtime_1.jsxs)("span", { children: ["\u2191", snapshot.ahead] }) : null, snapshot.behind > 0 ? (0, jsx_runtime_1.jsxs)("span", { children: ["\u2193", snapshot.behind] }) : null] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "gbar-pop-body", children: [(0, jsx_runtime_1.jsxs)("div", { className: "gbar-sec", children: [t('branchLocal'), branches !== null ? (0, jsx_runtime_1.jsx)("span", { className: "gbar-count", children: branches.local.length }) : null] }), branches === null ? ((0, jsx_runtime_1.jsxs)("div", { className: "gbar-loading", children: [(0, jsx_runtime_1.jsx)("span", { className: "gbar-spin" }), t('loading')] })) : branches.local.map(name => ((0, jsx_runtime_1.jsxs)("div", { className: "gbar-rowwrap", children: [(0, jsx_runtime_1.jsxs)("button", { type: "button", className: 'gbar-row' + (name === branches.current ? ' gbar-cur' : ''), onClick: () => { pickBranch(name); }, children: [(0, jsx_runtime_1.jsxs)("svg", { className: "gbar-bicon", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.3", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [(0, jsx_runtime_1.jsx)("circle", { cx: "4.5", cy: "3.5", r: "1.8" }), (0, jsx_runtime_1.jsx)("circle", { cx: "4.5", cy: "12.5", r: "1.8" }), (0, jsx_runtime_1.jsx)("path", { d: "M4.5 5.3v5.4" }), (0, jsx_runtime_1.jsx)("path", { d: "M11.5 3.7v3a2.6 2.6 0 0 1-2.6 2.6H4.5" })] }), (0, jsx_runtime_1.jsx)("span", { children: name }), name === branches.current ? (0, jsx_runtime_1.jsx)("span", { className: "gbar-check", "aria-hidden": true, children: "\u2713" }) : null] }), name !== branches.current && !isProtectedBranch(name) ? ((0, jsx_runtime_1.jsx)("button", { type: "button", className: 'gbar-del' + (confirmDelete === name ? ' gbar-arm' : ''), onClick: () => { deleteBranch(name); }, title: t('branchDelete'), children: confirmDelete === name ? t('branchDeleteConfirm') : ((0, jsx_runtime_1.jsxs)("svg", { viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.3", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [(0, jsx_runtime_1.jsx)("path", { d: "M2.5 4.5h11" }), (0, jsx_runtime_1.jsx)("path", { d: "M5.5 4.5V3.3c0-.44.36-.8.8-.8h3.4c.44 0 .8.36.8.8v1.2" }), (0, jsx_runtime_1.jsx)("path", { d: "M4 4.5l.6 8.2c.04.5.45.8.95.8h4.9c.5 0 .91-.3.95-.8l.6-8.2" })] })) })) : null] }, name))), (0, jsx_runtime_1.jsxs)("div", { className: "gbar-sec", children: [t('branchRemote'), branches !== null ? (0, jsx_runtime_1.jsx)("span", { className: "gbar-count", children: branches.remote.length }) : null] }), branches?.remote.map(name => ((0, jsx_runtime_1.jsxs)("div", { className: "gbar-rowwrap", children: [(0, jsx_runtime_1.jsxs)("button", { type: "button", className: 'gbar-row' + (name === branches.current ? ' gbar-cur' : ''), onClick: () => { pickBranch(name); }, children: [(0, jsx_runtime_1.jsx)("svg", { className: "gbar-bicon", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.3", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: (0, jsx_runtime_1.jsx)("path", { d: "M5.2 13a3.2 3.2 0 1 1 .5-6.36 4 4 0 0 1 7.75 1.06 2.65 2.65 0 0 1-.55 5.3H5.2Z" }) }), (0, jsx_runtime_1.jsx)("span", { children: shortBranch(name) }), (0, jsx_runtime_1.jsx)("span", { className: "gbar-rm", children: name.split('/')[0] })] }), !isProtectedBranch(shortBranch(name)) ? ((0, jsx_runtime_1.jsx)("button", { type: "button", className: 'gbar-del' + (confirmDelete === name ? ' gbar-arm' : ''), onClick: () => { deleteRemoteBranch(name); }, title: t('branchRemoteDelete'), children: confirmDelete === name ? t('branchDeleteConfirm') : ((0, jsx_runtime_1.jsxs)("svg", { viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.3", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [(0, jsx_runtime_1.jsx)("path", { d: "M2.5 4.5h11" }), (0, jsx_runtime_1.jsx)("path", { d: "M5.5 4.5V3.3c0-.44.36-.8.8-.8h3.4c.44 0 .8.36.8.8v1.2" }), (0, jsx_runtime_1.jsx)("path", { d: "M4 4.5l.6 8.2c.04.5.45.8.95.8h4.9c.5 0 .91-.3.95-.8l.6-8.2" })] })) })) : null] }, name)))] }), (0, jsx_runtime_1.jsxs)("div", { className: "gbar-actions", children: [(0, jsx_runtime_1.jsxs)("button", { type: "button", className: "gbar-act", onClick: openNewBranch, children: [(0, jsx_runtime_1.jsx)("svg", { viewBox: "0 0 16 16", fill: "currentColor", "aria-hidden": true, children: (0, jsx_runtime_1.jsx)("path", { d: "M7.4 2.6a1.2 1.2 0 1 1 2.2 0l3.2 1.6a1.2 1.2 0 1 1-1.1 2.1l-2.3-1.2a2.6 2.6 0 0 1-1.1.8l.6 4.2a1.2 1.2 0 1 1-1.7.2l-.6-4.2a2.6 2.6 0 0 1-1.2-.7l-2.9 1.5a1.2 1.2 0 1 1-1.1-2.1l2.9-1.5a2.6 2.6 0 0 1 .2-1.5l-3.2-1.6a1.2 1.2 0 1 1 1.1-2.1z" }) }), t('branchNew')] }), (0, jsx_runtime_1.jsxs)("button", { type: "button", className: "gbar-act", onClick: openGraph, children: [(0, jsx_runtime_1.jsxs)("svg", { viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", "aria-hidden": true, children: [(0, jsx_runtime_1.jsx)("path", { d: "M3 1.5v3.4a4.4 4.4 0 0 0 4.4 4.4h5.1" }), (0, jsx_runtime_1.jsx)("path", { d: "M13 1.5v4.9a3.2 3.2 0 0 1-3.2 3.2H3" }), (0, jsx_runtime_1.jsx)("circle", { cx: "3", cy: "1.5", r: "1.2", fill: "currentColor", stroke: "none" }), (0, jsx_runtime_1.jsx)("circle", { cx: "13", cy: "12", r: "1.2", fill: "currentColor", stroke: "none" })] }), t('branchGraph')] })] })] })) : null] }), newBranchOpen ? (0, react_dom_1.createPortal)((0, jsx_runtime_1.jsx)("div", { className: "gbar-modal-wrap", onMouseDown: event => { if (event.target === event.currentTarget)
|
|
1226
|
+
return ((0, jsx_runtime_1.jsxs)("span", { className: "gbar", "data-slot-plugin": "dsh-ui-tweaks-gitbar", children: [(0, jsx_runtime_1.jsxs)("span", { className: "gbar-fchip", title: feedCwd ?? snapshot.cwd, children: [(0, jsx_runtime_1.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.3", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: (0, jsx_runtime_1.jsx)("path", { d: "M1.5 4A1.5 1.5 0 0 1 3 2.5h3l1.5 2H13A1.5 1.5 0 0 1 14.5 6v6A1.5 1.5 0 0 1 13 13.5H3A1.5 1.5 0 0 1 1.5 12V4Z" }) }), (0, jsx_runtime_1.jsx)("span", { className: "gbar-folder", children: basenameOf(feedCwd ?? snapshot.cwd) })] }), (0, jsx_runtime_1.jsxs)("span", { className: "gbar-bwrap", children: [(0, jsx_runtime_1.jsxs)("button", { type: "button", ref: branchRef, className: 'gbar-chip' + (branchOpen ? ' gbar-open' : ''), onClick: toggleBranch, title: dirty ? t('dirty') : t('clean'), "aria-expanded": branchOpen, children: [(0, jsx_runtime_1.jsxs)("svg", { viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.3", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [(0, jsx_runtime_1.jsx)("circle", { cx: "4.5", cy: "3.5", r: "1.8" }), (0, jsx_runtime_1.jsx)("circle", { cx: "4.5", cy: "12.5", r: "1.8" }), (0, jsx_runtime_1.jsx)("circle", { cx: "12", cy: "5.5", r: "1.8" }), (0, jsx_runtime_1.jsx)("path", { d: "M4.5 5.3v5.4" }), (0, jsx_runtime_1.jsx)("path", { d: "M12 7.3c0 3-3.5 4.8-7.5 3.4" })] }), (0, jsx_runtime_1.jsx)("span", { className: "gbar-bname", children: snapshot.branch ?? snapshot.detachedHead ?? '—' })] }), branchOpen ? ((0, jsx_runtime_1.jsxs)("div", { className: "gbar-pop", role: "menu", "aria-label": snapshot.branch ?? 'git', ref: branchPopRef, children: [(0, jsx_runtime_1.jsxs)("div", { className: "gbar-pop-head", children: [(0, jsx_runtime_1.jsxs)("span", { className: "gbar-curname", title: dirty ? t('dirty') : t('clean'), children: [(0, jsx_runtime_1.jsxs)("svg", { className: "gbar-bicon", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.3", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [(0, jsx_runtime_1.jsx)("circle", { cx: "4.5", cy: "3.5", r: "1.8" }), (0, jsx_runtime_1.jsx)("circle", { cx: "4.5", cy: "12.5", r: "1.8" }), (0, jsx_runtime_1.jsx)("circle", { cx: "12", cy: "5.5", r: "1.8" }), (0, jsx_runtime_1.jsx)("path", { d: "M4.5 5.3v5.4" }), (0, jsx_runtime_1.jsx)("path", { d: "M12 7.3c0 3-3.5 4.8-7.5 3.4" })] }), (0, jsx_runtime_1.jsx)("span", { children: snapshot.branch ?? snapshot.detachedHead ?? '—' })] }), (0, jsx_runtime_1.jsxs)("span", { className: "gbar-state", children: [(0, jsx_runtime_1.jsx)("span", { className: 'gbar-dot ' + (dirty ? 'gbar-dirty' : 'gbar-clean'), "aria-hidden": true }), snapshot.ahead > 0 ? (0, jsx_runtime_1.jsxs)("span", { children: ["\u2191", snapshot.ahead] }) : null, snapshot.behind > 0 ? (0, jsx_runtime_1.jsxs)("span", { children: ["\u2193", snapshot.behind] }) : null] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "gbar-pop-body", children: [(0, jsx_runtime_1.jsxs)("div", { className: "gbar-sec", children: [t('branchLocal'), branches !== null ? (0, jsx_runtime_1.jsx)("span", { className: "gbar-count", children: branches.local.length }) : null] }), branches === null ? ((0, jsx_runtime_1.jsxs)("div", { className: "gbar-loading", children: [(0, jsx_runtime_1.jsx)("span", { className: "gbar-spin" }), t('loading')] })) : branches.local.map(name => ((0, jsx_runtime_1.jsxs)("div", { className: "gbar-rowwrap", children: [(0, jsx_runtime_1.jsxs)("button", { type: "button", className: 'gbar-row' + (name === branches.current ? ' gbar-cur' : ''), onClick: () => { pickBranch(name); }, children: [(0, jsx_runtime_1.jsxs)("svg", { className: "gbar-bicon", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.3", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [(0, jsx_runtime_1.jsx)("circle", { cx: "4.5", cy: "3.5", r: "1.8" }), (0, jsx_runtime_1.jsx)("circle", { cx: "4.5", cy: "12.5", r: "1.8" }), (0, jsx_runtime_1.jsx)("path", { d: "M4.5 5.3v5.4" }), (0, jsx_runtime_1.jsx)("path", { d: "M11.5 3.7v3a2.6 2.6 0 0 1-2.6 2.6H4.5" })] }), (0, jsx_runtime_1.jsx)("span", { children: name }), name === branches.current ? (0, jsx_runtime_1.jsx)("span", { className: "gbar-check", "aria-hidden": true, children: "\u2713" }) : null] }), name !== branches.current && !isProtectedBranch(name) ? ((0, jsx_runtime_1.jsx)("button", { type: "button", className: 'gbar-del' + (confirmDelete === name ? ' gbar-arm' : ''), onClick: () => { deleteBranch(name); }, title: t('branchDelete'), children: confirmDelete === name ? t('branchDeleteConfirm') : ((0, jsx_runtime_1.jsxs)("svg", { viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.3", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [(0, jsx_runtime_1.jsx)("path", { d: "M2.5 4.5h11" }), (0, jsx_runtime_1.jsx)("path", { d: "M5.5 4.5V3.3c0-.44.36-.8.8-.8h3.4c.44 0 .8.36.8.8v1.2" }), (0, jsx_runtime_1.jsx)("path", { d: "M4 4.5l.6 8.2c.04.5.45.8.95.8h4.9c.5 0 .91-.3.95-.8l.6-8.2" })] })) })) : null] }, name))), (0, jsx_runtime_1.jsxs)("div", { className: "gbar-sec", children: [t('branchRemote'), branches !== null ? (0, jsx_runtime_1.jsx)("span", { className: "gbar-count", children: branches.remote.length }) : null] }), branches?.remote.map(name => ((0, jsx_runtime_1.jsxs)("div", { className: "gbar-rowwrap", children: [(0, jsx_runtime_1.jsxs)("button", { type: "button", className: 'gbar-row' + (name === branches.current ? ' gbar-cur' : ''), onClick: () => { pickBranch(name); }, children: [(0, jsx_runtime_1.jsx)("svg", { className: "gbar-bicon", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.3", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: (0, jsx_runtime_1.jsx)("path", { d: "M5.2 13a3.2 3.2 0 1 1 .5-6.36 4 4 0 0 1 7.75 1.06 2.65 2.65 0 0 1-.55 5.3H5.2Z" }) }), (0, jsx_runtime_1.jsx)("span", { children: shortBranch(name) }), (0, jsx_runtime_1.jsx)("span", { className: "gbar-rm", children: name.split('/')[0] })] }), !isProtectedBranch(shortBranch(name)) ? ((0, jsx_runtime_1.jsx)("button", { type: "button", className: 'gbar-del' + (confirmDelete === name ? ' gbar-arm' : ''), onClick: () => { deleteRemoteBranch(name); }, title: t('branchRemoteDelete'), children: confirmDelete === name ? t('branchDeleteConfirm') : ((0, jsx_runtime_1.jsxs)("svg", { viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.3", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [(0, jsx_runtime_1.jsx)("path", { d: "M2.5 4.5h11" }), (0, jsx_runtime_1.jsx)("path", { d: "M5.5 4.5V3.3c0-.44.36-.8.8-.8h3.4c.44 0 .8.36.8.8v1.2" }), (0, jsx_runtime_1.jsx)("path", { d: "M4 4.5l.6 8.2c.04.5.45.8.95.8h4.9c.5 0 .91-.3.95-.8l.6-8.2" })] })) })) : null] }, name)))] }), (0, jsx_runtime_1.jsxs)("div", { className: "gbar-actions", children: [(0, jsx_runtime_1.jsxs)("button", { type: "button", className: "gbar-act", onClick: openNewBranch, children: [(0, jsx_runtime_1.jsx)("svg", { viewBox: "0 0 16 16", fill: "currentColor", "aria-hidden": true, children: (0, jsx_runtime_1.jsx)("path", { d: "M7.4 2.6a1.2 1.2 0 1 1 2.2 0l3.2 1.6a1.2 1.2 0 1 1-1.1 2.1l-2.3-1.2a2.6 2.6 0 0 1-1.1.8l.6 4.2a1.2 1.2 0 1 1-1.7.2l-.6-4.2a2.6 2.6 0 0 1-1.2-.7l-2.9 1.5a1.2 1.2 0 1 1-1.1-2.1l2.9-1.5a2.6 2.6 0 0 1 .2-1.5l-3.2-1.6a1.2 1.2 0 1 1 1.1-2.1z" }) }), t('branchNew')] }), (0, jsx_runtime_1.jsxs)("button", { type: "button", className: "gbar-act", onClick: openGraph, children: [(0, jsx_runtime_1.jsxs)("svg", { viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", "aria-hidden": true, children: [(0, jsx_runtime_1.jsx)("path", { d: "M3 1.5v3.4a4.4 4.4 0 0 0 4.4 4.4h5.1" }), (0, jsx_runtime_1.jsx)("path", { d: "M13 1.5v4.9a3.2 3.2 0 0 1-3.2 3.2H3" }), (0, jsx_runtime_1.jsx)("circle", { cx: "3", cy: "1.5", r: "1.2", fill: "currentColor", stroke: "none" }), (0, jsx_runtime_1.jsx)("circle", { cx: "13", cy: "12", r: "1.2", fill: "currentColor", stroke: "none" })] }), t('branchGraph')] })] })] })) : null] }), newBranchOpen ? (0, react_dom_1.createPortal)((0, jsx_runtime_1.jsx)("div", { className: "gbar-modal-wrap", onMouseDown: event => { if (event.target === event.currentTarget)
|
|
1117
1227
|
setNewBranchOpen(false); }, children: (0, jsx_runtime_1.jsxs)("div", { className: "gbar-modal", role: "dialog", "aria-label": t('branchNew'), children: [(0, jsx_runtime_1.jsxs)("div", { className: "gbar-head", children: [(0, jsx_runtime_1.jsx)("span", { className: "gbar-title", children: t('branchNew') }), (0, jsx_runtime_1.jsx)("span", { className: "gbar-branch", children: snapshot.branch ?? snapshot.detachedHead ?? '—' }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: "gbar-x", onClick: () => { setNewBranchOpen(false); }, "aria-label": "\u2715", children: "\u2715" })] }), (0, jsx_runtime_1.jsx)("input", { value: newBranchName, onChange: event => { setNewBranchName(event.target.value); }, onKeyDown: event => { if (event.key === 'Enter')
|
|
1118
1228
|
createBranch(); }, placeholder: t('branchNewPlaceholder'), "aria-label": t('branchNew'), autoFocus: true }), (0, jsx_runtime_1.jsxs)("div", { className: "gbar-baserow", children: [(0, jsx_runtime_1.jsx)("label", { className: "gbar-baselabel", htmlFor: "gbar-base-dlg", children: t('branchFrom') }), (0, jsx_runtime_1.jsxs)("select", { id: "gbar-base-dlg", className: "gbar-base", value: baseBranch, onChange: event => { setBaseBranch(event.target.value); }, "aria-label": t('branchFrom'), children: [(0, jsx_runtime_1.jsx)("option", { value: "", children: t('branchFromHead') }), branches?.local.map(name => (0, jsx_runtime_1.jsx)("option", { value: name, children: name }, name)), branches?.remote.map(name => (0, jsx_runtime_1.jsx)("option", { value: name, children: name }, name))] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "gbar-pushrow", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", className: 'gbar-chk' + (pushToRemote ? '' : ' gbar-off'), onClick: () => { setPushToRemote(value => !value); }, "aria-label": t('branchPushRemote'), children: pushToRemote ? '✓' : '✕' }), (0, jsx_runtime_1.jsx)("span", { className: "gbar-pushlabel", children: t('branchPushRemote') })] }), (0, jsx_runtime_1.jsxs)("div", { className: "gbar-foot", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", className: "gbar-btn gbar-ghost", onClick: () => { setNewBranchOpen(false); }, children: t('branchCancel') }), (0, jsx_runtime_1.jsxs)("button", { type: "button", className: "gbar-btn gbar-primary", onClick: createBranch, disabled: busy !== null || newBranchName.trim() === '', children: [busy === 'create' || busy === 'create-push' ? (0, jsx_runtime_1.jsx)("span", { className: "gbar-spin" }) : null, " ", t('branchCreate')] })] })] }) }), document.body) : null, graphOpen ? (0, react_dom_1.createPortal)((0, jsx_runtime_1.jsx)("div", { className: "gbar-modal-wrap", onMouseDown: event => { if (event.target === event.currentTarget)
|
|
1119
1229
|
setGraphOpen(false); }, children: (0, jsx_runtime_1.jsxs)("div", { className: "gbar-modal gbar-graph-modal", role: "dialog", "aria-label": t('graphTitle'), children: [(0, jsx_runtime_1.jsxs)("div", { className: "gbar-head", children: [(0, jsx_runtime_1.jsx)("span", { className: "gbar-title", children: t('graphTitle') }), (0, jsx_runtime_1.jsx)("span", { className: "gbar-branch", children: snapshot.branch ?? snapshot.detachedHead ?? '—' }), (0, jsx_runtime_1.jsx)("span", { className: "gbar-spacer" }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: "gbar-x gbar-refresh", onClick: fetchGraph, "aria-label": t('branchRefresh'), title: t('branchRefresh'), disabled: graphBusy, children: graphBusy ? (0, jsx_runtime_1.jsx)("span", { className: "gbar-spin" }) : ((0, jsx_runtime_1.jsxs)("svg", { viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [(0, jsx_runtime_1.jsx)("path", { d: "M13.4 8a5.4 5.4 0 1 1-1.6-3.8" }), (0, jsx_runtime_1.jsx)("path", { d: "M13.4 1.5v3h-3" })] })) }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: "gbar-x", onClick: () => { setGraphOpen(false); }, "aria-label": "\u2715", children: "\u2715" })] }), graph === null ? ((0, jsx_runtime_1.jsx)("div", { className: "gbar-graph-empty", children: graphBusy ? t('loading') : t('noChanges') })) : graph.commits.length === 0 ? ((0, jsx_runtime_1.jsx)("div", { className: "gbar-graph-empty", children: t('noChanges') })) : ((0, jsx_runtime_1.jsxs)("div", { className: "gbar-graph-table", role: "table", "aria-label": t('graphTitle'), children: [(0, jsx_runtime_1.jsxs)("div", { className: "gbar-graph-row gbar-graph-head", role: "row", children: [(0, jsx_runtime_1.jsx)("span", { className: "gbar-c-hash", role: "columnheader", children: t('graphColCommit') }), (0, jsx_runtime_1.jsx)("span", { className: "gbar-c-subject", role: "columnheader", children: t('graphColSubject') }), (0, jsx_runtime_1.jsx)("span", { className: "gbar-c-author", role: "columnheader", children: t('graphColAuthor') }), (0, jsx_runtime_1.jsx)("span", { className: "gbar-c-date", role: "columnheader", children: t('graphColDate') })] }), graph.commits.map(commit => ((0, jsx_runtime_1.jsxs)("div", { className: "gbar-graph-row", role: "row", children: [(0, jsx_runtime_1.jsx)("span", { className: "gbar-c-hash", role: "cell", children: (0, jsx_runtime_1.jsx)("code", { className: "gbar-hash", children: commit.hash }) }), (0, jsx_runtime_1.jsxs)("span", { className: "gbar-c-subject", role: "cell", children: [(0, jsx_runtime_1.jsx)("span", { className: "gbar-subject", children: commit.subject }), commit.refs !== '' ? (0, jsx_runtime_1.jsx)("span", { className: "gbar-refs", children: commit.refs }) : null] }), (0, jsx_runtime_1.jsx)("span", { className: "gbar-c-author", role: "cell", children: commit.author }), (0, jsx_runtime_1.jsx)("span", { className: "gbar-c-date", role: "cell", title: commit.date, children: commit.dateRelative })] }, commit.fullHash)))] }))] }) }), document.body) : null, notice !== null ? (0, react_dom_1.createPortal)((0, jsx_runtime_1.jsx)("div", { className: 'gbar-notice gbar-' + notice.kind, role: "status", children: notice.text }), document.body) : null] }));
|
|
@@ -3026,8 +3136,19 @@ function apply(ctx) {
|
|
|
3026
3136
|
id: 'gitbar-branch',
|
|
3027
3137
|
order: 10,
|
|
3028
3138
|
locale: NS,
|
|
3029
|
-
inject: () => ({ controller }),
|
|
3139
|
+
inject: () => ({ controller, sessionsService: ctx.sessions }),
|
|
3030
3140
|
}, gitbar_tsx_1.BranchChipEntry));
|
|
3141
|
+
// Warmup: the header chips mount only after the conversation projection
|
|
3142
|
+
// finishes loading (seconds on large inactive sessions). The input dock
|
|
3143
|
+
// mounts immediately on session switch, so a null-rendering seat there
|
|
3144
|
+
// prefetches the status into the shared cache right away — the chips then
|
|
3145
|
+
// paint folder+branch from the warm cache the moment they appear.
|
|
3146
|
+
ctx.slots.inject('conversation.input.dock', () => ctx.slots.register({
|
|
3147
|
+
name: 'conversation.input.dock',
|
|
3148
|
+
id: 'gitbar-warmup',
|
|
3149
|
+
order: 41,
|
|
3150
|
+
inject: () => ({}),
|
|
3151
|
+
}, gitbar_tsx_1.GitWarmup));
|
|
3031
3152
|
ctx.slots.inject('conversation.session.header.utilities', () => ctx.slots.register({
|
|
3032
3153
|
name: 'conversation.session.header.utilities',
|
|
3033
3154
|
id: 'gitbar-utils',
|
|
@@ -3230,63 +3351,63 @@ function linesToRecord(text, separator) {
|
|
|
3230
3351
|
function recordToLines(record, separator) {
|
|
3231
3352
|
return Object.entries(record).map(([key, value]) => `${key}${separator}${value}`).join('\n');
|
|
3232
3353
|
}
|
|
3233
|
-
exports.MCP_CSS = `
|
|
3234
|
-
.dut-mcp{display:grid;gap:12px;max-width:680px;padding:6px 2px 36px}
|
|
3235
|
-
.dut-mcp-head{display:flex;align-items:center;gap:10px;padding:14px 16px 0}
|
|
3236
|
-
.dut-mcp-head h2{margin:0;font-size:15px;font-weight:600;letter-spacing:-.01em;color:var(--dsw-alias-label-primary)}
|
|
3237
|
-
.dut-mcp-count{font-size:11.5px;color:var(--dsw-alias-label-secondary);padding:2px 8px;border-radius:999px;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1)}
|
|
3238
|
-
.dut-mcp-spacer{flex:1}
|
|
3239
|
-
.dut-mcp-btn{display:inline-flex;align-items:center;height:28px;padding:0 12px;border-radius:999px;border:1px solid var(--dsw-alias-border-l1);background:transparent;color:var(--dsw-alias-label-secondary);font:inherit;font-size:12px;cursor:pointer;transition:background .15s ease,color .15s ease,border-color .15s ease}
|
|
3240
|
-
.dut-mcp-btn:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}
|
|
3241
|
-
.dut-mcp-btn:disabled{opacity:.5;cursor:default}
|
|
3242
|
-
.dut-mcp-btn.dut-mcp-del:hover{border-color:color-mix(in srgb,var(--dsw-alias-state-error-primary) 55%,transparent);color:var(--dsw-alias-state-error-primary);background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 10%,transparent)}
|
|
3243
|
-
.dut-mcp-btn.dut-mcp-confirm{border-color:color-mix(in srgb,var(--dsw-alias-state-error-primary) 55%,transparent);color:var(--dsw-alias-state-error-primary);font-weight:600}
|
|
3244
|
-
.dut-mcp-body{display:grid;gap:2px;margin-top:4px}
|
|
3245
|
-
.dut-mcp-row{display:grid;gap:6px;padding:10px 16px;border-radius:12px}
|
|
3246
|
-
.dut-mcp-row:hover{background:var(--dsw-alias-interactive-bg-hover)}
|
|
3247
|
-
.dut-mcp-row-main{display:flex;align-items:center;gap:8px;min-width:0}
|
|
3248
|
-
.dut-mcp-name{font-size:13.5px;font-weight:600;color:var(--dsw-alias-label-primary);white-space:nowrap;text-overflow:ellipsis;overflow:hidden}
|
|
3249
|
-
.dut-mcp-badge{flex:none;font-size:11px;line-height:1;padding:4px 9px;border-radius:999px;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-secondary)}
|
|
3250
|
-
.dut-mcp-badge.dut-mcp-ok{background:color-mix(in srgb,var(--dsw-alias-state-success-primary) 12%,transparent);border-color:transparent;color:var(--dsw-alias-state-success-primary)}
|
|
3251
|
-
.dut-mcp-badge.dut-mcp-err{background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 12%,transparent);border-color:transparent;color:var(--dsw-alias-state-error-primary)}
|
|
3252
|
-
.dut-mcp-badge.dut-mcp-warn{background:color-mix(in srgb,var(--dsw-alias-state-warn-primary) 14%,transparent);border-color:transparent;color:var(--dsw-alias-state-warn-label)}
|
|
3253
|
-
.dut-mcp-sub{font-size:11.5px;color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;overflow:hidden}
|
|
3254
|
-
.dut-mcp-toggle{flex:none;font-size:11.5px;color:var(--dsw-alias-label-tertiary);background:transparent;border:none;padding:0;cursor:pointer;text-align:left}
|
|
3255
|
-
.dut-mcp-toggle:hover{color:var(--dsw-alias-label-primary)}
|
|
3256
|
-
.dut-mcp-tools{margin-left:2px;display:flex;flex-wrap:wrap;gap:4px}
|
|
3257
|
-
.dut-mcp-tool{font-size:11px;line-height:1;padding:3px 8px;border-radius:999px;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-secondary)}
|
|
3258
|
-
.dut-mcp-note{margin:2px 16px 0;padding:8px 12px;border-radius:10px;font-size:11.5px;line-height:1.55;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1)}
|
|
3259
|
-
.dut-mcp-empty{padding:32px 16px;text-align:center;font-size:12.5px;color:var(--dsw-alias-label-secondary)}
|
|
3260
|
-
.dut-mcp-alert{margin:8px 16px 0;padding:8px 12px;border-radius:10px;font-size:12px;line-height:1.5;background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 10%,transparent);color:var(--dsw-alias-state-error-primary)}
|
|
3261
|
-
.dut-mcp-notice{margin:8px 16px 0;padding:8px 12px;border-radius:10px;font-size:12px;line-height:1.5;background:color-mix(in srgb,var(--dsw-alias-state-success-primary) 12%,transparent);color:var(--dsw-alias-state-success-primary)}
|
|
3262
|
-
.dut-mcp-off{padding:20px 16px;display:grid;gap:12px}
|
|
3263
|
-
.dut-mcp-off p{margin:0;font-size:12.5px;line-height:1.6;color:var(--dsw-alias-label-secondary)}
|
|
3264
|
-
.dut-mcp-overlay{z-index:1100;justify-content:center;align-items:center;display:flex;position:fixed;inset:0}
|
|
3265
|
-
.dut-mcp-mask{background:var(--dsw-alias-bg-mask-1);backdrop-filter:var(--dsw-mask-blur);position:absolute;inset:0}
|
|
3266
|
-
.dut-mcp-panel{z-index:1;background:var(--dsw-alias-bg-layer-2);box-sizing:border-box;width:720px;max-width:calc(100vw - 48px);height:min(700px,100vh - 48px);box-shadow:var(--dsw-shadow-lv3);--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);border-radius:20px;display:flex;flex-direction:column;overflow:hidden}
|
|
3267
|
-
.dut-mcp-panel-head{box-sizing:border-box;flex:none;display:flex;align-items:center;gap:10px;height:52px;padding:0 12px 0 20px}
|
|
3268
|
-
.dut-mcp-panel-head h2{margin:0;font-size:16px;font-weight:600;letter-spacing:-.01em;color:var(--dsw-alias-label-primary)}
|
|
3269
|
-
.dut-mcp-panel-close{cursor:pointer;width:28px;height:28px;color:var(--dsw-alias-label-primary);background:transparent;border:none;border-radius:28px;display:inline-flex;justify-content:center;align-items:center;padding:0;font-size:13px}
|
|
3270
|
-
.dut-mcp-panel-close:hover{background:var(--dsw-alias-interactive-bg-hover)}
|
|
3271
|
-
.dut-mcp-tabs{flex:none;display:inline-flex;padding:3px;gap:3px;border:1px solid var(--dsw-alias-border-l1);border-radius:10px;background:var(--dsw-alias-bg-layer-2);margin:0 20px 10px;align-self:flex-start}
|
|
3272
|
-
.dut-mcp-tabs button{border:none;border-radius:7px;padding:5px 14px;background:transparent;color:var(--dsw-alias-label-secondary);font:inherit;font-size:12.5px;cursor:pointer}
|
|
3273
|
-
.dut-mcp-tabs button.dut-mcp-tab-on{background:color-mix(in srgb,var(--dsw-alias-state-business-primary) 12%,transparent);color:var(--dsw-alias-state-business-primary);font-weight:600}
|
|
3274
|
-
.dut-mcp-form{flex:1;min-height:0;overflow-y:auto;padding:0 20px 20px;display:grid;gap:12px;align-content:start}
|
|
3275
|
-
.dut-mcp-field{display:grid;gap:6px}
|
|
3276
|
-
.dut-mcp-field>span{font-size:12px;font-weight:600;color:var(--dsw-alias-label-primary)}
|
|
3277
|
-
.dut-mcp-field small{font-size:11px;line-height:1.5;color:var(--dsw-alias-label-tertiary)}
|
|
3278
|
-
.dut-mcp-input{box-sizing:border-box;width:100%;height:34px;padding:0 10px;border-radius:9px;border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);font:inherit;font-size:13px}
|
|
3279
|
-
.dut-mcp-input:focus{outline:none;border-color:color-mix(in srgb,var(--dsw-alias-state-business-primary) 55%,transparent)}
|
|
3280
|
-
.dut-mcp-input:disabled{opacity:.55;cursor:not-allowed}
|
|
3281
|
-
textarea.dut-mcp-input{height:auto;min-height:72px;padding:8px 10px;line-height:1.5;resize:vertical;font-family:var(--dsw-font-markdown-code-block-font-family, Consolas, monospace);font-size:12px}
|
|
3282
|
-
textarea.dut-mcp-input-lg{min-height:120px}
|
|
3283
|
-
textarea.dut-mcp-yaml{min-height:320px}
|
|
3284
|
-
.dut-mcp-row2{display:grid;grid-template-columns:1fr 1fr;gap:12px;align-items:start}
|
|
3285
|
-
.dut-mcp-field .dut-seg{width:fit-content}
|
|
3286
|
-
.dut-mcp-row2 .dut-seg{height:34px;box-sizing:border-box;align-items:center}
|
|
3287
|
-
.dut-mcp-row2 .dut-seg button{flex:none;white-space:nowrap;padding:0 16px;height:26px}
|
|
3288
|
-
.dut-mcp-foot{flex:none;display:flex;align-items:center;gap:8px;justify-content:flex-end;padding:12px 20px 16px;border-top:1px solid var(--dsw-alias-border-l1)}
|
|
3289
|
-
.dut-mcp-error{margin:0 20px 10px;padding:8px 12px;border-radius:10px;font-size:12px;line-height:1.5;background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 10%,transparent);color:var(--dsw-alias-state-error-primary)}
|
|
3354
|
+
exports.MCP_CSS = `
|
|
3355
|
+
.dut-mcp{display:grid;gap:12px;max-width:680px;padding:6px 2px 36px}
|
|
3356
|
+
.dut-mcp-head{display:flex;align-items:center;gap:10px;padding:14px 16px 0}
|
|
3357
|
+
.dut-mcp-head h2{margin:0;font-size:15px;font-weight:600;letter-spacing:-.01em;color:var(--dsw-alias-label-primary)}
|
|
3358
|
+
.dut-mcp-count{font-size:11.5px;color:var(--dsw-alias-label-secondary);padding:2px 8px;border-radius:999px;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1)}
|
|
3359
|
+
.dut-mcp-spacer{flex:1}
|
|
3360
|
+
.dut-mcp-btn{display:inline-flex;align-items:center;height:28px;padding:0 12px;border-radius:999px;border:1px solid var(--dsw-alias-border-l1);background:transparent;color:var(--dsw-alias-label-secondary);font:inherit;font-size:12px;cursor:pointer;transition:background .15s ease,color .15s ease,border-color .15s ease}
|
|
3361
|
+
.dut-mcp-btn:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}
|
|
3362
|
+
.dut-mcp-btn:disabled{opacity:.5;cursor:default}
|
|
3363
|
+
.dut-mcp-btn.dut-mcp-del:hover{border-color:color-mix(in srgb,var(--dsw-alias-state-error-primary) 55%,transparent);color:var(--dsw-alias-state-error-primary);background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 10%,transparent)}
|
|
3364
|
+
.dut-mcp-btn.dut-mcp-confirm{border-color:color-mix(in srgb,var(--dsw-alias-state-error-primary) 55%,transparent);color:var(--dsw-alias-state-error-primary);font-weight:600}
|
|
3365
|
+
.dut-mcp-body{display:grid;gap:2px;margin-top:4px}
|
|
3366
|
+
.dut-mcp-row{display:grid;gap:6px;padding:10px 16px;border-radius:12px}
|
|
3367
|
+
.dut-mcp-row:hover{background:var(--dsw-alias-interactive-bg-hover)}
|
|
3368
|
+
.dut-mcp-row-main{display:flex;align-items:center;gap:8px;min-width:0}
|
|
3369
|
+
.dut-mcp-name{font-size:13.5px;font-weight:600;color:var(--dsw-alias-label-primary);white-space:nowrap;text-overflow:ellipsis;overflow:hidden}
|
|
3370
|
+
.dut-mcp-badge{flex:none;font-size:11px;line-height:1;padding:4px 9px;border-radius:999px;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-secondary)}
|
|
3371
|
+
.dut-mcp-badge.dut-mcp-ok{background:color-mix(in srgb,var(--dsw-alias-state-success-primary) 12%,transparent);border-color:transparent;color:var(--dsw-alias-state-success-primary)}
|
|
3372
|
+
.dut-mcp-badge.dut-mcp-err{background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 12%,transparent);border-color:transparent;color:var(--dsw-alias-state-error-primary)}
|
|
3373
|
+
.dut-mcp-badge.dut-mcp-warn{background:color-mix(in srgb,var(--dsw-alias-state-warn-primary) 14%,transparent);border-color:transparent;color:var(--dsw-alias-state-warn-label)}
|
|
3374
|
+
.dut-mcp-sub{font-size:11.5px;color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;overflow:hidden}
|
|
3375
|
+
.dut-mcp-toggle{flex:none;font-size:11.5px;color:var(--dsw-alias-label-tertiary);background:transparent;border:none;padding:0;cursor:pointer;text-align:left}
|
|
3376
|
+
.dut-mcp-toggle:hover{color:var(--dsw-alias-label-primary)}
|
|
3377
|
+
.dut-mcp-tools{margin-left:2px;display:flex;flex-wrap:wrap;gap:4px}
|
|
3378
|
+
.dut-mcp-tool{font-size:11px;line-height:1;padding:3px 8px;border-radius:999px;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-secondary)}
|
|
3379
|
+
.dut-mcp-note{margin:2px 16px 0;padding:8px 12px;border-radius:10px;font-size:11.5px;line-height:1.55;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1)}
|
|
3380
|
+
.dut-mcp-empty{padding:32px 16px;text-align:center;font-size:12.5px;color:var(--dsw-alias-label-secondary)}
|
|
3381
|
+
.dut-mcp-alert{margin:8px 16px 0;padding:8px 12px;border-radius:10px;font-size:12px;line-height:1.5;background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 10%,transparent);color:var(--dsw-alias-state-error-primary)}
|
|
3382
|
+
.dut-mcp-notice{margin:8px 16px 0;padding:8px 12px;border-radius:10px;font-size:12px;line-height:1.5;background:color-mix(in srgb,var(--dsw-alias-state-success-primary) 12%,transparent);color:var(--dsw-alias-state-success-primary)}
|
|
3383
|
+
.dut-mcp-off{padding:20px 16px;display:grid;gap:12px}
|
|
3384
|
+
.dut-mcp-off p{margin:0;font-size:12.5px;line-height:1.6;color:var(--dsw-alias-label-secondary)}
|
|
3385
|
+
.dut-mcp-overlay{z-index:1100;justify-content:center;align-items:center;display:flex;position:fixed;inset:0}
|
|
3386
|
+
.dut-mcp-mask{background:var(--dsw-alias-bg-mask-1);backdrop-filter:var(--dsw-mask-blur);position:absolute;inset:0}
|
|
3387
|
+
.dut-mcp-panel{z-index:1;background:var(--dsw-alias-bg-layer-2);box-sizing:border-box;width:720px;max-width:calc(100vw - 48px);height:min(700px,100vh - 48px);box-shadow:var(--dsw-shadow-lv3);--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);border-radius:20px;display:flex;flex-direction:column;overflow:hidden}
|
|
3388
|
+
.dut-mcp-panel-head{box-sizing:border-box;flex:none;display:flex;align-items:center;gap:10px;height:52px;padding:0 12px 0 20px}
|
|
3389
|
+
.dut-mcp-panel-head h2{margin:0;font-size:16px;font-weight:600;letter-spacing:-.01em;color:var(--dsw-alias-label-primary)}
|
|
3390
|
+
.dut-mcp-panel-close{cursor:pointer;width:28px;height:28px;color:var(--dsw-alias-label-primary);background:transparent;border:none;border-radius:28px;display:inline-flex;justify-content:center;align-items:center;padding:0;font-size:13px}
|
|
3391
|
+
.dut-mcp-panel-close:hover{background:var(--dsw-alias-interactive-bg-hover)}
|
|
3392
|
+
.dut-mcp-tabs{flex:none;display:inline-flex;padding:3px;gap:3px;border:1px solid var(--dsw-alias-border-l1);border-radius:10px;background:var(--dsw-alias-bg-layer-2);margin:0 20px 10px;align-self:flex-start}
|
|
3393
|
+
.dut-mcp-tabs button{border:none;border-radius:7px;padding:5px 14px;background:transparent;color:var(--dsw-alias-label-secondary);font:inherit;font-size:12.5px;cursor:pointer}
|
|
3394
|
+
.dut-mcp-tabs button.dut-mcp-tab-on{background:color-mix(in srgb,var(--dsw-alias-state-business-primary) 12%,transparent);color:var(--dsw-alias-state-business-primary);font-weight:600}
|
|
3395
|
+
.dut-mcp-form{flex:1;min-height:0;overflow-y:auto;padding:0 20px 20px;display:grid;gap:12px;align-content:start}
|
|
3396
|
+
.dut-mcp-field{display:grid;gap:6px}
|
|
3397
|
+
.dut-mcp-field>span{font-size:12px;font-weight:600;color:var(--dsw-alias-label-primary)}
|
|
3398
|
+
.dut-mcp-field small{font-size:11px;line-height:1.5;color:var(--dsw-alias-label-tertiary)}
|
|
3399
|
+
.dut-mcp-input{box-sizing:border-box;width:100%;height:34px;padding:0 10px;border-radius:9px;border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);font:inherit;font-size:13px}
|
|
3400
|
+
.dut-mcp-input:focus{outline:none;border-color:color-mix(in srgb,var(--dsw-alias-state-business-primary) 55%,transparent)}
|
|
3401
|
+
.dut-mcp-input:disabled{opacity:.55;cursor:not-allowed}
|
|
3402
|
+
textarea.dut-mcp-input{height:auto;min-height:72px;padding:8px 10px;line-height:1.5;resize:vertical;font-family:var(--dsw-font-markdown-code-block-font-family, Consolas, monospace);font-size:12px}
|
|
3403
|
+
textarea.dut-mcp-input-lg{min-height:120px}
|
|
3404
|
+
textarea.dut-mcp-yaml{min-height:320px}
|
|
3405
|
+
.dut-mcp-row2{display:grid;grid-template-columns:1fr 1fr;gap:12px;align-items:start}
|
|
3406
|
+
.dut-mcp-field .dut-seg{width:fit-content}
|
|
3407
|
+
.dut-mcp-row2 .dut-seg{height:34px;box-sizing:border-box;align-items:center}
|
|
3408
|
+
.dut-mcp-row2 .dut-seg button{flex:none;white-space:nowrap;padding:0 16px;height:26px}
|
|
3409
|
+
.dut-mcp-foot{flex:none;display:flex;align-items:center;gap:8px;justify-content:flex-end;padding:12px 20px 16px;border-top:1px solid var(--dsw-alias-border-l1)}
|
|
3410
|
+
.dut-mcp-error{margin:0 20px 10px;padding:8px 12px;border-radius:10px;font-size:12px;line-height:1.5;background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 10%,transparent);color:var(--dsw-alias-state-error-primary)}
|
|
3290
3411
|
`;
|
|
3291
3412
|
/** Install the MCP stylesheet once (idempotent); returns the disposer. */
|
|
3292
3413
|
function installMcpStyles() {
|
|
@@ -4376,28 +4497,28 @@ const WHALE_VIEW_H = 17.04;
|
|
|
4376
4497
|
// ---------------------------------------------------------------------------
|
|
4377
4498
|
// Styles — resident (translucent, still) vs working (opaque, swimming).
|
|
4378
4499
|
// ---------------------------------------------------------------------------
|
|
4379
|
-
exports.WHALE_CSS = `
|
|
4380
|
-
.duwi-row{box-sizing:border-box;width:100%;max-width:calc(var(--dsh-composer-card-max-width) + 2 * var(--dsh-composer-side-clearance, 0px));margin:0 auto;padding:0 calc(var(--dsh-composer-side-clearance, 0px) + 14px) 0 var(--dsh-composer-side-clearance, 0px);display:flex;align-items:flex-end;justify-content:flex-end;height:27px;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}
|
|
4381
|
-
.duwi-stack{display:flex;flex-direction:column;align-items:center;transform:translateY(6px)}
|
|
4382
|
-
.duwi-whale{display:block;color:var(--dsw-alias-label-primary);transform-origin:50% 60%;pointer-events:auto;cursor:pointer}
|
|
4383
|
-
.duwi-row.duwi-swim .duwi-whale,.duwi-whale:hover{animation:duwi-swim 1.9s ease-in-out infinite}
|
|
4384
|
-
.duwi-waves{display:block;width:26px;height:9px;margin-top:-3px;overflow:hidden}
|
|
4385
|
-
.duwi-wave-back{stroke:#3d8bfd;opacity:.35}
|
|
4386
|
-
.duwi-wave-front{stroke:#3d8bfd;opacity:.8}
|
|
4387
|
-
.duwi-wave-front,.duwi-wave-back{animation:duwi-drift-front 1.9s linear infinite}
|
|
4388
|
-
.duwi-wave-back{animation-duration:3.4s;animation-direction:reverse}
|
|
4389
|
-
@keyframes duwi-swim{
|
|
4390
|
-
0%,100%{transform:translateY(0) rotate(-4deg)}
|
|
4391
|
-
50%{transform:translateY(-3.5px) rotate(4deg)}
|
|
4392
|
-
}
|
|
4393
|
-
@keyframes duwi-drift-front{
|
|
4394
|
-
from{transform:translateX(0)}
|
|
4395
|
-
to{transform:translateX(-8px)}
|
|
4396
|
-
}
|
|
4397
|
-
@media (prefers-reduced-motion:reduce){
|
|
4398
|
-
.duwi-row.duwi-swim .duwi-whale,.duwi-whale:hover{animation:none}
|
|
4399
|
-
.duwi-wave-front,.duwi-wave-back{animation:none}
|
|
4400
|
-
}
|
|
4500
|
+
exports.WHALE_CSS = `
|
|
4501
|
+
.duwi-row{box-sizing:border-box;width:100%;max-width:calc(var(--dsh-composer-card-max-width) + 2 * var(--dsh-composer-side-clearance, 0px));margin:0 auto;padding:0 calc(var(--dsh-composer-side-clearance, 0px) + 14px) 0 var(--dsh-composer-side-clearance, 0px);display:flex;align-items:flex-end;justify-content:flex-end;height:27px;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}
|
|
4502
|
+
.duwi-stack{display:flex;flex-direction:column;align-items:center;transform:translateY(6px)}
|
|
4503
|
+
.duwi-whale{display:block;color:var(--dsw-alias-label-primary);transform-origin:50% 60%;pointer-events:auto;cursor:pointer}
|
|
4504
|
+
.duwi-row.duwi-swim .duwi-whale,.duwi-whale:hover{animation:duwi-swim 1.9s ease-in-out infinite}
|
|
4505
|
+
.duwi-waves{display:block;width:26px;height:9px;margin-top:-3px;overflow:hidden}
|
|
4506
|
+
.duwi-wave-back{stroke:#3d8bfd;opacity:.35}
|
|
4507
|
+
.duwi-wave-front{stroke:#3d8bfd;opacity:.8}
|
|
4508
|
+
.duwi-wave-front,.duwi-wave-back{animation:duwi-drift-front 1.9s linear infinite}
|
|
4509
|
+
.duwi-wave-back{animation-duration:3.4s;animation-direction:reverse}
|
|
4510
|
+
@keyframes duwi-swim{
|
|
4511
|
+
0%,100%{transform:translateY(0) rotate(-4deg)}
|
|
4512
|
+
50%{transform:translateY(-3.5px) rotate(4deg)}
|
|
4513
|
+
}
|
|
4514
|
+
@keyframes duwi-drift-front{
|
|
4515
|
+
from{transform:translateX(0)}
|
|
4516
|
+
to{transform:translateX(-8px)}
|
|
4517
|
+
}
|
|
4518
|
+
@media (prefers-reduced-motion:reduce){
|
|
4519
|
+
.duwi-row.duwi-swim .duwi-whale,.duwi-whale:hover{animation:none}
|
|
4520
|
+
.duwi-wave-front,.duwi-wave-back{animation:none}
|
|
4521
|
+
}
|
|
4401
4522
|
`;
|
|
4402
4523
|
/** Idempotent installer for the indicator styles (same pattern as the other features). */
|
|
4403
4524
|
function installWhaleStyles() {
|