zidane-ui 9.1.6 → 9.1.9
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/dist/adapters/run-host.js +17 -20
- package/dist/adapters/server-files-host.js +3 -1
- package/dist/adapters/server-host.js +18 -11
- package/dist/adapters/server-machines-host.js +3 -1
- package/dist/adapters/server-session-host.js +2 -1
- package/dist/adapters/server-settings-accounts.js +2 -1
- package/dist/adapters/server-settings-host.js +3 -3
- package/dist/adapters/sse-host.js +9 -7
- package/dist/chat/SessionGroupHeader.js +2 -2
- package/dist/chat/SessionHostHeader.js +1 -1
- package/dist/chat/StatusDot.js +24 -20
- package/dist/chat/composer/Composer.d.ts +13 -8
- package/dist/chat/composer/Composer.js +14 -10
- package/dist/chat/composer/ComposerEditor.js +1 -1
- package/dist/chat/composer/HostComposer.d.ts +1 -1
- package/dist/chat/composer/HostComposer.js +7 -10
- package/dist/chat/composer/RunStatusChip.js +13 -1
- package/dist/chat/composer/attachment-ingest.d.ts +4 -1
- package/dist/chat/composer/attachment-ingest.js +27 -10
- package/dist/chat/composer/composer-bus.d.ts +9 -1
- package/dist/chat/composer/composer-bus.js +49 -6
- package/dist/chat/composer/index.d.ts +2 -2
- package/dist/chat/composer/index.js +2 -2
- package/dist/chat/composer/use-draft-target.d.ts +4 -0
- package/dist/chat/composer/use-draft-target.js +15 -4
- package/dist/chat/composer/use-send-prompt.d.ts +5 -1
- package/dist/chat/composer/use-send-prompt.js +2 -12
- package/dist/chat/headless/chip-labels.d.ts +2 -0
- package/dist/chat/headless/chip-labels.js +3 -1
- package/dist/chat/headless/composer/labels-editor.d.ts +2 -0
- package/dist/chat/headless/composer/labels-editor.js +2 -0
- package/dist/chat/headless/file-chip.d.ts +12 -13
- package/dist/chat/headless/file-chip.js +40 -2
- package/dist/chat/headless/fixture-host.js +14 -17
- package/dist/chat/headless/host.d.ts +24 -6
- package/dist/chat/headless/index.d.ts +4 -4
- package/dist/chat/headless/index.js +4 -4
- package/dist/chat/headless/labels.d.ts +16 -0
- package/dist/chat/headless/labels.js +15 -2
- package/dist/chat/headless/send-flow.d.ts +21 -4
- package/dist/chat/headless/send-flow.js +25 -6
- package/dist/chat/headless/session-list.d.ts +11 -0
- package/dist/chat/headless/sidebar/index.js +1 -1
- package/dist/chat/headless/sidebar/labels.d.ts +12 -1
- package/dist/chat/headless/transcript-host.d.ts +8 -1
- package/dist/chat/headless/transcript-labels.d.ts +2 -0
- package/dist/chat/index.d.ts +3 -3
- package/dist/chat/index.js +2 -2
- package/dist/chat/interactions/InboxPanel.js +2 -2
- package/dist/chat/interactions/QuestionField.js +2 -2
- package/dist/chat/rich-composer/RichComposer.d.ts +9 -2
- package/dist/chat/rich-composer/RichComposer.js +28 -7
- package/dist/chat/rich-composer/composer-extensions.d.ts +2 -0
- package/dist/chat/rich-composer/composer-extensions.js +2 -2
- package/dist/chat/rich-composer/composer-keys.js +1 -1
- package/dist/chat/rich-composer/use-composer-bus.js +2 -1
- package/dist/chat/rich-composer/use-composer-editor.d.ts +4 -1
- package/dist/chat/rich-composer/use-composer-editor.js +2 -1
- package/dist/chat/sidebar/SessionSidebar.js +1 -2
- package/dist/chat/sidebar/SidebarSearchRow.js +1 -1
- package/dist/chat/sidebar/useSidebarKeyboardNav.d.ts +0 -2
- package/dist/chat/sidebar/useSidebarKeyboardNav.js +7 -13
- package/dist/chat/testing/contract.d.ts +1 -1
- package/dist/chat/testing/contract.js +8 -7
- package/dist/chat/transcript/BadgeMenu.d.ts +12 -3
- package/dist/chat/transcript/BadgeMenu.js +20 -3
- package/dist/chat/transcript/CodemodeScript.js +147 -44
- package/dist/chat/transcript/EditDiffBlock.js +1 -4
- package/dist/chat/transcript/FileChip.js +60 -14
- package/dist/chat/transcript/LiveOutput.js +7 -3
- package/dist/chat/transcript/badges.js +2 -2
- package/dist/chat/transcript/index.d.ts +2 -2
- package/dist/chat/transcript/markdown-context.d.ts +4 -1
- package/dist/chat/transcript/rolling.d.ts +12 -0
- package/dist/chat/transcript/rolling.js +22 -0
- package/dist/chat/transcript/script-input.d.ts +1 -1
- package/dist/chat/transcript/shell-block.js +70 -60
- package/dist/chat/transcript/tool-row.js +21 -5
- package/dist/code/editor/FileTree.d.ts +3 -1
- package/dist/code/editor/FileTree.js +29 -1
- package/dist/components/Restricted.d.ts +25 -0
- package/dist/components/Restricted.js +32 -0
- package/dist/components/StepFrame.d.ts +1 -1
- package/dist/components/ZidaneMark.d.ts +28 -0
- package/dist/components/ZidaneMark.js +114 -0
- package/dist/components/palette/PalettePanel.d.ts +7 -1
- package/dist/components/palette/PalettePanel.js +37 -11
- package/dist/components/zidane-mark.d.ts +52 -0
- package/dist/components/zidane-mark.js +94 -0
- package/dist/core.css +59 -6
- package/dist/dist/{index-DqCio7Nd.d.ts → index-Bq87OcGy.d.ts} +19 -12
- package/dist/dist/index.d.ts +1 -1
- package/dist/extensions/ExtensionSettingsSection.d.ts +18 -0
- package/dist/extensions/ExtensionSettingsSection.js +227 -0
- package/dist/extensions/headless/host.d.ts +1 -1
- package/dist/extensions/headless/labels.d.ts +41 -1
- package/dist/extensions/headless/labels.js +57 -0
- package/dist/extensions/headless/select.js +1 -2
- package/dist/extensions/index.d.ts +2 -1
- package/dist/extensions/index.js +2 -1
- package/dist/files/FilesTab.js +2 -0
- package/dist/files/TreeColumn.d.ts +5 -1
- package/dist/files/TreeColumn.js +6 -0
- package/dist/files/headless/fixture-host.js +5 -3
- package/dist/files/headless/host.d.ts +24 -6
- package/dist/files/headless/index.d.ts +2 -2
- package/dist/files/headless/labels.d.ts +1 -0
- package/dist/files/headless/labels.js +1 -0
- package/dist/files/testing/contract.js +9 -2
- package/dist/files/useWorkspace.d.ts +14 -2
- package/dist/files/useWorkspace.js +87 -9
- package/dist/git/BranchMenu.js +1 -1
- package/dist/git/MoveSessionDialog.js +1 -1
- package/dist/git/RemoteFolderPicker.js +1 -1
- package/dist/git/WherePicker.js +1 -1
- package/dist/git/headless/index.js +1 -1
- package/dist/git/useEnvironmentChoices.js +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.js +4 -2
- package/dist/keybindings/headless/catalog.js +1 -1
- package/dist/labels.d.ts +1 -0
- package/dist/labels.js +1 -0
- package/dist/machines/DaemonMenu.js +1 -1
- package/dist/machines/HostCapabilities.d.ts +23 -1
- package/dist/machines/HostCapabilities.js +149 -65
- package/dist/machines/HostSyncPanel.js +129 -123
- package/dist/machines/HostsSection.js +5 -1
- package/dist/machines/ServerCard.d.ts +4 -2
- package/dist/machines/ServerCard.js +222 -99
- package/dist/machines/ServerMachinesPanel.js +16 -13
- package/dist/machines/ServerUpdatePanel.js +31 -21
- package/dist/machines/TokensPanel.js +75 -53
- package/dist/machines/headless/fixture-host.d.ts +5 -0
- package/dist/machines/headless/fixture-host.js +13 -4
- package/dist/machines/headless/fixtures.js +1 -1
- package/dist/machines/headless/host.d.ts +22 -2
- package/dist/machines/headless/index.d.ts +2 -2
- package/dist/machines/headless/labels.d.ts +22 -1
- package/dist/machines/headless/labels.js +22 -2
- package/dist/machines/testing/contract.d.ts +3 -1
- package/dist/machines/testing/contract.js +9 -0
- package/dist/motion/size.d.ts +22 -1
- package/dist/motion/size.js +82 -4
- package/dist/onboarding/demos/delivery.d.ts +16 -0
- package/dist/onboarding/demos/delivery.js +132 -0
- package/dist/onboarding/demos/index.d.ts +2 -1
- package/dist/onboarding/demos/index.js +2 -1
- package/dist/onboarding/headless/labels.d.ts +8 -0
- package/dist/onboarding/headless/labels.js +7 -0
- package/dist/onboarding/index.d.ts +2 -1
- package/dist/onboarding/index.js +2 -1
- package/dist/onboarding/steps/ConversationStep.js +46 -4
- package/dist/palette/CommandPalette.js +3 -0
- package/dist/palette/PaletteDialog.js +7 -3
- package/dist/palette/usePaletteController.d.ts +10 -0
- package/dist/palette/usePaletteController.js +25 -3
- package/dist/server/sse-handler.js +6 -1
- package/dist/session/ArtifactsPanel.js +1 -1
- package/dist/session/SideChat.js +1 -2
- package/dist/session/UsagePanel.js +1 -1
- package/dist/session/headless/host.d.ts +3 -1
- package/dist/session/headless/index.js +2 -2
- package/dist/settings/SettingsRestricted.d.ts +25 -0
- package/dist/settings/SettingsRestricted.js +44 -0
- package/dist/settings/SettingsRowsPage.js +31 -37
- package/dist/settings/headless/catalog.js +7 -6
- package/dist/settings/headless/labels.d.ts +4 -2
- package/dist/settings/headless/labels.js +4 -2
- package/dist/settings/headless/layout.js +1 -1
- package/dist/settings/headless/providers.d.ts +2 -0
- package/dist/settings/headless/search.d.ts +1 -1
- package/dist/settings/index.d.ts +2 -2
- package/dist/settings/index.js +2 -2
- package/dist/settings/rows.d.ts +51 -8
- package/dist/settings/rows.js +81 -26
- package/dist/settings/sections/enabled-list/EnabledListSection.js +3 -2
- package/dist/settings/sections/environments/EnvironmentsSection.js +4 -3
- package/dist/settings/sections/extensions/ExtensionConfigRows.d.ts +2 -2
- package/dist/settings/sections/extensions/ExtensionConfigRows.js +22 -25
- package/dist/settings/sections/extensions/ExtensionOptionsSection.js +3 -2
- package/dist/settings/sections/extensions/options-labels.d.ts +2 -2
- package/dist/settings/sections/extensions/options-labels.js +2 -2
- package/dist/settings/sections/host-catalog/HostCatalogSection.d.ts +5 -3
- package/dist/settings/sections/host-catalog/HostCatalogSection.js +7 -4
- package/dist/settings/sections/instructions/InstructionsSection.js +24 -17
- package/dist/settings/sections/logs/LogsSection.d.ts +2 -1
- package/dist/settings/sections/logs/LogsSection.js +64 -56
- package/dist/settings/sections/mcp/McpSection.d.ts +1 -1
- package/dist/settings/sections/mcp/McpSection.js +18 -17
- package/dist/settings/sections/models/ModelRows.d.ts +3 -3
- package/dist/settings/sections/models/ModelRows.js +8 -7
- package/dist/settings/sections/performance/PerformanceSection.js +13 -4
- package/dist/settings/sections/performance/labels.d.ts +0 -1
- package/dist/settings/sections/performance/labels.js +0 -1
- package/dist/settings/sections/providers/CredentialSources.js +18 -8
- package/dist/settings/sections/providers/ProvidersSection.d.ts +2 -2
- package/dist/settings/sections/providers/ProvidersSection.js +20 -17
- package/dist/settings/sections/providers/ServerProvidersSection.d.ts +1 -1
- package/dist/settings/sections/providers/ServerProvidersSection.js +10 -14
- package/dist/settings/sections/shared/catalog.js +3 -2
- package/dist/settings/sections/skills/SkillList.js +3 -2
- package/dist/settings/testing/accounts-demo.js +1 -0
- package/dist/settings/testing/accounts.contract.js +2 -0
- package/dist/styles.css +160 -24
- package/dist/terminal/HostTerminalSurface.js +1 -1
- package/dist/terminal/headless/links.d.ts +19 -1
- package/dist/terminal/headless/links.js +26 -2
- package/dist/theme/css-vars.js +1 -0
- package/dist/theme/derive.d.ts +4 -0
- package/dist/theme/derive.js +2 -0
- package/dist/workspace/PanelContentView.js +1 -1
- package/dist/workspace/PanelHome.d.ts +3 -1
- package/dist/workspace/PanelHome.js +4 -3
- package/dist/workspace/SidePanel.d.ts +3 -1
- package/dist/workspace/SidePanel.js +3 -2
- package/dist/workspace/headless/open-target.d.ts +1 -1
- package/dist/workspace/headless/open-target.js +2 -2
- package/package.json +2 -2
- package/src/styles/chat.css +10 -10
- package/src/styles/motion.css +37 -0
- package/src/styles/primitives.css +11 -3
- package/src/styles/sidebar.css +12 -0
- package/src/styles/tokens.css +6 -0
- package/src/styles/transcript.css +69 -5
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { BTN_DANGER, BTN_PRIMARY, BTN_SECONDARY } from "../../../components/button.js";
|
|
2
2
|
import { ErrorNote, FormCard, FormSection, MetaChip, OpLine, RowText } from "../../../components/Form.js";
|
|
3
|
-
import { constant, useReadable } from "../../../chat/headless/store.js";
|
|
4
3
|
import { toSettingsError } from "../../headless/host.js";
|
|
5
4
|
import { useSettingsHost } from "../../SettingsProvider.js";
|
|
6
5
|
import { SettingsPanel, SettingsPanelBody } from "../../section.js";
|
|
7
6
|
import { hasCredentialChoice } from "../../headless/providers.js";
|
|
7
|
+
import { SettingsRestricted } from "../../SettingsRestricted.js";
|
|
8
8
|
import { useSettingsResource } from "../shared/catalog.js";
|
|
9
9
|
import { CredentialSources } from "./CredentialSources.js";
|
|
10
10
|
import { useAccountsSectionLabels } from "./ProvidersSection.js";
|
|
@@ -21,19 +21,16 @@ import { useMemo, useState } from "react";
|
|
|
21
21
|
* is left alone. With more than one stored, they are its credential sources
|
|
22
22
|
* (`CredentialSources`: the one in use picked, an OAuth account renamed).
|
|
23
23
|
*/
|
|
24
|
-
const ALWAYS = constant(true);
|
|
25
24
|
const YES = async () => true;
|
|
26
25
|
/**
|
|
27
26
|
* Renders the providers of the nearest `SettingsProvider`'s host (`providers`) as a server's cards: Set API
|
|
28
27
|
* key needs `setApiKey`, Sign in `signIn`, Remove `remove`; a connection that may not write (`writable`)
|
|
29
|
-
*
|
|
28
|
+
* sees the cards restricted ("Admin only").
|
|
30
29
|
*
|
|
31
30
|
* @param props - The `hostName`, an `intro`, `className` and `style`.
|
|
32
31
|
*/
|
|
33
32
|
function ServerProvidersSection({ hostName, intro, className, style }) {
|
|
34
|
-
const
|
|
35
|
-
const providers = host.providers;
|
|
36
|
-
const writable = useReadable(host.writable ?? ALWAYS);
|
|
33
|
+
const providers = useSettingsHost().providers;
|
|
37
34
|
const l = useAccountsSectionLabels();
|
|
38
35
|
const resource = useMemo(() => providers?.list("") ?? null, [providers]);
|
|
39
36
|
const load = useSettingsResource(resource);
|
|
@@ -49,21 +46,20 @@ function ServerProvidersSection({ hostName, intro, className, style }) {
|
|
|
49
46
|
kind: "busy",
|
|
50
47
|
children: l.accountsServerReading(hostName)
|
|
51
48
|
}),
|
|
52
|
-
list && providers && /* @__PURE__ */ jsx(FormSection, {
|
|
49
|
+
list && providers && /* @__PURE__ */ jsx(SettingsRestricted, { children: /* @__PURE__ */ jsx(FormSection, {
|
|
53
50
|
layout: "cards",
|
|
54
51
|
children: list.map((provider) => /* @__PURE__ */ jsx(ProviderCard, {
|
|
55
52
|
host: providers,
|
|
56
53
|
hostName,
|
|
57
54
|
provider,
|
|
58
|
-
writable,
|
|
59
55
|
labels: l
|
|
60
56
|
}, provider.key))
|
|
61
|
-
})
|
|
57
|
+
}) })
|
|
62
58
|
]
|
|
63
59
|
})] })
|
|
64
60
|
});
|
|
65
61
|
}
|
|
66
|
-
function ProviderCard({ host, hostName, provider,
|
|
62
|
+
function ProviderCard({ host, hostName, provider, labels: l }) {
|
|
67
63
|
const [editing, setEditing] = useState(false);
|
|
68
64
|
const [signingIn, setSigningIn] = useState(false);
|
|
69
65
|
const [key, setKey] = useState("");
|
|
@@ -107,13 +103,13 @@ function ProviderCard({ host, hostName, provider, writable, labels: l }) {
|
|
|
107
103
|
children: provider.methods.map((method) => /* @__PURE__ */ jsx(MetaChip, { children: method.detail }, `${method.source}:${method.key ?? method.detail}`))
|
|
108
104
|
}) : void 0
|
|
109
105
|
}),
|
|
110
|
-
|
|
106
|
+
signIn && provider.oauth && !signingIn && /* @__PURE__ */ jsx("button", {
|
|
111
107
|
type: "button",
|
|
112
108
|
className: BTN_SECONDARY,
|
|
113
109
|
onClick: () => setSigningIn(true),
|
|
114
110
|
children: l.accountsSignIn
|
|
115
111
|
}),
|
|
116
|
-
|
|
112
|
+
setApiKey && !editing && /* @__PURE__ */ jsx("button", {
|
|
117
113
|
type: "button",
|
|
118
114
|
className: BTN_SECONDARY,
|
|
119
115
|
onClick: () => setEditing(true),
|
|
@@ -162,7 +158,7 @@ function ProviderCard({ host, hostName, provider, writable, labels: l }) {
|
|
|
162
158
|
children: /* @__PURE__ */ jsx(CredentialSources, {
|
|
163
159
|
provider,
|
|
164
160
|
cwd: "",
|
|
165
|
-
host
|
|
161
|
+
host,
|
|
166
162
|
labels: l,
|
|
167
163
|
confirm: YES,
|
|
168
164
|
onError: setError
|
|
@@ -185,7 +181,7 @@ function ProviderCard({ host, hostName, provider, writable, labels: l }) {
|
|
|
185
181
|
}),
|
|
186
182
|
/* @__PURE__ */ jsx(MetaChip, { children: method.detail })
|
|
187
183
|
]
|
|
188
|
-
}),
|
|
184
|
+
}), remove && /* @__PURE__ */ jsx("button", {
|
|
189
185
|
type: "button",
|
|
190
186
|
className: BTN_DANGER,
|
|
191
187
|
disabled: busy,
|
|
@@ -5,6 +5,7 @@ import { Checkbox } from "../../../components/Form.js";
|
|
|
5
5
|
import { toSettingsError } from "../../headless/host.js";
|
|
6
6
|
import { useSettingsDocument, useSettingsHost, useSettingsWritable } from "../../SettingsProvider.js";
|
|
7
7
|
import { useSectionLabels } from "../use-section-labels.js";
|
|
8
|
+
import { SettingsRestricted } from "../../SettingsRestricted.js";
|
|
8
9
|
import { enabledNames, toggleEnabled } from "../../headless/enabled.js";
|
|
9
10
|
import { DEFAULT_CATALOG_SHARED_LABELS } from "./labels.js";
|
|
10
11
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -130,7 +131,7 @@ function EnabledList({ catalog, keyOf, labelOf, detailOf, leadOf, badgeOf, statu
|
|
|
130
131
|
return /* @__PURE__ */ jsxs("div", {
|
|
131
132
|
className,
|
|
132
133
|
style,
|
|
133
|
-
children: [preamble, catalog.length === 0 ? /* @__PURE__ */ jsx(EmptyState, { title: emptyMessage }) : /* @__PURE__ */ jsx("ul", {
|
|
134
|
+
children: [preamble, catalog.length === 0 ? /* @__PURE__ */ jsx(EmptyState, { title: emptyMessage }) : /* @__PURE__ */ jsx(SettingsRestricted, { children: /* @__PURE__ */ jsx("ul", {
|
|
134
135
|
className: "zg-tray rounded-zg-lg flex flex-col list-none m-0 p-1",
|
|
135
136
|
children: catalog.map((entry) => {
|
|
136
137
|
const key = keyOf(entry);
|
|
@@ -177,7 +178,7 @@ function EnabledList({ catalog, keyOf, labelOf, detailOf, leadOf, badgeOf, statu
|
|
|
177
178
|
}) : null]
|
|
178
179
|
}, key);
|
|
179
180
|
})
|
|
180
|
-
})]
|
|
181
|
+
}) })]
|
|
181
182
|
});
|
|
182
183
|
}
|
|
183
184
|
//#endregion
|
|
@@ -6,6 +6,7 @@ import { Checkbox, MetaChip } from "../../../components/Form.js";
|
|
|
6
6
|
import { LoadError } from "../../../components/LoadError.js";
|
|
7
7
|
import { useSettingsHost } from "../../SettingsProvider.js";
|
|
8
8
|
import { useSectionLabels } from "../use-section-labels.js";
|
|
9
|
+
import { SettingsRestricted } from "../../SettingsRestricted.js";
|
|
9
10
|
import { OpenFileButton, RevealPathButton, useCatalogSharedLabels, useEnabledList, useSettingsResource } from "../shared/catalog.js";
|
|
10
11
|
import { useCodeDocument } from "../../../code/editor/useCodeDocument.js";
|
|
11
12
|
import { formatTokens } from "../../../session/headless/usage-format.js";
|
|
@@ -121,7 +122,7 @@ function SkillList({ cwd, catalog, actionOf, onSaved, emptyMessage }) {
|
|
|
121
122
|
weights
|
|
122
123
|
}),
|
|
123
124
|
shown.length === 0 && /* @__PURE__ */ jsx(EmptyState, { title: inScope.length === 0 ? l.skillsSectionNoneInScope(filter) : l.skillsSectionNoMatch(query.trim()) }),
|
|
124
|
-
/* @__PURE__ */ jsx("ul", {
|
|
125
|
+
/* @__PURE__ */ jsx(SettingsRestricted, { children: /* @__PURE__ */ jsx("ul", {
|
|
125
126
|
className: "flex flex-col gap-2 list-none m-0 p-0",
|
|
126
127
|
children: shown.map((entry) => /* @__PURE__ */ jsx(SkillCard, {
|
|
127
128
|
cwd,
|
|
@@ -139,7 +140,7 @@ function SkillList({ cwd, catalog, actionOf, onSaved, emptyMessage }) {
|
|
|
139
140
|
action: actionOf?.(entry),
|
|
140
141
|
onSaved
|
|
141
142
|
}, entry.name))
|
|
142
|
-
})
|
|
143
|
+
}) })
|
|
143
144
|
]
|
|
144
145
|
});
|
|
145
146
|
}
|
|
@@ -46,6 +46,7 @@ const PROVIDERS = [{
|
|
|
46
46
|
source: "oauth",
|
|
47
47
|
key: "anthropic:oauth:work",
|
|
48
48
|
label: "work",
|
|
49
|
+
email: "work@example.com",
|
|
49
50
|
detail: "expires in 12 days",
|
|
50
51
|
active: true
|
|
51
52
|
}, {
|
|
@@ -143,6 +144,7 @@ function describeSettingsAccountsContract(name, makeHarness, capabilities) {
|
|
|
143
144
|
const anthropic = list.find((p) => p.key === "anthropic");
|
|
144
145
|
expect(anthropic.available).toBe(true);
|
|
145
146
|
expect(anthropic.methods.find((m) => m.active)?.key).toBe("anthropic:oauth:work");
|
|
147
|
+
expect(anthropic.methods.find((m) => m.active)?.email).toBe("work@example.com");
|
|
146
148
|
expect(list.find((p) => p.key === "openai").available).toBe(false);
|
|
147
149
|
});
|
|
148
150
|
it.skipIf(!has("providers.setApiKey"))("setApiKey stores the key and the list shows it", async () => {
|
package/dist/styles.css
CHANGED
|
@@ -303,7 +303,6 @@
|
|
|
303
303
|
.sticky{position:sticky;}
|
|
304
304
|
.static{position:static;}
|
|
305
305
|
.-inset-\[2px\]{inset:-2px;}
|
|
306
|
-
.-inset-\[3px\]{inset:-3px;}
|
|
307
306
|
.-inset-px{inset:-1px;}
|
|
308
307
|
.inset-0{inset:0;}
|
|
309
308
|
.-inset-x-1{left:-0.25rem;right:-0.25rem;}
|
|
@@ -401,6 +400,11 @@
|
|
|
401
400
|
.m\[2\]{margin:2;}
|
|
402
401
|
.m\[2\]\!{margin:2 !important;}
|
|
403
402
|
.m\[3\]{margin:3;}
|
|
403
|
+
.m\[4\]{margin:4;}
|
|
404
|
+
.m\[5\]{margin:5;}
|
|
405
|
+
.m\[6\]{margin:6;}
|
|
406
|
+
.m\[8\]{margin:8;}
|
|
407
|
+
.m\[9\]{margin:9;}
|
|
404
408
|
.m23\.6{margin:5.9rem;}
|
|
405
409
|
.m4\.7144{margin:1.1786rem;}
|
|
406
410
|
.ma{margin:auto;}
|
|
@@ -412,6 +416,7 @@
|
|
|
412
416
|
.-my-1{margin-top:-0.25rem;margin-bottom:-0.25rem;}
|
|
413
417
|
.-my-px{margin-top:-1px;margin-bottom:-1px;}
|
|
414
418
|
.mx{margin-left:1rem;margin-right:1rem;}
|
|
419
|
+
.mx-0\.5{margin-left:0.125rem;margin-right:0.125rem;}
|
|
415
420
|
.mx-1{margin-left:0.25rem;margin-right:0.25rem;}
|
|
416
421
|
.mx-1\.5{margin-left:0.375rem;margin-right:0.375rem;}
|
|
417
422
|
.mx-2{margin-left:0.5rem;margin-right:0.5rem;}
|
|
@@ -474,7 +479,6 @@
|
|
|
474
479
|
.mt-\[5px\]{margin-top:5px;}
|
|
475
480
|
.mt-\[6px\]{margin-top:6px;}
|
|
476
481
|
.mt-\[7px\]{margin-top:7px;}
|
|
477
|
-
.mt-0{margin-top:0;}
|
|
478
482
|
.mt-0\.5{margin-top:0.125rem;}
|
|
479
483
|
.mt-1{margin-top:0.25rem;}
|
|
480
484
|
.mt-1\.5{margin-top:0.375rem;}
|
|
@@ -504,6 +508,7 @@
|
|
|
504
508
|
.\!w-40{width:10rem !important;}
|
|
505
509
|
.\!w-64{width:16rem !important;}
|
|
506
510
|
.\!w-auto{width:auto !important;}
|
|
511
|
+
.h-\[108px\]{height:108px;}
|
|
507
512
|
.h-\[14px\]{height:14px;}
|
|
508
513
|
.h-\[18px\]{height:18px;}
|
|
509
514
|
.h-\[1em\]{height:1em;}
|
|
@@ -567,6 +572,7 @@
|
|
|
567
572
|
.max-h-\[min\(70vh\,560px\)\]{max-height:min(70vh,560px);}
|
|
568
573
|
.max-h-16{max-height:4rem;}
|
|
569
574
|
.max-h-28{max-height:7rem;}
|
|
575
|
+
.max-h-40{max-height:10rem;}
|
|
570
576
|
.max-h-60{max-height:15rem;}
|
|
571
577
|
.max-h-64{max-height:16rem;}
|
|
572
578
|
.max-h-72{max-height:18rem;}
|
|
@@ -812,7 +818,6 @@
|
|
|
812
818
|
.gap-8{gap:2rem;}
|
|
813
819
|
.gap-px{gap:1px;}
|
|
814
820
|
.gap-x-1{column-gap:0.25rem;}
|
|
815
|
-
.gap-x-1\.5{column-gap:0.375rem;}
|
|
816
821
|
.gap-x-2{column-gap:0.5rem;}
|
|
817
822
|
.gap-x-2\.5{column-gap:0.625rem;}
|
|
818
823
|
.gap-x-3{column-gap:0.75rem;}
|
|
@@ -831,6 +836,9 @@
|
|
|
831
836
|
.space-y-4>:not([hidden])~:not([hidden]){--un-space-y-reverse:0;margin-top:calc(1rem * calc(1 - var(--un-space-y-reverse)));margin-bottom:calc(1rem * var(--un-space-y-reverse));}
|
|
832
837
|
.space-y-5>:not([hidden])~:not([hidden]){--un-space-y-reverse:0;margin-top:calc(1.25rem * calc(1 - var(--un-space-y-reverse)));margin-bottom:calc(1.25rem * var(--un-space-y-reverse));}
|
|
833
838
|
.divide-y>:not([hidden])~:not([hidden]){--un-divide-y-reverse:0;border-top-width:calc(1px * calc(1 - var(--un-divide-y-reverse)));border-bottom-width:calc(1px * var(--un-divide-y-reverse));}
|
|
839
|
+
.border-\[var\(--zg-border\)\],
|
|
840
|
+
.border-zg-border,
|
|
841
|
+
.divide-\[var\(--zg-border\)\]>:not([hidden])~:not([hidden]){border-color:var(--zg-border);}
|
|
834
842
|
.\[\&\+\&\]\:border-\[var\(--zg-hairline\)\]+.\[\&\+\&\]\:border-\[var\(--zg-hairline\)\],
|
|
835
843
|
.border-\[var\(--zg-hairline\)\],
|
|
836
844
|
.divide-\[var\(--zg-hairline\)\]>:not([hidden])~:not([hidden]){border-color:var(--zg-hairline);}
|
|
@@ -867,8 +875,6 @@
|
|
|
867
875
|
.border-s-2{border-inline-start-width:2px;}
|
|
868
876
|
.border-\[var\(--zg-accent\)\]{border-color:var(--zg-accent);}
|
|
869
877
|
.border-\[var\(--zg-border-strong\)\]{border-color:var(--zg-border-strong);}
|
|
870
|
-
.border-\[var\(--zg-border\)\],
|
|
871
|
-
.border-zg-border{border-color:var(--zg-border);}
|
|
872
878
|
.border-\[var\(--zg-text-muted\)\]{border-color:var(--zg-text-muted);}
|
|
873
879
|
.border-transparent{border-color:transparent;}
|
|
874
880
|
.border-zg-danger{border-color:var(--zg-danger);}
|
|
@@ -1027,6 +1033,7 @@
|
|
|
1027
1033
|
.pb-2{padding-bottom:0.5rem;}
|
|
1028
1034
|
.pb-2\.5{padding-bottom:0.625rem;}
|
|
1029
1035
|
.pb-3{padding-bottom:0.75rem;}
|
|
1036
|
+
.pb-3\.5{padding-bottom:0.875rem;}
|
|
1030
1037
|
.pb-4{padding-bottom:1rem;}
|
|
1031
1038
|
.pb-6{padding-bottom:1.5rem;}
|
|
1032
1039
|
.pb-8{padding-bottom:2rem;}
|
|
@@ -1134,10 +1141,12 @@
|
|
|
1134
1141
|
.text-\[var\(--zg-accent\)\],
|
|
1135
1142
|
.text-zg-accent{color:var(--zg-accent);}
|
|
1136
1143
|
.text-\[var\(--zg-bg\)\]{color:var(--zg-bg);}
|
|
1144
|
+
.text-\[var\(--zg-choice-fg\,var\(--zg-text-muted\)\)\]{color:var(--zg-choice-fg,var(--zg-text-muted));}
|
|
1137
1145
|
.text-\[var\(--zg-code-fg\)\]{color:var(--zg-code-fg);}
|
|
1138
1146
|
.text-\[var\(--zg-danger\)\],
|
|
1139
1147
|
.text-zg-danger{color:var(--zg-danger);}
|
|
1140
1148
|
.text-\[var\(--zg-error\)\]{color:var(--zg-error);}
|
|
1149
|
+
.text-\[var\(--zg-sidebar-label-fg\,var\(--zg-text-muted\)\)\]{color:var(--zg-sidebar-label-fg,var(--zg-text-muted));}
|
|
1141
1150
|
.text-\[var\(--zg-success\)\],
|
|
1142
1151
|
.text-zg-success{color:var(--zg-success);}
|
|
1143
1152
|
.text-\[var\(--zg-text-muted\)\],
|
|
@@ -1162,6 +1171,7 @@
|
|
|
1162
1171
|
.enabled\:hover\:text-\[var\(--zg-text\)\]:hover:enabled{color:var(--zg-text);}
|
|
1163
1172
|
.disabled\:hover\:text-\[var\(--zg-text-muted\)\]:hover:disabled{color:var(--zg-text-muted);}
|
|
1164
1173
|
.disabled\:text-\[var\(--zg-text-muted\)\]:disabled{color:var(--zg-text-muted);}
|
|
1174
|
+
.placeholder\:text-\[var\(--zg-sidebar-label-fg\,var\(--zg-text-muted\)\)\]::placeholder{color:var(--zg-sidebar-label-fg,var(--zg-text-muted));}
|
|
1165
1175
|
.placeholder\:text-\[var\(--zg-text-muted\)\]::placeholder{color:var(--zg-text-muted);}
|
|
1166
1176
|
.placeholder\:text-\[var\(--zg-text-subtle\)\]::placeholder{color:var(--zg-text-subtle);}
|
|
1167
1177
|
.text-inherit{color:inherit;}
|
|
@@ -1188,7 +1198,6 @@
|
|
|
1188
1198
|
.tracking-\[0\.12em\]{letter-spacing:0.12em;}
|
|
1189
1199
|
.tracking-\[inherit\]{letter-spacing:inherit;}
|
|
1190
1200
|
.tracking-normal{letter-spacing:0em;}
|
|
1191
|
-
.tracking-wide{letter-spacing:0.025em;}
|
|
1192
1201
|
.font-\[inherit\]{font-family:inherit;}
|
|
1193
1202
|
.font-mono{font-family:var(--zg-font-mono);}
|
|
1194
1203
|
.font-sans{font-family:var(--zg-font-ui);}
|
|
@@ -1368,6 +1377,7 @@
|
|
|
1368
1377
|
--zg-ring: #26a9f1;
|
|
1369
1378
|
|
|
1370
1379
|
--zg-text-raw: #e5e8ec;
|
|
1380
|
+
--zg-text-strong-raw: #ffffff;
|
|
1371
1381
|
--zg-text-muted-raw: #9499a0;
|
|
1372
1382
|
--zg-text-subtle-raw: #5f636a;
|
|
1373
1383
|
|
|
@@ -1634,6 +1644,11 @@ html[data-motion='off'] {
|
|
|
1634
1644
|
color-mix(in oklab, var(--zg-text-raw) var(--zg-contrast-base), var(--zg-bg)),
|
|
1635
1645
|
var(--zg-contrast-target) var(--zg-contrast-boost)
|
|
1636
1646
|
);
|
|
1647
|
+
--zg-text-strong: color-mix(
|
|
1648
|
+
in oklab,
|
|
1649
|
+
color-mix(in oklab, var(--zg-text-strong-raw, var(--zg-text-raw)) var(--zg-contrast-base), var(--zg-bg)),
|
|
1650
|
+
var(--zg-contrast-target) var(--zg-contrast-boost)
|
|
1651
|
+
);
|
|
1637
1652
|
--zg-text-muted: color-mix(
|
|
1638
1653
|
in oklab,
|
|
1639
1654
|
color-mix(in oklab, var(--zg-text-muted-raw) var(--zg-contrast-base), var(--zg-bg)),
|
|
@@ -1775,6 +1790,16 @@ html[data-motion='off'] {
|
|
|
1775
1790
|
scale: 0.985;
|
|
1776
1791
|
}
|
|
1777
1792
|
|
|
1793
|
+
/* Restricted (`Restricted.tsx`): what a connection may read but not change,
|
|
1794
|
+
dimmed by tone and opacity together; its tooltip says why. */
|
|
1795
|
+
.zg-restricted {
|
|
1796
|
+
cursor: not-allowed;
|
|
1797
|
+
}
|
|
1798
|
+
.zg-restricted > [inert] {
|
|
1799
|
+
opacity: 0.55;
|
|
1800
|
+
filter: saturate(0.6);
|
|
1801
|
+
}
|
|
1802
|
+
|
|
1778
1803
|
/* Tooltip (`Tooltip.tsx`): visibility, the fade + 2px rise and the show
|
|
1779
1804
|
delay are driven inline by the component (one timing model for inline and
|
|
1780
1805
|
portalled bubbles). This is the hidden state before it renders. */
|
|
@@ -2005,12 +2030,10 @@ html[data-motion='off'] {
|
|
|
2005
2030
|
background: var(--zg-row-hover);
|
|
2006
2031
|
}
|
|
2007
2032
|
|
|
2008
|
-
/* The
|
|
2033
|
+
/* The section label: sentence case, as written. */
|
|
2009
2034
|
.zg-section-label {
|
|
2010
2035
|
font-size: var(--zg-font-size-badge);
|
|
2011
2036
|
font-weight: 600;
|
|
2012
|
-
letter-spacing: 0.08em;
|
|
2013
|
-
text-transform: uppercase;
|
|
2014
2037
|
/* A real label, read like any text: the muted tone (subtle is for decoration). */
|
|
2015
2038
|
color: var(--zg-text-muted);
|
|
2016
2039
|
}
|
|
@@ -2414,6 +2437,16 @@ html[data-motion='reduced'] .zg-shimmer {
|
|
|
2414
2437
|
white-space: nowrap;
|
|
2415
2438
|
}
|
|
2416
2439
|
|
|
2440
|
+
/* SmoothHeight: eases between two contents' heights while `data-easing`, then lets go. */
|
|
2441
|
+
.zg-smooth-height[data-easing] {
|
|
2442
|
+
overflow: hidden;
|
|
2443
|
+
transition: height var(--zg-motion-settle);
|
|
2444
|
+
}
|
|
2445
|
+
/* The content's own margins stay inside what is measured. */
|
|
2446
|
+
.zg-smooth-height-inner {
|
|
2447
|
+
display: flow-root;
|
|
2448
|
+
}
|
|
2449
|
+
|
|
2417
2450
|
/* HeldWidth: a trailing slot held to its widest content; content sits on
|
|
2418
2451
|
the right edge and is revealed from the left as the slot grows. */
|
|
2419
2452
|
.zg-held-width {
|
|
@@ -2836,6 +2869,33 @@ html[data-motion='reduced'] :is(.animate-spin, .zg-spin-ring, .zg-sendstop-ring)
|
|
|
2836
2869
|
`running`, Timeline `tool-running`). Applied to an absolutely positioned
|
|
2837
2870
|
ring sibling, never to the dot itself. */
|
|
2838
2871
|
|
|
2872
|
+
/* The zidane mark spinning in and out (`ZidaneMark`): a quarter turn the way
|
|
2873
|
+
its bands flow, from `--zg-mark-from` of its size (the dot it grows out
|
|
2874
|
+
of in `StatusDot`). `.zg-mark-in` plays on mount; `.zg-mark-swap` on a
|
|
2875
|
+
`Presence` plays both ways. Turn and scale ride `snap` in and `exit`
|
|
2876
|
+
out, opacity `fade` / `fade-out`. */
|
|
2877
|
+
.zg-mark-in,
|
|
2878
|
+
.zg-presence.zg-mark-swap[data-state='enter'] {
|
|
2879
|
+
animation:
|
|
2880
|
+
zg-mark-in var(--zg-motion-snap) both,
|
|
2881
|
+
zg-fade-in var(--zg-motion-fade) both;
|
|
2882
|
+
}
|
|
2883
|
+
.zg-presence.zg-mark-swap[data-state='exit'] {
|
|
2884
|
+
animation:
|
|
2885
|
+
zg-mark-out var(--zg-motion-exit) both,
|
|
2886
|
+
zg-fade-out var(--zg-motion-fade-out) both;
|
|
2887
|
+
}
|
|
2888
|
+
@keyframes zg-mark-in {
|
|
2889
|
+
from {
|
|
2890
|
+
transform: scale(var(--zg-mark-from, 0.6)) rotate(-90deg);
|
|
2891
|
+
}
|
|
2892
|
+
}
|
|
2893
|
+
@keyframes zg-mark-out {
|
|
2894
|
+
to {
|
|
2895
|
+
transform: scale(var(--zg-mark-from, 0.6)) rotate(45deg);
|
|
2896
|
+
}
|
|
2897
|
+
}
|
|
2898
|
+
|
|
2839
2899
|
@keyframes zg-orbit {
|
|
2840
2900
|
to {
|
|
2841
2901
|
transform: rotate(360deg);
|
|
@@ -3682,12 +3742,10 @@ html[data-motion='reduced'] .zg-seg > span:nth-child(-n + 3) {
|
|
|
3682
3742
|
contain-intrinsic-size: auto 28px;
|
|
3683
3743
|
}
|
|
3684
3744
|
|
|
3745
|
+
/* Active: a flat wash a step above hover, no raised chip (it read as a button). Hover keeps it. */
|
|
3685
3746
|
.zg-session-row[data-active='true']::before,
|
|
3686
|
-
.zg-session-row[data-tentative-active='true']::before
|
|
3687
|
-
|
|
3688
|
-
.zg-session-row[data-tentative-active='true']:hover::before {
|
|
3689
|
-
background: var(--zg-raised);
|
|
3690
|
-
box-shadow: var(--zg-shadow-raised);
|
|
3747
|
+
.zg-session-row[data-tentative-active='true']::before {
|
|
3748
|
+
background: var(--zg-row-active);
|
|
3691
3749
|
}
|
|
3692
3750
|
|
|
3693
3751
|
.zg-session-row:hover:not([data-active='true']):not([data-tentative-active='true'])::before {
|
|
@@ -3702,11 +3760,6 @@ html[data-motion='reduced'] .zg-seg > span:nth-child(-n + 3) {
|
|
|
3702
3760
|
box-shadow: var(--zg-shadow-well);
|
|
3703
3761
|
}
|
|
3704
3762
|
|
|
3705
|
-
.zg-session-row[data-active='true'] .zg-session-title,
|
|
3706
|
-
.zg-session-row[data-tentative-active='true'] .zg-session-title {
|
|
3707
|
-
font-weight: 500;
|
|
3708
|
-
}
|
|
3709
|
-
|
|
3710
3763
|
/* The title's color; its fade lives on the clip around it (`.zg-title-clip`). */
|
|
3711
3764
|
.zg-session-title {
|
|
3712
3765
|
color: var(--zg-text-muted);
|
|
@@ -4046,6 +4099,13 @@ html[data-motion='reduced'] .zg-orb-ripple {
|
|
|
4046
4099
|
transform-origin: var(--radix-dropdown-menu-content-transform-origin);
|
|
4047
4100
|
}
|
|
4048
4101
|
|
|
4102
|
+
/* Dark appearance: primary text at the theme's strongest, as in the sidebar. */
|
|
4103
|
+
:root.dark .zg-inbox {
|
|
4104
|
+
--zg-text: var(--zg-text-strong);
|
|
4105
|
+
/* A question's unpicked choices (QuestionField), muted elsewhere. */
|
|
4106
|
+
--zg-choice-fg: var(--zg-text-strong);
|
|
4107
|
+
}
|
|
4108
|
+
|
|
4049
4109
|
/* Inbox card resolved: lifts away on `exit` and fades on `fade-out`, then
|
|
4050
4110
|
unmounts (InboxPanel waits `readExitMs`). */
|
|
4051
4111
|
.zg-inbox-card[data-state='leaving'] {
|
|
@@ -4088,6 +4148,18 @@ html[data-motion='reduced'] .zg-orb-ripple {
|
|
|
4088
4148
|
width: 0;
|
|
4089
4149
|
}
|
|
4090
4150
|
|
|
4151
|
+
/* Dark appearance: primary text at the theme's strongest (pure white unless the theme names its text); muted and
|
|
4152
|
+
subtle keep the theme's gray. */
|
|
4153
|
+
:root.dark .zg-sidebar {
|
|
4154
|
+
--zg-text: var(--zg-text-strong);
|
|
4155
|
+
/* Project names, the New session label, the search placeholder; muted elsewhere. */
|
|
4156
|
+
--zg-sidebar-label-fg: var(--zg-text-strong);
|
|
4157
|
+
}
|
|
4158
|
+
/* Every session title, not only the active one (`.zg-session-title` is muted in chat.css). */
|
|
4159
|
+
:root.dark .zg-sidebar .zg-session-title {
|
|
4160
|
+
color: var(--zg-text);
|
|
4161
|
+
}
|
|
4162
|
+
|
|
4091
4163
|
/* Content sheet: full panel width, pinned to the aside's right edge so it
|
|
4092
4164
|
travels with it. A light opacity fade rides along (no blur, no
|
|
4093
4165
|
re-layout: nothing inside changes position relative to the sheet). */
|
|
@@ -4895,7 +4967,8 @@ a.zg-badge:hover,
|
|
|
4895
4967
|
script has not reached are dim; the running one carries the accent and the
|
|
4896
4968
|
running sweep; a call that ends washes its line once; a failed line is red,
|
|
4897
4969
|
the script's own error under it. A running script past 15 lines scrolls to
|
|
4898
|
-
follow its running line
|
|
4970
|
+
follow its running line, and keeps that window once it ends. Motion stops
|
|
4971
|
+
under reduced / off. */
|
|
4899
4972
|
/* The frame's hairline, drawn again over the lines: the sticky gutter and the
|
|
4900
4973
|
tinted lines are opaque, and covered it where they meet the frame's edge. */
|
|
4901
4974
|
.zg-script-frame::after {
|
|
@@ -4921,13 +4994,15 @@ a.zg-badge:hover,
|
|
|
4921
4994
|
.zg-code-scroll[data-wrap] .zg-script-lines {
|
|
4922
4995
|
width: auto;
|
|
4923
4996
|
}
|
|
4924
|
-
|
|
4925
|
-
|
|
4997
|
+
/* A long script's window: the frame's own scroller takes it, so one element
|
|
4998
|
+
scrolls both ways and the sticky gutter stays put sideways too. */
|
|
4999
|
+
.zg-code-scroll:has(> .zg-script-lines[data-window]) {
|
|
5000
|
+
max-height: calc(15 * 1.5 * var(--zg-font-size-code) + 1rem);
|
|
4926
5001
|
overflow-y: auto;
|
|
4927
5002
|
scroll-behavior: smooth;
|
|
4928
5003
|
}
|
|
4929
|
-
html[data-motion='off'] .zg-
|
|
4930
|
-
html[data-motion='reduced'] .zg-
|
|
5004
|
+
html[data-motion='off'] .zg-code-scroll,
|
|
5005
|
+
html[data-motion='reduced'] .zg-code-scroll {
|
|
4931
5006
|
scroll-behavior: auto;
|
|
4932
5007
|
}
|
|
4933
5008
|
.zg-script-line {
|
|
@@ -4978,6 +5053,61 @@ html[data-motion='reduced'] .zg-script-lines {
|
|
|
4978
5053
|
.zg-script-line[data-state='idle'] .zg-script-number {
|
|
4979
5054
|
opacity: 0.4;
|
|
4980
5055
|
}
|
|
5056
|
+
/* In a loop that went round again: ran in the round before, not yet in this one. */
|
|
5057
|
+
.zg-script-line[data-state='previous'] .zg-script-code {
|
|
5058
|
+
opacity: 0.6;
|
|
5059
|
+
}
|
|
5060
|
+
.zg-script-line[data-state='previous'] .zg-script-mark {
|
|
5061
|
+
opacity: 0.35;
|
|
5062
|
+
}
|
|
5063
|
+
/* A `sleep`: the running tint, softer, and its mark breathing. */
|
|
5064
|
+
.zg-script-line[data-state='waiting'] {
|
|
5065
|
+
--zg-script-tint: color-mix(in srgb, var(--zg-accent-wash) 40%, transparent);
|
|
5066
|
+
--zg-script-bar: color-mix(in srgb, var(--zg-accent) 60%, transparent);
|
|
5067
|
+
}
|
|
5068
|
+
.zg-script-line[data-state='waiting'] .zg-script-gutter {
|
|
5069
|
+
color: var(--zg-accent);
|
|
5070
|
+
}
|
|
5071
|
+
.zg-script-line[data-state='waiting'] .zg-script-mark {
|
|
5072
|
+
animation: zg-script-breathe 2s ease-in-out infinite;
|
|
5073
|
+
}
|
|
5074
|
+
html[data-motion='off'] .zg-script-line .zg-script-mark,
|
|
5075
|
+
html[data-motion='reduced'] .zg-script-line .zg-script-mark {
|
|
5076
|
+
animation: none;
|
|
5077
|
+
}
|
|
5078
|
+
|
|
5079
|
+
/* Loops: the first line's mark, and while the script is in a loop, its line
|
|
5080
|
+
numbers in the running color. */
|
|
5081
|
+
.zg-script-loop {
|
|
5082
|
+
color: var(--zg-text-subtle);
|
|
5083
|
+
transition: color var(--zg-motion-fade);
|
|
5084
|
+
}
|
|
5085
|
+
.zg-script-loop[data-active] {
|
|
5086
|
+
color: var(--zg-accent);
|
|
5087
|
+
}
|
|
5088
|
+
.zg-script-line[data-in-loop] .zg-script-number {
|
|
5089
|
+
color: color-mix(in srgb, var(--zg-accent) 75%, var(--zg-text-subtle));
|
|
5090
|
+
}
|
|
5091
|
+
|
|
5092
|
+
/* After a line's code: a loop's round, a line's call count, a wait's time left. */
|
|
5093
|
+
.zg-script-note {
|
|
5094
|
+
display: inline-flex;
|
|
5095
|
+
align-items: center;
|
|
5096
|
+
gap: 0.25rem;
|
|
5097
|
+
margin-inline-start: 0.625ch;
|
|
5098
|
+
border-radius: var(--zg-radius-xs);
|
|
5099
|
+
font-family: var(--zg-font-ui);
|
|
5100
|
+
font-size: 0.85em;
|
|
5101
|
+
color: var(--zg-text-subtle);
|
|
5102
|
+
font-variant-numeric: tabular-nums;
|
|
5103
|
+
vertical-align: 0.05em;
|
|
5104
|
+
transition: color var(--zg-motion-fade);
|
|
5105
|
+
}
|
|
5106
|
+
.zg-script-note[data-active] {
|
|
5107
|
+
padding-inline: 0.375rem;
|
|
5108
|
+
color: var(--zg-accent);
|
|
5109
|
+
background: color-mix(in srgb, var(--zg-accent-wash) 60%, transparent);
|
|
5110
|
+
}
|
|
4981
5111
|
/* A line's tint and bar come from its state. The gutter stays opaque (code
|
|
4982
5112
|
scrolled sideways passes under it): the tint goes on a layer over its own
|
|
4983
5113
|
background, and the bar sits on it, so both stay in place while scrolling. */
|
|
@@ -5032,6 +5162,12 @@ html[data-motion='reduced'] .zg-script-line::after {
|
|
|
5032
5162
|
animation: none;
|
|
5033
5163
|
}
|
|
5034
5164
|
|
|
5165
|
+
@keyframes zg-script-breathe {
|
|
5166
|
+
50% {
|
|
5167
|
+
opacity: 0.4;
|
|
5168
|
+
}
|
|
5169
|
+
}
|
|
5170
|
+
|
|
5035
5171
|
@keyframes zg-script-settle {
|
|
5036
5172
|
from {
|
|
5037
5173
|
background-color: color-mix(in srgb, var(--zg-success-soft) 80%, transparent);
|
|
@@ -6,9 +6,9 @@ import { matchesBinding } from "../keybindings/match.js";
|
|
|
6
6
|
import { useKeybindingsHost } from "../keybindings/KeybindingsProvider.js";
|
|
7
7
|
import { useSymbolsFontUrl, useTerminalActions, useTerminalStore } from "./TerminalProvider.js";
|
|
8
8
|
import { useLinkRouter } from "../extensions/links.js";
|
|
9
|
+
import { detectLinks, linkTarget, resolveTerminalPath, serverOnlyLink } from "./headless/links.js";
|
|
9
10
|
import { loadGhostty, openTerminal } from "./ghostty.js";
|
|
10
11
|
import { terminalFont } from "./grid-size.js";
|
|
11
|
-
import { detectLinks, linkTarget, resolveTerminalPath, serverOnlyLink } from "./headless/links.js";
|
|
12
12
|
import { planChunk, planReset, shouldAck } from "./headless/output-cursor.js";
|
|
13
13
|
import { feedSlices, yieldToEventLoop } from "./headless/replay.js";
|
|
14
14
|
import { macTerminalKey } from "./keys.js";
|
|
@@ -14,6 +14,24 @@ type TerminalLink = {
|
|
|
14
14
|
line?: number;
|
|
15
15
|
column?: number;
|
|
16
16
|
};
|
|
17
|
+
/** Where in a file a path points: 1-based. */
|
|
18
|
+
interface PathPosition {
|
|
19
|
+
/** The line. */
|
|
20
|
+
line: number;
|
|
21
|
+
/** The column. */
|
|
22
|
+
column?: number;
|
|
23
|
+
/** The last line of a range. */
|
|
24
|
+
endLine?: number;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* A path written with a position at its end, split into both, as the terminal's links read one (plus a range's
|
|
28
|
+
* end and GitHub's `#L12`). `null` when the text ends in no position, or in line 0.
|
|
29
|
+
*
|
|
30
|
+
* @param text - The text, trimmed.
|
|
31
|
+
*/
|
|
32
|
+
declare function splitPathPosition(text: string): ({
|
|
33
|
+
path: string;
|
|
34
|
+
} & PathPosition) | null;
|
|
17
35
|
/**
|
|
18
36
|
* Links on one line. URLs with a scheme are only used to keep paths out of
|
|
19
37
|
* them (`https://x.dev/a/b.ts` is not a path): the library links those
|
|
@@ -54,4 +72,4 @@ declare function resolveTerminalPath(path: string, cwd: string, home?: string):
|
|
|
54
72
|
*/
|
|
55
73
|
declare function serverOnlyLink(url: string, serverName: string | null, describe: (serverName: string) => string): string | null;
|
|
56
74
|
//#endregion
|
|
57
|
-
export { LinkTarget, TerminalLink, detectLinks, linkTarget, resolveTerminalPath, serverOnlyLink };
|
|
75
|
+
export { LinkTarget, PathPosition, TerminalLink, detectLinks, linkTarget, resolveTerminalPath, serverOnlyLink, splitPathPosition };
|
|
@@ -13,7 +13,31 @@ function basename(path) {
|
|
|
13
13
|
}
|
|
14
14
|
const URL_RE = /\bhttps?:\/\/[^\s"'<>`]+/g;
|
|
15
15
|
const LOCAL_RE = /(?<![\w./:@-])(?:localhost|127\.0\.0\.1|0\.0\.0\.0|\[::1\]):\d{2,5}(?:\/[^\s"'<>`]*)?/g;
|
|
16
|
-
|
|
16
|
+
/** A position after a path: `:12`, `:12:5` or `(12,5)` (tsc). Groups: line, column, tsc line, tsc column. */
|
|
17
|
+
const POSITION = String.raw`(?::(\d+)(?::(\d+))?|\((\d+),(\d+)\))`;
|
|
18
|
+
const PATH_RE = new RegExp(String.raw`(?<![\w./@+~-])((?:\.{1,2}\/|~\/|\/)?(?:[\w.@+-]+\/)*[\w.@+-]+)${POSITION}?`, "g");
|
|
19
|
+
/** A whole text ending in a position: the terminal's, a range's end (`:12-20`), or GitHub's `#L12`, `#L12C5`, `#L12-L20`. */
|
|
20
|
+
const ENDS_IN_POSITION = new RegExp(String.raw`^(.+?)(?:${POSITION}(?:-(\d+))?|#L(\d+)(?:C(\d+))?(?:-L?(\d+))?)$`);
|
|
21
|
+
/**
|
|
22
|
+
* A path written with a position at its end, split into both, as the terminal's links read one (plus a range's
|
|
23
|
+
* end and GitHub's `#L12`). `null` when the text ends in no position, or in line 0.
|
|
24
|
+
*
|
|
25
|
+
* @param text - The text, trimmed.
|
|
26
|
+
*/
|
|
27
|
+
function splitPathPosition(text) {
|
|
28
|
+
const m = ENDS_IN_POSITION.exec(text);
|
|
29
|
+
if (!m) return null;
|
|
30
|
+
const line = Number(m[2] ?? m[4] ?? m[7]);
|
|
31
|
+
if (!(line >= 1)) return null;
|
|
32
|
+
const column = m[3] ?? m[5] ?? m[8];
|
|
33
|
+
const endLine = m[6] ?? m[9];
|
|
34
|
+
return {
|
|
35
|
+
path: m[1],
|
|
36
|
+
line,
|
|
37
|
+
...column ? { column: Number(column) } : {},
|
|
38
|
+
...endLine && Number(endLine) > line ? { endLine: Number(endLine) } : {}
|
|
39
|
+
};
|
|
40
|
+
}
|
|
17
41
|
/** Extensions that make a bare name (no slash, no position) read as a file. */
|
|
18
42
|
const FILE_EXTENSIONS = new Set("ts tsx js jsx mjs cjs mts cts json jsonc md mdx py rs go rb java kt kts swift c h cc cpp hpp cs css scss sass less html htm vue svelte astro yml yaml toml lock sh bash zsh fish txt sql graphql gql proto xml ini env conf cfg php ex exs erl hs ml zig nim lua dart scala clj r jl tf".split(" "));
|
|
19
43
|
/** Trailing characters that end a sentence rather than an address. */
|
|
@@ -197,4 +221,4 @@ function serverOnlyLink(url, serverName, describe) {
|
|
|
197
221
|
return LOOPBACK_HOSTS.has(host) || host.endsWith(".localhost") ? describe(serverName) : null;
|
|
198
222
|
}
|
|
199
223
|
//#endregion
|
|
200
|
-
export { detectLinks, linkTarget, resolveTerminalPath, serverOnlyLink };
|
|
224
|
+
export { detectLinks, linkTarget, resolveTerminalPath, serverOnlyLink, splitPathPosition };
|
package/dist/theme/css-vars.js
CHANGED
|
@@ -18,6 +18,7 @@ function paletteToCssVars(p) {
|
|
|
18
18
|
"--zg-border-strong": p.borderStrong,
|
|
19
19
|
"--zg-ring": p.ring,
|
|
20
20
|
"--zg-text-raw": p.text,
|
|
21
|
+
"--zg-text-strong-raw": p.textStrong,
|
|
21
22
|
"--zg-text-muted-raw": p.textMuted,
|
|
22
23
|
"--zg-text-subtle-raw": p.textSubtle,
|
|
23
24
|
"--zg-accent": p.accent,
|
package/dist/theme/derive.d.ts
CHANGED
|
@@ -14,6 +14,8 @@ interface ThemeSeed {
|
|
|
14
14
|
appearance?: Appearance;
|
|
15
15
|
/** Body text. Derived from `canvas` with a faint tint when omitted. */
|
|
16
16
|
text?: string;
|
|
17
|
+
/** Primary text where it reads strongest (the sidebar and the inbox in dark). Defaults to white in dark, `text` in light. */
|
|
18
|
+
textStrong?: string;
|
|
17
19
|
/** Secondary text. Pushed until it clears its contrast floor. */
|
|
18
20
|
textMuted?: string;
|
|
19
21
|
/** Tertiary text, such as hints. Pushed until it clears its contrast floor. */
|
|
@@ -189,6 +191,8 @@ interface ResolvedPalette {
|
|
|
189
191
|
ring: string;
|
|
190
192
|
/** Body text. */
|
|
191
193
|
text: string;
|
|
194
|
+
/** Primary text where it reads strongest (the sidebar and the inbox in dark). */
|
|
195
|
+
textStrong: string;
|
|
192
196
|
/** Secondary text. */
|
|
193
197
|
textMuted: string;
|
|
194
198
|
/** Tertiary text, such as hints. */
|
package/dist/theme/derive.js
CHANGED
|
@@ -184,6 +184,7 @@ function derivePalette(seed) {
|
|
|
184
184
|
const hoverWash = dark ? "rgba(255, 255, 255, 0.05)" : "rgba(0, 0, 0, 0.04)";
|
|
185
185
|
const textBase = seed.text ?? tintedNeutral(dark ? .93 : .24, tintSource, tint * .5);
|
|
186
186
|
const text = ensureContrast(textBase, surface2, CONTRAST.text);
|
|
187
|
+
const textStrong = ensureContrast(seed.textStrong ?? (dark ? "#ffffff" : text), surface2, CONTRAST.text);
|
|
187
188
|
const textMuted = ensureContrast(seed.textMuted ?? mix(text, bg, .42), surface2, CONTRAST.textMuted);
|
|
188
189
|
const textSubtle = ensureContrast(seed.textSubtle ?? mix(text, bg, .62), bg, CONTRAST.textSubtle);
|
|
189
190
|
const accent = ensureContrast(seed.accent, bg, 3);
|
|
@@ -256,6 +257,7 @@ function derivePalette(seed) {
|
|
|
256
257
|
text,
|
|
257
258
|
textMuted,
|
|
258
259
|
textSubtle,
|
|
260
|
+
textStrong,
|
|
259
261
|
accentFg,
|
|
260
262
|
accentFill,
|
|
261
263
|
accentFillHover,
|