zidane-ui 9.1.4 → 9.1.5
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/server-extensions-host.js +1 -1
- package/dist/adapters/server-host.js +2 -1
- package/dist/adapters/server-machines-host.js +1 -1
- package/dist/adapters/server-session-host.js +87 -13
- package/dist/adapters/server-settings-host.js +1 -1
- package/dist/appearance/AppearanceProvider.js +2 -2
- package/dist/appearance/headless/index.js +1 -1
- package/dist/approvals/headless/index.js +2 -2
- package/dist/chat/HostTranscript.d.ts +5 -1
- package/dist/chat/HostTranscript.js +16 -4
- package/dist/chat/RunEstimateChip.d.ts +5 -3
- package/dist/chat/RunEstimateChip.js +33 -3
- package/dist/chat/Transcript.js +1 -1
- package/dist/chat/composer/ComposerEditor.js +1 -1
- package/dist/chat/composer/ConversationBadges.js +16 -10
- package/dist/chat/composer/composer-bus.d.ts +2 -2
- package/dist/chat/composer/composer-bus.js +2 -2
- package/dist/chat/composer/use-composer-stores.js +1 -1
- package/dist/chat/composer/use-run-meter.js +1 -1
- package/dist/chat/headless/composer/conversation-badges.d.ts +8 -3
- package/dist/chat/headless/composer/conversation-badges.js +26 -11
- package/dist/chat/headless/composer/index.js +2 -2
- package/dist/chat/headless/composer/labels-chrome.d.ts +3 -1
- package/dist/chat/headless/composer/labels-chrome.js +3 -1
- package/dist/chat/headless/index.d.ts +5 -3
- package/dist/chat/headless/index.js +16 -14
- package/dist/chat/headless/labels.d.ts +54 -1
- package/dist/chat/headless/labels.js +62 -2
- package/dist/chat/headless/secrets.d.ts +32 -0
- package/dist/chat/headless/secrets.js +43 -0
- package/dist/chat/headless/session-list.d.ts +45 -0
- package/dist/chat/headless/sidebar/estimates.js +13 -1
- package/dist/chat/headless/sidebar/index.d.ts +2 -2
- package/dist/chat/headless/sidebar/labels.d.ts +50 -0
- package/dist/chat/headless/sidebar/labels.js +1 -0
- package/dist/chat/headless/sidebar/query.d.ts +2 -2
- package/dist/chat/headless/sidebar/query.js +6 -3
- package/dist/chat/headless/sidebar/types.d.ts +7 -1
- package/dist/chat/headless/sidebar/view.js +2 -0
- package/dist/chat/headless/transcript/auth-failure.d.ts +67 -0
- package/dist/chat/headless/transcript/auth-failure.js +87 -0
- package/dist/chat/headless/transcript/index.d.ts +2 -1
- package/dist/chat/headless/transcript/index.js +2 -1
- package/dist/chat/headless/transcript/nesting.d.ts +3 -3
- package/dist/chat/headless/transcript/nesting.js +12 -4
- package/dist/chat/index.d.ts +4 -2
- package/dist/chat/index.js +3 -1
- package/dist/chat/interactions/InboxPanel.d.ts +6 -2
- package/dist/chat/interactions/InboxPanel.js +82 -44
- package/dist/chat/interactions/PlanCard.d.ts +2 -2
- package/dist/chat/interactions/PlanCard.js +1 -1
- package/dist/chat/interactions/QuestionField.d.ts +8 -3
- package/dist/chat/interactions/QuestionField.js +89 -8
- package/dist/chat/interactions/QuestionForm.d.ts +3 -1
- package/dist/chat/interactions/QuestionForm.js +48 -10
- package/dist/chat/interactions/SecretInput.d.ts +32 -0
- package/dist/chat/interactions/SecretInput.js +72 -0
- package/dist/chat/interactions/card-ui.d.ts +5 -3
- package/dist/chat/interactions/card-ui.js +5 -3
- package/dist/chat/interactions/index.d.ts +2 -1
- package/dist/chat/interactions/index.js +2 -1
- package/dist/chat/sidebar/SessionSidebar.js +2 -0
- package/dist/chat/sidebar/SidebarFilterMenu.d.ts +7 -2
- package/dist/chat/sidebar/SidebarFilterMenu.js +26 -2
- package/dist/chat/sidebar/SidebarSessionRow.d.ts +3 -1
- package/dist/chat/sidebar/SidebarSessionRow.js +8 -3
- package/dist/chat/sidebar/sidebar-live.js +8 -4
- package/dist/chat/transcript/AuthFailureCard.d.ts +34 -0
- package/dist/chat/transcript/AuthFailureCard.js +358 -0
- package/dist/chat/transcript/InteractionToolBody.js +12 -2
- package/dist/chat/transcript/actions.d.ts +24 -1
- package/dist/chat/transcript/index.d.ts +3 -2
- package/dist/chat/transcript/index.js +2 -1
- package/dist/chat/transcript/notices.d.ts +2 -1
- package/dist/chat/transcript/notices.js +13 -1
- package/dist/chat/transcript/script-input.d.ts +1 -1
- package/dist/chat/transcript/shell-block.js +1 -1
- package/dist/components/HowItWorks.d.ts +8 -1
- package/dist/components/HowItWorks.js +2 -2
- package/dist/components/RowActionsMenu.d.ts +6 -1
- package/dist/components/RowActionsMenu.js +4 -0
- package/dist/core.css +24 -0
- package/dist/dist/{index-WlE93Q6d.d.ts → index-BI6RZc60.d.ts} +36 -3
- package/dist/dist/index-f-XWIoYo.d.ts +1 -0
- package/dist/dist/index.d.ts +6 -0
- package/dist/dist/sandbox-B4OW6oNx.d.ts +2 -0
- package/dist/dist/timeout-B5pO5I5a.d.ts +30 -0
- package/dist/extensions/ExtensionSettingsPage.js +1 -1
- package/dist/extensions/ExtensionSettingsSidebar.js +1 -1
- package/dist/extensions/headless/fixture-host.js +1 -1
- package/dist/extensions/headless/index.js +4 -4
- package/dist/extensions/hooks.js +1 -1
- package/dist/files/DiffsTab.js +1 -1
- package/dist/files/EditorColumn.js +1 -1
- package/dist/files/MediaDiff.js +1 -1
- package/dist/files/SearchPanel.js +121 -53
- package/dist/files/headless/name-match.js +29 -14
- package/dist/files/useEntryActions.js +1 -1
- package/dist/files/useOpenFiles.js +1 -1
- package/dist/git/WherePicker.js +2 -2
- package/dist/git/headless/environment.d.ts +6 -1
- package/dist/git/headless/environment.js +5 -2
- package/dist/git/headless/labels.d.ts +2 -0
- package/dist/git/headless/labels.js +2 -0
- package/dist/git/index.d.ts +2 -1
- package/dist/git/index.js +2 -1
- package/dist/git/useStartFromPanel.d.ts +22 -0
- package/dist/git/useStartFromPanel.js +91 -0
- package/dist/keybindings/KeyCommands.js +1 -1
- package/dist/keybindings/KeybindingsProvider.js +1 -1
- package/dist/keybindings/headless/catalog.js +2 -2
- package/dist/keybindings/headless/index.js +2 -2
- package/dist/keybindings/headless/overrides.js +1 -1
- package/dist/machines/HostSyncPanel.js +1 -1
- package/dist/machines/SyncOutcomeBadge.js +1 -1
- package/dist/machines/headless/index.js +1 -1
- package/dist/onboarding/demos/features.d.ts +9 -1
- package/dist/onboarding/demos/features.js +107 -2
- package/dist/onboarding/demos/how-it-works.d.ts +5 -1
- package/dist/onboarding/demos/how-it-works.js +120 -2
- package/dist/onboarding/demos/index.js +1 -1
- package/dist/onboarding/headless/labels.d.ts +17 -0
- package/dist/onboarding/headless/labels.js +17 -0
- package/dist/onboarding/index.js +4 -4
- package/dist/onboarding/marks.d.ts +1 -2
- package/dist/onboarding/marks.js +4 -12
- package/dist/onboarding/steps/ConnectorsStep.js +1 -1
- package/dist/onboarding/steps/ReadyStep.js +1 -1
- package/dist/onboarding/steps/SkillsStep.js +1 -1
- package/dist/onboarding/steps/connect/ProviderPanel.js +1 -1
- package/dist/onboarding/tutorials.d.ts +3 -1
- package/dist/onboarding/tutorials.js +2 -1
- package/dist/palette/app-sources.js +1 -1
- package/dist/session/ArtifactsPanel.js +1 -1
- package/dist/session/PanelAttention.d.ts +14 -6
- package/dist/session/PanelAttention.js +35 -24
- package/dist/session/PlanTracker.d.ts +54 -0
- package/dist/session/PlanTracker.js +412 -0
- package/dist/session/ProjectHome.d.ts +15 -2
- package/dist/session/ProjectHome.js +158 -85
- package/dist/session/RemindersPanel.d.ts +25 -0
- package/dist/session/RemindersPanel.js +526 -0
- package/dist/session/SecretsPanel.d.ts +19 -0
- package/dist/session/SecretsPanel.js +241 -0
- package/dist/session/SessionProvider.d.ts +26 -5
- package/dist/session/SessionProvider.js +51 -6
- package/dist/session/StepStatusIcon.d.ts +24 -0
- package/dist/session/StepStatusIcon.js +50 -0
- package/dist/session/TodoList.d.ts +4 -3
- package/dist/session/TodoList.js +6 -5
- package/dist/session/headless/fixture-host.d.ts +32 -22
- package/dist/session/headless/fixture-host.js +86 -51
- package/dist/session/headless/fixture-plans.d.ts +57 -0
- package/dist/session/headless/fixture-plans.js +141 -0
- package/dist/session/headless/fixture-schedules.d.ts +49 -0
- package/dist/session/headless/fixture-schedules.js +133 -0
- package/dist/session/headless/home-layout.d.ts +10 -2
- package/dist/session/headless/home-layout.js +7 -2
- package/dist/session/headless/host.d.ts +85 -13
- package/dist/session/headless/index.d.ts +5 -3
- package/dist/session/headless/index.js +5 -3
- package/dist/session/headless/labels.d.ts +95 -12
- package/dist/session/headless/labels.js +67 -18
- package/dist/session/headless/plans.d.ts +53 -0
- package/dist/session/headless/plans.js +78 -0
- package/dist/session/headless/reminder-labels.d.ts +63 -0
- package/dist/session/headless/reminder-labels.js +84 -0
- package/dist/session/headless/schedules.d.ts +93 -0
- package/dist/session/headless/schedules.js +190 -0
- package/dist/session/headless/secrets.d.ts +28 -0
- package/dist/session/headless/secrets.js +48 -0
- package/dist/session/index.d.ts +7 -5
- package/dist/session/index.js +6 -4
- package/dist/session/testing/contract.d.ts +18 -5
- package/dist/session/testing/contract.js +351 -43
- package/dist/session/testing/index.d.ts +4 -2
- package/dist/session/testing/index.js +4 -2
- package/dist/settings/headless/catalog.js +17 -1
- package/dist/settings/headless/index.d.ts +2 -2
- package/dist/settings/headless/index.js +3 -3
- package/dist/settings/headless/labels.d.ts +0 -2
- package/dist/settings/headless/labels.js +0 -2
- package/dist/settings/headless/layout.js +7 -1
- package/dist/settings/headless/providers.d.ts +17 -1
- package/dist/settings/headless/providers.js +19 -1
- package/dist/settings/headless/search.d.ts +1 -1
- package/dist/settings/rows.d.ts +1 -1
- package/dist/settings/rows.js +2 -2
- package/dist/settings/sections/appearance/AppearanceSection.js +2 -2
- package/dist/settings/sections/claude-import/ClaudeImportDialog.js +1 -1
- package/dist/settings/sections/editor/EditorSection.js +1 -1
- package/dist/settings/sections/environments/EnvironmentsSection.js +1 -1
- package/dist/settings/sections/extensions/ChangeOriginDialog.js +1 -1
- package/dist/settings/sections/extensions/CreateExtensionDialog.js +1 -1
- package/dist/settings/sections/extensions/ExtensionsSection.js +1 -1
- package/dist/settings/sections/host-catalog/HostCatalogSection.js +1 -1
- package/dist/settings/sections/instructions/InstructionsSection.js +1 -1
- package/dist/settings/sections/mcp/McpSection.js +1 -1
- package/dist/settings/sections/mcp/McpServerRow.js +1 -1
- package/dist/settings/sections/models/ModelRows.js +2 -2
- package/dist/settings/sections/providers/ProvidersSection.js +209 -201
- package/dist/settings/sections/providers/ServerProvidersSection.js +1 -1
- package/dist/settings/sections/shared/catalog.js +1 -1
- package/dist/settings/sections/skills/SkillsSection.js +2 -2
- package/dist/styles.css +59 -1
- package/dist/terminal/HostTerminalSurface.js +2 -2
- package/dist/workspace/PanelContentView.d.ts +22 -4
- package/dist/workspace/PanelContentView.js +112 -16
- package/dist/workspace/PanelGlyph.d.ts +21 -0
- package/dist/workspace/PanelGlyph.js +33 -0
- package/dist/workspace/PanelHome.js +5 -3
- package/dist/workspace/PanelStrip.js +11 -4
- package/dist/workspace/PanelToolbar.d.ts +32 -0
- package/dist/workspace/PanelToolbar.js +194 -0
- package/dist/workspace/WorkspaceProvider.d.ts +3 -1
- package/dist/workspace/WorkspaceProvider.js +6 -2
- package/dist/workspace/extension-tabs.js +5 -2
- package/dist/workspace/headless/host.d.ts +4 -0
- package/dist/workspace/headless/index.d.ts +3 -1
- package/dist/workspace/headless/index.js +4 -2
- package/dist/workspace/headless/labels.d.ts +10 -0
- package/dist/workspace/headless/labels.js +11 -1
- package/dist/workspace/headless/pages.d.ts +15 -0
- package/dist/workspace/headless/pages.js +49 -0
- package/dist/workspace/headless/tab-mark.d.ts +14 -0
- package/dist/workspace/headless/tab-mark.js +27 -0
- package/dist/workspace/headless/view.d.ts +7 -1
- package/dist/workspace/index.d.ts +3 -2
- package/dist/workspace/index.js +3 -2
- package/dist/workspace/testing/index.js +6 -0
- package/dist/workspace/workspace-key-commands.js +3 -3
- package/package.json +2 -2
- package/src/styles/motion.css +13 -0
- package/src/styles/onboarding.css +0 -1
- package/src/styles/primitives.css +10 -0
- package/src/styles/workspace.css +17 -0
- package/dist/session/TodosPanel.d.ts +0 -19
- package/dist/session/TodosPanel.js +0 -251
- package/dist/session/headless/todos.d.ts +0 -22
- package/dist/session/headless/todos.js +0 -38
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { writable } from "../chat/headless/store.js";
|
|
2
|
-
import { ExtensionsHostError } from "../extensions/headless/host.js";
|
|
3
2
|
import { createServerWebviewSources } from "./extension-modules.js";
|
|
4
3
|
import { createDialogQueue } from "../extensions/headless/dialog-queue.js";
|
|
5
4
|
import { createUiEffectChannel } from "../extensions/headless/effect-channel.js";
|
|
5
|
+
import { ExtensionsHostError } from "../extensions/headless/host.js";
|
|
6
6
|
import { EXTENSION_TOKENS } from "../extensions/headless/wire.js";
|
|
7
7
|
import { IpcErrorCode, ServerCallError, ServerConnectionError, createExtensionsClient } from "zidane/ipc/browser";
|
|
8
8
|
//#region src/adapters/server-extensions-host.ts
|
|
@@ -42,7 +42,8 @@ function toSidebarListSession(row) {
|
|
|
42
42
|
...row.isMain ? { isMain: true } : {},
|
|
43
43
|
...row.favorite ? { favorite: true } : {},
|
|
44
44
|
...row.agentId ? { agentId: row.agentId } : {},
|
|
45
|
-
...row.facets && Object.keys(row.facets).length > 0 ? { facets: row.facets } : {}
|
|
45
|
+
...row.facets && Object.keys(row.facets).length > 0 ? { facets: row.facets } : {},
|
|
46
|
+
...row.scheduleId ? { scheduleId: row.scheduleId } : {}
|
|
46
47
|
};
|
|
47
48
|
}
|
|
48
49
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { machinesError } from "../machines/headless/host.js";
|
|
2
1
|
import { closableClient } from "./closable-client.js";
|
|
2
|
+
import { machinesError } from "../machines/headless/host.js";
|
|
3
3
|
import { createPresenceStore } from "../machines/headless/presence.js";
|
|
4
4
|
import { createMachineLists, createOnlineMachines, lazyReadable } from "../machines/headless/stores.js";
|
|
5
5
|
import { createHostSyncReads } from "../machines/headless/sync.js";
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { createArtifactsState, groupArtifactRows, plainArtifactRow } from "../session/headless/artifacts.js";
|
|
2
2
|
import { createQueueState } from "../session/headless/queue.js";
|
|
3
3
|
import { createRunningWorkState } from "../session/headless/running-work.js";
|
|
4
|
-
import {
|
|
4
|
+
import { createSchedulesState } from "../session/headless/schedules.js";
|
|
5
|
+
import { createPlansState } from "../session/headless/plans.js";
|
|
6
|
+
import { createSecretsState } from "../session/headless/secrets.js";
|
|
5
7
|
//#region src/adapters/server-session-host.ts
|
|
6
8
|
/**
|
|
7
9
|
* Creates a {@link SessionHost} over a zidane-server client.
|
|
@@ -10,7 +12,7 @@ import { createTodosState } from "../session/headless/todos.js";
|
|
|
10
12
|
*/
|
|
11
13
|
function createServerSessionHost(options) {
|
|
12
14
|
const { client, saveExport } = options;
|
|
13
|
-
const
|
|
15
|
+
const plans = createPlansState((sessionId) => client.call("plans.get", { sessionId }));
|
|
14
16
|
const queue = createQueueState({
|
|
15
17
|
list: (sessionId) => client.call("queue.list", { sessionId }),
|
|
16
18
|
remove: (sessionId, id) => client.call("queue.remove", {
|
|
@@ -26,10 +28,15 @@ function createServerSessionHost(options) {
|
|
|
26
28
|
});
|
|
27
29
|
const work = createRunningWorkState((sessionId) => client.call("chat.listWork", { sessionId }));
|
|
28
30
|
const artifacts = createArtifactsState(async (sessionId) => groupArtifactRows((await client.call("sessions.artifacts", { sessionId })).map(plainArtifactRow)));
|
|
31
|
+
const secrets = createSecretsState((sessionId) => client.call("secrets.list", { sessionId }));
|
|
32
|
+
const schedules = client.can("schedules.status") ? createSchedulesState({
|
|
33
|
+
status: () => client.call("schedules.status", {}),
|
|
34
|
+
list: () => client.call("schedules.list", {})
|
|
35
|
+
}) : null;
|
|
29
36
|
const onSignal = (signal) => {
|
|
30
37
|
switch (signal.kind) {
|
|
31
|
-
case "
|
|
32
|
-
|
|
38
|
+
case "plans:snapshot":
|
|
39
|
+
plans.push(signal.sessionId, signal.snapshot);
|
|
33
40
|
break;
|
|
34
41
|
case "queue:changed":
|
|
35
42
|
queue.replace(signal.sessionId, signal.items);
|
|
@@ -41,20 +48,43 @@ function createServerSessionHost(options) {
|
|
|
41
48
|
case "work:snapshot":
|
|
42
49
|
work.push(signal.sessionId, signal.items);
|
|
43
50
|
break;
|
|
44
|
-
case "
|
|
51
|
+
case "secrets:changed":
|
|
52
|
+
secrets.wakeAll();
|
|
53
|
+
break;
|
|
54
|
+
case "schedules:changed":
|
|
55
|
+
case "settings:changed":
|
|
56
|
+
schedules?.wake();
|
|
57
|
+
break;
|
|
58
|
+
case "sessions:changed": if (signal.op === "delete") {
|
|
59
|
+
plans.forget(signal.sessionId);
|
|
60
|
+
secrets.forget(signal.sessionId);
|
|
61
|
+
}
|
|
45
62
|
}
|
|
46
63
|
};
|
|
47
64
|
const unsubscribe = [client.onSignal(onSignal), client.onOpen((_hello, reconnected) => {
|
|
48
|
-
if (reconnected)
|
|
65
|
+
if (reconnected) {
|
|
66
|
+
queue.reset(true);
|
|
67
|
+
schedules?.wake();
|
|
68
|
+
}
|
|
49
69
|
})];
|
|
50
70
|
return {
|
|
51
|
-
|
|
52
|
-
snapshot:
|
|
53
|
-
refresh:
|
|
54
|
-
|
|
55
|
-
sessionId,
|
|
56
|
-
|
|
57
|
-
|
|
71
|
+
plans: {
|
|
72
|
+
snapshot: plans.snapshot,
|
|
73
|
+
refresh: plans.refresh,
|
|
74
|
+
...client.can("plans.edit") ? { edit: async (sessionId, planId, op) => {
|
|
75
|
+
plans.push(sessionId, await client.call("plans.edit", {
|
|
76
|
+
sessionId,
|
|
77
|
+
planId,
|
|
78
|
+
op
|
|
79
|
+
}));
|
|
80
|
+
} } : {},
|
|
81
|
+
...client.can("plans.control") ? { control: async (sessionId, planId, action) => {
|
|
82
|
+
plans.push(sessionId, await client.call("plans.control", {
|
|
83
|
+
sessionId,
|
|
84
|
+
planId,
|
|
85
|
+
action
|
|
86
|
+
}));
|
|
87
|
+
} } : {},
|
|
58
88
|
retry: async (sessionId, message) => {
|
|
59
89
|
await client.call("chat.pushQueued", {
|
|
60
90
|
sessionId,
|
|
@@ -190,6 +220,50 @@ function createServerSessionHost(options) {
|
|
|
190
220
|
if (signal.kind === "sessions:changed" && signal.op === "update") onChange(signal.sessionId);
|
|
191
221
|
})
|
|
192
222
|
} } : {},
|
|
223
|
+
...client.can("secrets.list") ? { secrets: {
|
|
224
|
+
entries: secrets.entries,
|
|
225
|
+
refresh: secrets.refresh,
|
|
226
|
+
...client.can("secrets.save") ? { save: (sessionId, input) => client.call("secrets.save", {
|
|
227
|
+
sessionId,
|
|
228
|
+
name: input.name,
|
|
229
|
+
value: input.value,
|
|
230
|
+
ttl: input.ttl
|
|
231
|
+
}) } : {},
|
|
232
|
+
...client.can("secrets.revoke") ? { revoke: async (sessionId, name) => (await client.call("secrets.revoke", {
|
|
233
|
+
sessionId,
|
|
234
|
+
name
|
|
235
|
+
})).removed } : {}
|
|
236
|
+
} } : {},
|
|
237
|
+
...schedules ? { schedules: {
|
|
238
|
+
status: schedules.status,
|
|
239
|
+
all: schedules.all,
|
|
240
|
+
forSession: schedules.forSession,
|
|
241
|
+
refresh: schedules.refresh,
|
|
242
|
+
ensure: schedules.ensure,
|
|
243
|
+
async create(input) {
|
|
244
|
+
const created = await client.call("schedules.create", input);
|
|
245
|
+
schedules.apply(created);
|
|
246
|
+
return created;
|
|
247
|
+
},
|
|
248
|
+
async update(id, patch) {
|
|
249
|
+
const updated = await client.call("schedules.update", {
|
|
250
|
+
id,
|
|
251
|
+
patch
|
|
252
|
+
});
|
|
253
|
+
schedules.apply(updated);
|
|
254
|
+
return updated;
|
|
255
|
+
},
|
|
256
|
+
async remove(id) {
|
|
257
|
+
const removed = await client.call("schedules.delete", { id });
|
|
258
|
+
schedules.drop(id);
|
|
259
|
+
return removed;
|
|
260
|
+
},
|
|
261
|
+
runNow: (id) => client.call("schedules.runNow", { id }),
|
|
262
|
+
fires: (id, limit) => client.call("schedules.fires", {
|
|
263
|
+
id,
|
|
264
|
+
...limit !== void 0 ? { limit } : {}
|
|
265
|
+
})
|
|
266
|
+
} } : {},
|
|
193
267
|
close() {
|
|
194
268
|
for (const off of unsubscribe) off();
|
|
195
269
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { writable } from "../chat/headless/store.js";
|
|
2
|
-
import { DEFAULT_SETTINGS } from "../settings/headless/catalog.js";
|
|
3
2
|
import { closableClient } from "./closable-client.js";
|
|
3
|
+
import { DEFAULT_SETTINGS } from "../settings/headless/catalog.js";
|
|
4
4
|
import { serverSettingsSections } from "./server-settings-sections.js";
|
|
5
5
|
import { serverSettingsAccounts } from "./server-settings-accounts.js";
|
|
6
6
|
import { serverSettingsModels } from "./server-settings-models.js";
|
|
@@ -3,11 +3,11 @@ import { shikiThemeFor } from "../code/shiki-theme.js";
|
|
|
3
3
|
import { derivePalette } from "../theme/derive.js";
|
|
4
4
|
import { seedFromTheme } from "../theme/from-theme.js";
|
|
5
5
|
import { BUILTIN_THEMES, DEFAULT_THEME, resolveTheme } from "../theme/themes.js";
|
|
6
|
+
import { DEFAULT_APPEARANCE, activeThemeId, resolveMotion } from "./headless/prefs.js";
|
|
7
|
+
import { fontsToCssVars } from "./headless/fonts.js";
|
|
6
8
|
import { constant, useReadable } from "../chat/headless/store.js";
|
|
7
9
|
import { codeThemeTypeOf } from "../code/code-themes.js";
|
|
8
10
|
import { applyPalette } from "./apply.js";
|
|
9
|
-
import { fontsToCssVars } from "./headless/fonts.js";
|
|
10
|
-
import { DEFAULT_APPEARANCE, activeThemeId, resolveMotion } from "./headless/prefs.js";
|
|
11
11
|
import { jsx } from "react/jsx-runtime";
|
|
12
12
|
import { createContext, useContext, useEffect, useMemo, useState, useSyncExternalStore } from "react";
|
|
13
13
|
//#region src/appearance/AppearanceProvider.tsx
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { CURATED_FONTS, FONT_STACKS, availableCuratedFonts, cssFamily, fontStack, fontsToCssVars, guessKind, isFontAvailable, queryInstalledFonts } from "./fonts.js";
|
|
2
1
|
import { DEFAULT_APPEARANCE, LIMITS, activeThemeId, parseAppearance, resolveMotion, stepInterfaceScale } from "./prefs.js";
|
|
3
2
|
import { APPEARANCE_STORAGE_KEY, BOOT_SNAPSHOT_KEY, createStorageAppearancePrefs, createStorageBoot } from "./storage.js";
|
|
3
|
+
import { CURATED_FONTS, FONT_STACKS, availableCuratedFonts, cssFamily, fontStack, fontsToCssVars, guessKind, isFontAvailable, queryInstalledFonts } from "./fonts.js";
|
|
4
4
|
import { zoomKeyCommands } from "./zoom-commands.js";
|
|
5
5
|
export { APPEARANCE_STORAGE_KEY, BOOT_SNAPSHOT_KEY, CURATED_FONTS, DEFAULT_APPEARANCE, FONT_STACKS, LIMITS, activeThemeId, availableCuratedFonts, createStorageAppearancePrefs, createStorageBoot, cssFamily, fontStack, fontsToCssVars, guessKind, isFontAvailable, parseAppearance, queryInstalledFonts, resolveMotion, stepInterfaceScale, zoomKeyCommands };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { createApprovalHeads } from "./heads.js";
|
|
2
|
-
import { DEFAULT_APPROVALS_LABELS } from "./labels.js";
|
|
3
1
|
import { createPendingApprovals } from "./pending.js";
|
|
4
2
|
import { createSafelist } from "./safelist.js";
|
|
3
|
+
import { createApprovalHeads } from "./heads.js";
|
|
4
|
+
import { DEFAULT_APPROVALS_LABELS } from "./labels.js";
|
|
5
5
|
import { FILE_EDIT_TOOLS, allowDecision, approvalPath, approvalPreview, initialHunkMask, isFileEditApproval } from "./preview.js";
|
|
6
6
|
export { DEFAULT_APPROVALS_LABELS, FILE_EDIT_TOOLS, allowDecision, approvalPath, approvalPreview, createApprovalHeads, createPendingApprovals, createSafelist, initialHunkMask, isFileEditApproval };
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { AuthSettingsTarget } from "./headless/transcript/auth-failure.js";
|
|
2
|
+
import "./headless/transcript/index.js";
|
|
1
3
|
import { TranscriptProps } from "./Transcript.js";
|
|
2
4
|
//#region src/chat/HostTranscript.d.ts
|
|
3
5
|
/** Props for {@link HostTranscript}: the {@link TranscriptProps} minus the ones the host supplies (`events`, `streaming`, `sessionId`), plus `sessionId` and `onOpenSession`. */
|
|
@@ -8,12 +10,14 @@ interface HostTranscriptProps extends Omit<TranscriptProps, 'events' | 'streamin
|
|
|
8
10
|
onOpenSession?(sessionId: string): void;
|
|
9
11
|
/** Opens a new terminal of the session and types `input` into it (a reply's shell block). Absent: blocks offer no Run in a terminal. */
|
|
10
12
|
onRunInTerminal?(input: string): void;
|
|
13
|
+
/** Opens Settings on the account (or MCP server) a failed sign-in names. Absent: its card has no Settings button. */
|
|
14
|
+
onOpenSettings?(target: AuthSettingsTarget): void;
|
|
11
15
|
}
|
|
12
16
|
/**
|
|
13
17
|
* Renders a session's transcript from the {@link ChatHost} in context, with loading, earlier-messages, and row actions wired to the host.
|
|
14
18
|
*
|
|
15
19
|
* @param props - The {@link HostTranscriptProps}; other props pass through to {@link Transcript}.
|
|
16
20
|
*/
|
|
17
|
-
declare function HostTranscript({ sessionId, onOpenSession, onRunInTerminal, ...props }: HostTranscriptProps): import("react").JSX.Element;
|
|
21
|
+
declare function HostTranscript({ sessionId, onOpenSession, onRunInTerminal, onOpenSettings, ...props }: HostTranscriptProps): import("react").JSX.Element;
|
|
18
22
|
//#endregion
|
|
19
23
|
export { HostTranscript, HostTranscriptProps };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useReadable } from "./headless/store.js";
|
|
2
2
|
import { useChatHost } from "./ChatProvider.js";
|
|
3
|
+
import { useSettingsHost } from "../settings/SettingsProvider.js";
|
|
3
4
|
import { useChatLabels } from "./useChatLabels.js";
|
|
4
5
|
import { TranscriptActionsProvider } from "./transcript/actions.js";
|
|
5
6
|
import { DEFAULT_TRANSCRIPT_OPTIONS, Transcript } from "./Transcript.js";
|
|
@@ -11,7 +12,8 @@ import { useMemo } from "react";
|
|
|
11
12
|
* shows a loading line until its history has arrived, an "Earlier messages"
|
|
12
13
|
* control while older events exist, and binds the rows' actions to the host
|
|
13
14
|
* (full tool output, stopping a call, continuing a failed run through
|
|
14
|
-
* `send
|
|
15
|
+
* `send`, fixing a failed sign-in over the nearest settings host's accounts).
|
|
16
|
+
* An action the host leaves out hides its control.
|
|
15
17
|
*
|
|
16
18
|
* <ChatProvider host={host}>
|
|
17
19
|
* <HostTranscript sessionId={id} onOpenSession={setActive} />
|
|
@@ -26,8 +28,9 @@ const RING_STYLE = {
|
|
|
26
28
|
*
|
|
27
29
|
* @param props - The {@link HostTranscriptProps}; other props pass through to {@link Transcript}.
|
|
28
30
|
*/
|
|
29
|
-
function HostTranscript({ sessionId, onOpenSession, onRunInTerminal, ...props }) {
|
|
31
|
+
function HostTranscript({ sessionId, onOpenSession, onRunInTerminal, onOpenSettings, ...props }) {
|
|
30
32
|
const host = useChatHost();
|
|
33
|
+
const { providers, mcp } = useSettingsHost();
|
|
31
34
|
const labels = useChatLabels();
|
|
32
35
|
const transcript = useMemo(() => host.transcript(sessionId), [host, sessionId]);
|
|
33
36
|
const state = useReadable(transcript);
|
|
@@ -40,12 +43,21 @@ function HostTranscript({ sessionId, onOpenSession, onRunInTerminal, ...props })
|
|
|
40
43
|
sessionId,
|
|
41
44
|
prompt
|
|
42
45
|
}) } : {},
|
|
43
|
-
...onRunInTerminal ? { runInTerminal: onRunInTerminal } : {}
|
|
46
|
+
...onRunInTerminal ? { runInTerminal: onRunInTerminal } : {},
|
|
47
|
+
...providers || mcp?.signIn || onOpenSettings ? { accounts: {
|
|
48
|
+
cwd: "",
|
|
49
|
+
...providers ? { providers } : {},
|
|
50
|
+
...mcp?.signIn ? { mcp } : {},
|
|
51
|
+
...onOpenSettings ? { openSettings: onOpenSettings } : {}
|
|
52
|
+
} } : {}
|
|
44
53
|
}), [
|
|
45
54
|
host,
|
|
46
55
|
sessionId,
|
|
47
56
|
onOpenSession,
|
|
48
|
-
onRunInTerminal
|
|
57
|
+
onRunInTerminal,
|
|
58
|
+
providers,
|
|
59
|
+
mcp,
|
|
60
|
+
onOpenSettings
|
|
49
61
|
]);
|
|
50
62
|
if (!state.hydrated) return /* @__PURE__ */ jsx("div", {
|
|
51
63
|
role: "status",
|
|
@@ -27,7 +27,7 @@ declare function RunEstimatesProvider({ store, children }: RunEstimatesProviderP
|
|
|
27
27
|
declare function useRunEstimate(sessionId: string | undefined, label?: string, store?: RunEstimatesStore): RunEstimateView | undefined;
|
|
28
28
|
/** Props of {@link RunEstimateChip}. */
|
|
29
29
|
interface RunEstimateChipProps {
|
|
30
|
-
/** The estimate to count down. */
|
|
30
|
+
/** The estimate to count down, or the problem that keeps the run from having one. */
|
|
31
31
|
estimate: RunEstimateView;
|
|
32
32
|
/**
|
|
33
33
|
* A line after the chip's own in its tooltip. A function is read when the
|
|
@@ -44,10 +44,12 @@ interface RunEstimateChipProps {
|
|
|
44
44
|
* The time a run has left, counting down (`~11m`), in the info tint;
|
|
45
45
|
* `almost done` once the estimate is spent, dimmed while the run waits on
|
|
46
46
|
* the user, and `over` in the warning tint once the run is past its
|
|
47
|
-
* estimate.
|
|
47
|
+
* estimate. A run the host could not estimate, for a reason that will not go
|
|
48
|
+
* away by itself (a rejected request, missing credentials), shows a muted
|
|
49
|
+
* warning mark whose tooltip says why.
|
|
48
50
|
*
|
|
49
51
|
* @param props - The `estimate`, a tooltip `detail`, `className` and `style`.
|
|
50
52
|
*/
|
|
51
|
-
declare function RunEstimateChip(
|
|
53
|
+
declare function RunEstimateChip(props: RunEstimateChipProps): import("react").JSX.Element;
|
|
52
54
|
//#endregion
|
|
53
55
|
export { RunEstimateChip, RunEstimateChipProps, RunEstimatesProvider, RunEstimatesProviderProps, useRunEstimate };
|
|
@@ -2,7 +2,7 @@ import { useChatLabels } from "./useChatLabels.js";
|
|
|
2
2
|
import { pickRunEstimate } from "./headless/sidebar/estimates.js";
|
|
3
3
|
import { jsx } from "react/jsx-runtime";
|
|
4
4
|
import { createContext, useCallback, useContext, useEffect, useState, useSyncExternalStore } from "react";
|
|
5
|
-
import { estimateReadout, formatEstimate } from "zidane/chat/pure";
|
|
5
|
+
import { estimateReadout, formatEstimate, isRunEstimated } from "zidane/chat/pure";
|
|
6
6
|
//#region src/chat/RunEstimateChip.tsx
|
|
7
7
|
/**
|
|
8
8
|
* Run time estimates in a component (`Settings.runEstimates`): the app's
|
|
@@ -85,11 +85,41 @@ const TONE = {
|
|
|
85
85
|
* The time a run has left, counting down (`~11m`), in the info tint;
|
|
86
86
|
* `almost done` once the estimate is spent, dimmed while the run waits on
|
|
87
87
|
* the user, and `over` in the warning tint once the run is past its
|
|
88
|
-
* estimate.
|
|
88
|
+
* estimate. A run the host could not estimate, for a reason that will not go
|
|
89
|
+
* away by itself (a rejected request, missing credentials), shows a muted
|
|
90
|
+
* warning mark whose tooltip says why.
|
|
89
91
|
*
|
|
90
92
|
* @param props - The `estimate`, a tooltip `detail`, `className` and `style`.
|
|
91
93
|
*/
|
|
92
|
-
function RunEstimateChip(
|
|
94
|
+
function RunEstimateChip(props) {
|
|
95
|
+
const { estimate } = props;
|
|
96
|
+
return isRunEstimated(estimate) ? /* @__PURE__ */ jsx(TimingChip, {
|
|
97
|
+
...props,
|
|
98
|
+
estimate
|
|
99
|
+
}) : /* @__PURE__ */ jsx(ProblemMark, {
|
|
100
|
+
problem: estimate,
|
|
101
|
+
...props.className ? { className: props.className } : {},
|
|
102
|
+
...props.style ? { style: props.style } : {}
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
/** A run with no estimate, and why. */
|
|
106
|
+
function ProblemMark({ problem, className, style }) {
|
|
107
|
+
const title = useChatLabels().estimateProblemTitle(problem.problem.reason, problem.problem.message);
|
|
108
|
+
return /* @__PURE__ */ jsx("span", {
|
|
109
|
+
"data-testid": "run-estimate",
|
|
110
|
+
"data-state": "problem",
|
|
111
|
+
role: "img",
|
|
112
|
+
title,
|
|
113
|
+
"aria-label": title,
|
|
114
|
+
className: ["shrink-0 inline-flex self-center text-[var(--zg-text-subtle)]", className].filter(Boolean).join(" "),
|
|
115
|
+
style,
|
|
116
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
117
|
+
"aria-hidden": true,
|
|
118
|
+
className: "i-ph-warning-circle text-zg-meta"
|
|
119
|
+
})
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
function TimingChip({ estimate, detail, className, style }) {
|
|
93
123
|
const labels = useChatLabels();
|
|
94
124
|
const { state, text } = useEstimateShown(estimate);
|
|
95
125
|
const [readDetail, setReadDetail] = useState();
|
package/dist/chat/Transcript.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import { firstRowId } from "./headless/transcript/rows.js";
|
|
1
2
|
import { useExtensionItems } from "../extensions/ExtensionsProvider.js";
|
|
2
3
|
import { LinkSessionScope } from "../extensions/links.js";
|
|
3
4
|
import { CvRow, TranscriptSettling } from "./transcript/LazyRow.js";
|
|
4
5
|
import { MarkdownDiagrams } from "./transcript/markdown.js";
|
|
5
6
|
import { useTranscriptActions } from "./transcript/actions.js";
|
|
6
7
|
import { RowIconsContext } from "./transcript/frame.js";
|
|
7
|
-
import { firstRowId } from "./headless/transcript/rows.js";
|
|
8
8
|
import { ExtensionSlot } from "../extensions/ExtensionSlot.js";
|
|
9
9
|
import { rowTurnIds, stopForRow } from "./headless/transcript/select-stops.js";
|
|
10
10
|
import { rowCvStyle, rowEstimatePx } from "./transcript/row-estimate.js";
|
|
@@ -2,8 +2,8 @@ import { plainTextToDocJson } from "./prompt-history-nav.js";
|
|
|
2
2
|
import { suggestionExtension } from "./suggestion-extension.js";
|
|
3
3
|
import { jsx } from "react/jsx-runtime";
|
|
4
4
|
import { useLayoutEffect } from "react";
|
|
5
|
-
import Placeholder from "@tiptap/extension-placeholder";
|
|
6
5
|
import { EditorContent, useEditor } from "@tiptap/react";
|
|
6
|
+
import Placeholder from "@tiptap/extension-placeholder";
|
|
7
7
|
import StarterKit from "@tiptap/starter-kit";
|
|
8
8
|
//#region src/chat/composer/ComposerEditor.tsx
|
|
9
9
|
/**
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { remindersSummary } from "../../session/headless/schedules.js";
|
|
1
2
|
import { useComposerLabels } from "./ComposerHostProvider.js";
|
|
2
3
|
import { useExtensionItems, useExtensionsHost } from "../../extensions/ExtensionsProvider.js";
|
|
3
|
-
import { useSessionHost, useSessionQueue, useSessionRunningWork,
|
|
4
|
+
import { useSessionHost, useSessionPlans, useSessionQueue, useSessionRunningWork, useSessionSchedules } from "../../session/SessionProvider.js";
|
|
4
5
|
import { slotItems } from "../../extensions/headless/select.js";
|
|
5
6
|
import { ComposerBadges } from "./ComposerBadges.js";
|
|
6
7
|
import { mergeBadgeOrder, orderComposerBadges } from "./badge-order.js";
|
|
@@ -13,13 +14,14 @@ import { memo, useCallback, useEffect, useMemo, useRef } from "react";
|
|
|
13
14
|
/**
|
|
14
15
|
* The composer's badge strip for one conversation (`ComposerBadges`, drawn
|
|
15
16
|
* at the top of the composer's tray): what waits in the inbox, the todos'
|
|
16
|
-
* progress, the queued messages, the
|
|
17
|
+
* progress, the queued messages, the reminders that will fire (zidane's
|
|
18
|
+
* schedules, a click opens the Reminders tab), the running work you can stop, and what
|
|
17
19
|
* extensions show with the session: their `composer.badges` slot items
|
|
18
20
|
* (`ExtensionsHost`, a click runs the item's command or opens its panel).
|
|
19
21
|
* What goes in, in which default order
|
|
20
22
|
* and how many per extension, is `conversationBadges` (`zidane-ui/chat/headless`).
|
|
21
23
|
*
|
|
22
|
-
* The session's
|
|
24
|
+
* The session's plan, queue and running work come from the `SessionHost`
|
|
23
25
|
* (`zidane-ui/session`), its pending requests from the `ChatHost`
|
|
24
26
|
* (`interactions`). Running opens the app's Running work view
|
|
25
27
|
* (`onOpenRunningWork`); it shows once a call has run a moment and stays a
|
|
@@ -36,16 +38,18 @@ const NO_ORDER = [];
|
|
|
36
38
|
const ConversationBadges = memo(function ConversationBadges({ sessionId, showTodos = true, panels, onScreen = null, onOpenPanel, onClosePanel, order = NO_ORDER, onOrderChange, onOpenRunningWork, className, style }) {
|
|
37
39
|
const labels = useComposerLabels();
|
|
38
40
|
const interactions = usePendingInteractions(sessionId);
|
|
39
|
-
const
|
|
40
|
-
const
|
|
41
|
+
const plans = useSessionPlans(sessionId);
|
|
42
|
+
const fetchPlans = useSessionHost().plans?.refresh;
|
|
41
43
|
const queued = useSessionQueue(sessionId).length;
|
|
42
44
|
const slots = useExtensionItems("slot");
|
|
43
45
|
const slotBadges = useMemo(() => slotItems(slots, "composer.badges", sessionId ?? void 0), [slots, sessionId]);
|
|
44
46
|
const runCommand = useExtensionsHost()?.commands?.run;
|
|
45
47
|
const work = useSustainedWork(sessionId, useSessionRunningWork(sessionId));
|
|
48
|
+
const scheduled = useSessionSchedules(sessionId);
|
|
49
|
+
const reminders = useMemo(() => remindersSummary(scheduled), [scheduled]);
|
|
46
50
|
useEffect(() => {
|
|
47
|
-
if (sessionId)
|
|
48
|
-
}, [sessionId,
|
|
51
|
+
if (sessionId) fetchPlans?.(sessionId);
|
|
52
|
+
}, [sessionId, fetchPlans]);
|
|
49
53
|
const head = interactions[0] ?? null;
|
|
50
54
|
const waiting = interactions.length;
|
|
51
55
|
const data = useMemo(() => conversationBadges({
|
|
@@ -54,21 +58,23 @@ const ConversationBadges = memo(function ConversationBadges({ sessionId, showTod
|
|
|
54
58
|
head: head.request,
|
|
55
59
|
live: head.live !== false
|
|
56
60
|
} : null,
|
|
57
|
-
|
|
61
|
+
plans,
|
|
58
62
|
showTodos,
|
|
59
63
|
queued,
|
|
60
64
|
work,
|
|
61
65
|
slotBadges,
|
|
62
|
-
panels
|
|
66
|
+
panels,
|
|
67
|
+
reminders
|
|
63
68
|
}, labels), [
|
|
64
69
|
head,
|
|
65
70
|
waiting,
|
|
66
|
-
|
|
71
|
+
plans,
|
|
67
72
|
showTodos,
|
|
68
73
|
queued,
|
|
69
74
|
work,
|
|
70
75
|
slotBadges,
|
|
71
76
|
panels,
|
|
77
|
+
reminders,
|
|
72
78
|
labels
|
|
73
79
|
]);
|
|
74
80
|
const shown = useRef(onScreen);
|
|
@@ -134,9 +134,9 @@ interface ComposerDraft {
|
|
|
134
134
|
* REPLACE the composer's draft (Edit message): the editor holds `text`, the
|
|
135
135
|
* staged attachments become `attachments`, and the caret lands at the end.
|
|
136
136
|
*
|
|
137
|
-
* @param draft - The draft, and the scope of the composer it is for.
|
|
137
|
+
* @param draft - The draft, and the scope of the composer it is for (absent: the window's).
|
|
138
138
|
*/
|
|
139
|
-
declare function pushComposerDraft({ scopeKey, text, attachments }: ComposerDraft & ComposerTarget): void;
|
|
139
|
+
declare function pushComposerDraft({ scopeKey, text, attachments }: ComposerDraft & Partial<ComposerTarget>): void;
|
|
140
140
|
/**
|
|
141
141
|
* Takes the drafts pushed to a composer.
|
|
142
142
|
*
|
|
@@ -223,13 +223,13 @@ function onComposerPrompt(scopeKey, handler) {
|
|
|
223
223
|
* REPLACE the composer's draft (Edit message): the editor holds `text`, the
|
|
224
224
|
* staged attachments become `attachments`, and the caret lands at the end.
|
|
225
225
|
*
|
|
226
|
-
* @param draft - The draft, and the scope of the composer it is for.
|
|
226
|
+
* @param draft - The draft, and the scope of the composer it is for (absent: the window's).
|
|
227
227
|
*/
|
|
228
228
|
function pushComposerDraft({ scopeKey, text, attachments }) {
|
|
229
229
|
dispatch(DRAFT_EVENT, {
|
|
230
230
|
text,
|
|
231
231
|
attachments
|
|
232
|
-
}, { scopeKey });
|
|
232
|
+
}, scopeKey === void 0 ? void 0 : { scopeKey });
|
|
233
233
|
}
|
|
234
234
|
/**
|
|
235
235
|
* Takes the drafts pushed to a composer.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { useComposerHost } from "./ComposerHostProvider.js";
|
|
2
1
|
import { IDLE_RESOURCE } from "../../app/headless/resource.js";
|
|
3
2
|
import { createModelPickerPrefs } from "../headless/composer/model-picker-prefs.js";
|
|
3
|
+
import { useComposerHost } from "./ComposerHostProvider.js";
|
|
4
4
|
import { modelKnobsOf } from "../headless/composer/model-knobs.js";
|
|
5
5
|
import { modelNamesOf } from "../headless/composer/model-names.js";
|
|
6
6
|
import { useEffect, useMemo, useSyncExternalStore } from "react";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { useComposerHost } from "./ComposerHostProvider.js";
|
|
2
1
|
import { EMPTY_RUN_METER } from "../headless/composer/run-meter.js";
|
|
2
|
+
import { useComposerHost } from "./ComposerHostProvider.js";
|
|
3
3
|
import { useCallback, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
|
|
4
4
|
//#region src/chat/composer/use-run-meter.ts
|
|
5
5
|
/**
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ExtensionItem } from "../../../extensions/headless/wire.js";
|
|
2
2
|
import { ComposerChromeLabels } from "./labels-chrome.js";
|
|
3
|
-
import {
|
|
3
|
+
import { RemindersSummary } from "../../../session/headless/schedules.js";
|
|
4
|
+
import { InteractionRequest, PlansSnapshot } from "zidane/chat";
|
|
4
5
|
import { RunningWorkItem } from "zidane/ipc";
|
|
5
6
|
//#region src/chat/headless/composer/conversation-badges.d.ts
|
|
6
7
|
/** One badge of the strip, as data (the kit's `ComposerBadge` without its click). */
|
|
@@ -48,8 +49,8 @@ interface InboxSummary {
|
|
|
48
49
|
interface ConversationBadgeInput {
|
|
49
50
|
/** The pending requests, `null` for none. */
|
|
50
51
|
inbox: InboxSummary | null;
|
|
51
|
-
/** The
|
|
52
|
-
|
|
52
|
+
/** The session's plans: the badge follows the plan worth a glance (`active`: applying, else stopped). */
|
|
53
|
+
plans: PlansSnapshot | null;
|
|
53
54
|
/** `Settings.showTodoIndicator`. */
|
|
54
55
|
showTodos: boolean;
|
|
55
56
|
/** Messages in the conversation's queue. */
|
|
@@ -60,6 +61,10 @@ interface ConversationBadgeInput {
|
|
|
60
61
|
slotBadges?: readonly ExtensionItem<'slot'>[];
|
|
61
62
|
/** The conversation's panels (the catalog's ids): an extension badge opens one of them or nothing. */
|
|
62
63
|
panels: ReadonlySet<string>;
|
|
64
|
+
/** The conversation's reminders that will fire (`remindersSummary`), `null` for none. */
|
|
65
|
+
reminders?: RemindersSummary | null;
|
|
66
|
+
/** The clock, for the next reminder's day words. @default Date.now() */
|
|
67
|
+
now?: number;
|
|
63
68
|
}
|
|
64
69
|
/** How many badges one extension shows in one composer (zidane's `MAX_COMPOSER_BADGES`). */
|
|
65
70
|
declare const MAX_EXTENSION_COMPOSER_BADGES = 8;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { INBOX_PANEL_ID, QUEUE_PANEL_ID,
|
|
1
|
+
import { INBOX_PANEL_ID, QUEUE_PANEL_ID, REMINDERS_PANEL_ID, describeTime, planProgressLabel } from "zidane/chat/pure";
|
|
2
2
|
//#region src/chat/headless/composer/conversation-badges.ts
|
|
3
3
|
/** Default slots: the built-ins lead, extensions sit at the kit's default (100). */
|
|
4
4
|
const BADGE_ORDER = {
|
|
5
5
|
inbox: 0,
|
|
6
6
|
todos: 10,
|
|
7
7
|
queue: 20,
|
|
8
|
+
reminders: 25,
|
|
8
9
|
work: 30
|
|
9
10
|
};
|
|
10
11
|
/** How many badges one extension shows in one composer (zidane's `MAX_COMPOSER_BADGES`). */
|
|
@@ -19,7 +20,7 @@ const MAX_EXTENSION_COMPOSER_BADGES = 8;
|
|
|
19
20
|
function conversationBadges(input, labels) {
|
|
20
21
|
const out = [];
|
|
21
22
|
if (input.inbox) out.push(inboxBadge(input.inbox, labels));
|
|
22
|
-
const todos = input.showTodos && input.
|
|
23
|
+
const todos = input.showTodos && input.plans ? todosBadge(input.plans, labels) : null;
|
|
23
24
|
if (todos) out.push(todos);
|
|
24
25
|
if (input.queued > 0) out.push({
|
|
25
26
|
id: "queue",
|
|
@@ -30,6 +31,19 @@ function conversationBadges(input, labels) {
|
|
|
30
31
|
order: BADGE_ORDER.queue,
|
|
31
32
|
panel: QUEUE_PANEL_ID
|
|
32
33
|
});
|
|
34
|
+
if (input.reminders) {
|
|
35
|
+
const when = describeTime(input.reminders.next, input.now ?? Date.now());
|
|
36
|
+
const short = when.startsWith("today ") ? when.slice(6) : when;
|
|
37
|
+
out.push({
|
|
38
|
+
id: "reminders",
|
|
39
|
+
label: labels.badgeReminders(short),
|
|
40
|
+
icon: "i-ph-alarm",
|
|
41
|
+
count: String(input.reminders.count),
|
|
42
|
+
title: labels.badgeRemindersTitle(input.reminders.count, when),
|
|
43
|
+
order: BADGE_ORDER.reminders,
|
|
44
|
+
panel: input.panels.has(REMINDERS_PANEL_ID) ? REMINDERS_PANEL_ID : null
|
|
45
|
+
});
|
|
46
|
+
}
|
|
33
47
|
if (input.work.length > 0) out.push(workBadge(input.work, labels));
|
|
34
48
|
const shown = /* @__PURE__ */ new Map();
|
|
35
49
|
const room = (extension) => {
|
|
@@ -79,20 +93,21 @@ function inboxBadge({ count, head, live }, labels) {
|
|
|
79
93
|
};
|
|
80
94
|
}
|
|
81
95
|
function todosBadge(snap, labels) {
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
const
|
|
87
|
-
const
|
|
96
|
+
const active = snap.active;
|
|
97
|
+
if (!active || active.state !== "applying" && active.state !== "stopped") return null;
|
|
98
|
+
const count = planProgressLabel(active.progress);
|
|
99
|
+
if (!count) return null;
|
|
100
|
+
const { completed, cancelled, total, activeIndex } = active.progress;
|
|
101
|
+
const progress = labels.badgeTodosProgress(completed + cancelled, total);
|
|
102
|
+
const current = active.state === "applying" && activeIndex >= 0 ? snap.plans.find((p) => p.id === active.planId)?.steps[activeIndex] : void 0;
|
|
88
103
|
return {
|
|
89
104
|
id: "todos",
|
|
90
105
|
label: labels.badgeTodos,
|
|
91
106
|
icon: "i-ph-list-checks",
|
|
92
|
-
count
|
|
93
|
-
title: current ? labels.badgeTodosCurrent(current.
|
|
107
|
+
count,
|
|
108
|
+
title: active.state === "stopped" ? labels.badgeTodosStopped(progress) : current ? labels.badgeTodosCurrent(current.title, progress) : progress,
|
|
94
109
|
order: BADGE_ORDER.todos,
|
|
95
|
-
panel:
|
|
110
|
+
panel: INBOX_PANEL_ID
|
|
96
111
|
};
|
|
97
112
|
}
|
|
98
113
|
function slotBadge(entry, panels) {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import { DEFAULT_MODEL_PICKER_PREFS, MODEL_PICKER_STORAGE_KEY, createModelPickerPrefs, parseModelPickerPrefs } from "./model-picker-prefs.js";
|
|
2
|
+
import { EMPTY_RUN_METER, createRunMeter } from "./run-meter.js";
|
|
1
3
|
import { DEFAULT_COMPOSER_CHROME_LABELS } from "./labels-chrome.js";
|
|
2
4
|
import { DEFAULT_COMPOSER_LABELS } from "./labels.js";
|
|
3
5
|
import { findCommand } from "./commands.js";
|
|
4
|
-
import { DEFAULT_MODEL_PICKER_PREFS, MODEL_PICKER_STORAGE_KEY, createModelPickerPrefs, parseModelPickerPrefs } from "./model-picker-prefs.js";
|
|
5
|
-
import { EMPTY_RUN_METER, createRunMeter } from "./run-meter.js";
|
|
6
6
|
import { composeLiveCost, formatSessionCostLabel } from "./live-cost.js";
|
|
7
7
|
import { createModelKnobs, modelKnobsOf } from "./model-knobs.js";
|
|
8
8
|
import { createModelNames, modelNamesOf, namerFor } from "./model-names.js";
|
|
@@ -16,7 +16,9 @@ declare const DEFAULT_COMPOSER_CHROME_LABELS: {
|
|
|
16
16
|
badgeTodos: string;
|
|
17
17
|
badgeTodosProgress: (done: number, total: number) => string;
|
|
18
18
|
badgeTodosCurrent: (content: string, progress: string) => string;
|
|
19
|
-
|
|
19
|
+
badgeTodosStopped: (progress: string) => string;
|
|
20
|
+
badgeReminders: (when: string) => string;
|
|
21
|
+
badgeRemindersTitle: (n: number, when: string) => string;
|
|
20
22
|
/** The archived session's banner. */
|
|
21
23
|
archivedNotice: string;
|
|
22
24
|
unarchive: string;
|