@qilin-agent/client-ui-workspace 3.1.3 → 3.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/README.i18n.yaml +24 -24
- package/lib/client.js +4 -368
- package/lib/types/client/contract/slots.d.ts +0 -56
- package/lib/types/client/index.d.ts +1 -1
- package/lib/types/client/locales.d.ts +0 -10
- package/lib/types/client/navigation.d.ts +2 -47
- package/package.json +22 -24
- package/lib/types/client/AgentPresetChip.d.ts +0 -10
- package/lib/types/client/WorkbenchSwitchSeat.d.ts +0 -15
- package/lib/types/client/rows/WorkbenchSwitch.d.ts +0 -29
package/README.i18n.yaml
CHANGED
|
@@ -5,63 +5,63 @@
|
|
|
5
5
|
/:
|
|
6
6
|
en: a92228dd36f58c28
|
|
7
7
|
zh: d2bcff3de67211c9
|
|
8
|
-
/qilin-client-ui-workspace:
|
|
9
|
-
en:
|
|
10
|
-
zh:
|
|
11
|
-
/qilin-client-ui-workspace/summary:
|
|
8
|
+
/qilin-agent-client-ui-workspace:
|
|
9
|
+
en: 7c92dee86395fa5e
|
|
10
|
+
zh: eb914b3268d653ac
|
|
11
|
+
/qilin-agent-client-ui-workspace/summary:
|
|
12
12
|
en: 1fb6e04bffdf985e
|
|
13
13
|
zh: 5068ce8d141f377e
|
|
14
|
-
/qilin-client-ui-workspace/table-of-contents:
|
|
14
|
+
/qilin-agent-client-ui-workspace/table-of-contents:
|
|
15
15
|
en: d152484eb41ac6b4
|
|
16
16
|
zh: 09388d293f9be9cb
|
|
17
|
-
/qilin-client-ui-workspace/use-this-package:
|
|
17
|
+
/qilin-agent-client-ui-workspace/use-this-package:
|
|
18
18
|
en: d2973905f9fc3331
|
|
19
19
|
zh: 5d557bd5c8eb783a
|
|
20
|
-
/qilin-client-ui-workspace/use-this-package/reordering-and-view-options:
|
|
20
|
+
/qilin-agent-client-ui-workspace/use-this-package/reordering-and-view-options:
|
|
21
21
|
en: 6cea302320f00839
|
|
22
22
|
zh: d695994ec569a43e
|
|
23
|
-
/qilin-client-ui-workspace/use-this-package/workspace-hierarchy:
|
|
23
|
+
/qilin-agent-client-ui-workspace/use-this-package/workspace-hierarchy:
|
|
24
24
|
en: 5e049b90c55eddb3
|
|
25
25
|
zh: e06dc8d0d25c013f
|
|
26
|
-
/qilin-client-ui-workspace/use-this-package/search:
|
|
26
|
+
/qilin-agent-client-ui-workspace/use-this-package/search:
|
|
27
27
|
en: faf570bcad825439
|
|
28
28
|
zh: a65300b0b40a8550
|
|
29
|
-
/qilin-client-ui-workspace/use-this-package/managing-sessions:
|
|
29
|
+
/qilin-agent-client-ui-workspace/use-this-package/managing-sessions:
|
|
30
30
|
en: 7a50621fbde08357
|
|
31
31
|
zh: 735a575e236e3860
|
|
32
|
-
/qilin-client-ui-workspace/use-this-package/pending-interactions:
|
|
32
|
+
/qilin-agent-client-ui-workspace/use-this-package/pending-interactions:
|
|
33
33
|
en: efcede0546e167c5
|
|
34
34
|
zh: 74afe770abb49016
|
|
35
|
-
/qilin-client-ui-workspace/use-this-package/active-schedule-markers:
|
|
35
|
+
/qilin-agent-client-ui-workspace/use-this-package/active-schedule-markers:
|
|
36
36
|
en: 2b0cda3b7b38ce39
|
|
37
37
|
zh: e33243b642a6164a
|
|
38
|
-
/qilin-client-ui-workspace/understand-the-implementation:
|
|
38
|
+
/qilin-agent-client-ui-workspace/understand-the-implementation:
|
|
39
39
|
en: f08ceb1f5612a6ac
|
|
40
40
|
zh: a75b56cc094b5c45
|
|
41
|
-
/qilin-client-ui-workspace/understand-the-implementation/the-directory-flow-hole:
|
|
41
|
+
/qilin-agent-client-ui-workspace/understand-the-implementation/the-directory-flow-hole:
|
|
42
42
|
en: 978415ec6b2e0cc0
|
|
43
43
|
zh: 0d5c705ff34fb1da
|
|
44
|
-
/qilin-client-ui-workspace/understand-the-implementation/the-hero-run-mode-chip:
|
|
44
|
+
/qilin-agent-client-ui-workspace/understand-the-implementation/the-hero-run-mode-chip:
|
|
45
45
|
en: 745e917ae00da6ab
|
|
46
46
|
zh: 32c745f9078829b8
|
|
47
|
-
/qilin-client-ui-workspace/understand-the-implementation/view-state:
|
|
48
|
-
en:
|
|
49
|
-
zh:
|
|
50
|
-
/qilin-client-ui-workspace/understand-the-implementation/hover-cards:
|
|
47
|
+
/qilin-agent-client-ui-workspace/understand-the-implementation/view-state:
|
|
48
|
+
en: dc93d10e80153f62
|
|
49
|
+
zh: 5caa3399dbf84f62
|
|
50
|
+
/qilin-agent-client-ui-workspace/understand-the-implementation/hover-cards:
|
|
51
51
|
en: f236cadca4c98088
|
|
52
52
|
zh: 8b36850c1d5f73d2
|
|
53
|
-
/qilin-client-ui-workspace/further-exploration:
|
|
53
|
+
/qilin-agent-client-ui-workspace/further-exploration:
|
|
54
54
|
en: cf79dbc3c0a50622
|
|
55
55
|
zh: e86fbbd598a7fe77
|
|
56
|
-
/qilin-client-ui-workspace/model-experience:
|
|
56
|
+
/qilin-agent-client-ui-workspace/model-experience:
|
|
57
57
|
en: 3120df665299c634
|
|
58
58
|
zh: 1d9f365d091d0d2a
|
|
59
|
-
/qilin-client-ui-workspace/model-experience/kv-cache-effect:
|
|
59
|
+
/qilin-agent-client-ui-workspace/model-experience/kv-cache-effect:
|
|
60
60
|
en: ca75c51c89c2c9b0
|
|
61
61
|
zh: de54f3467ef3b9be
|
|
62
|
-
/qilin-client-ui-workspace/known-limitations-and-deferred-work:
|
|
62
|
+
/qilin-agent-client-ui-workspace/known-limitations-and-deferred-work:
|
|
63
63
|
en: ead58471d372f64f
|
|
64
64
|
zh: 3af32ed381b76179
|
|
65
|
-
/qilin-client-ui-workspace/known-limitations-and-deferred-work/dev-note:
|
|
65
|
+
/qilin-agent-client-ui-workspace/known-limitations-and-deferred-work/dev-note:
|
|
66
66
|
en: e67f633dc6fe7773
|
|
67
67
|
zh: 3bb0c20c93f16f98
|
package/lib/client.js
CHANGED
|
@@ -685,8 +685,6 @@ window.__ModuleLoader__.load({
|
|
|
685
685
|
/** Implements Workspace archive and directory UI operations. */
|
|
686
686
|
var UiWorkspaceService = class extends _qilin_agent_kylin.Service {
|
|
687
687
|
directoryPicker;
|
|
688
|
-
agentPresets;
|
|
689
|
-
workbench;
|
|
690
688
|
workspaces;
|
|
691
689
|
sessions;
|
|
692
690
|
view;
|
|
@@ -702,19 +700,13 @@ window.__ModuleLoader__.load({
|
|
|
702
700
|
/**
|
|
703
701
|
* @param ctx - Client root Context.
|
|
704
702
|
* @param directoryPicker - the directory-picking Remote namespace.
|
|
705
|
-
* @param agentPresets - the preset-switch caller, for the blank-session
|
|
706
|
-
* tag rebind (D3: a blank session may switch presets; a started one may not).
|
|
707
|
-
* @param workbench - the tag state owner, supplying each new task's preset
|
|
708
|
-
* and the visibility fold the reuse rule checks.
|
|
709
703
|
* @param workspaces - pure Workspace Controller.
|
|
710
704
|
* @param sessions - pure Session Controller.
|
|
711
705
|
* @param view - the browser's viewing-store write set, which owns saved Session order.
|
|
712
706
|
*/
|
|
713
|
-
constructor(ctx, directoryPicker,
|
|
707
|
+
constructor(ctx, directoryPicker, workspaces, sessions, view) {
|
|
714
708
|
super(ctx, "uiWorkspace");
|
|
715
709
|
this.directoryPicker = directoryPicker;
|
|
716
|
-
this.agentPresets = agentPresets;
|
|
717
|
-
this.workbench = workbench;
|
|
718
710
|
this.workspaces = workspaces;
|
|
719
711
|
this.sessions = sessions;
|
|
720
712
|
this.view = view;
|
|
@@ -738,56 +730,14 @@ window.__ModuleLoader__.load({
|
|
|
738
730
|
const sessions = this.sessions.list.getSnapshot();
|
|
739
731
|
for (const id of sessions.ids) {
|
|
740
732
|
const summary = sessions.byId[id];
|
|
741
|
-
if (summary !== void 0 && summary.blank && summary.cwd === workspace.path && workspace.sessionIds.includes(summary.id) && !archived.includes(summary.id))
|
|
742
|
-
this.rebindBlankToActiveTag(id);
|
|
743
|
-
return summary.id;
|
|
744
|
-
}
|
|
733
|
+
if (summary !== void 0 && summary.blank && summary.cwd === workspace.path && workspace.sessionIds.includes(summary.id) && !archived.includes(summary.id)) return summary.id;
|
|
745
734
|
}
|
|
746
|
-
const attempt = this.sessions.create({
|
|
747
|
-
workspaceId,
|
|
748
|
-
agentPreset: this.workbench.presetFor(this.workbench.state.getSnapshot().active)
|
|
749
|
-
}).finally(() => {
|
|
735
|
+
const attempt = this.sessions.create({ workspaceId }).finally(() => {
|
|
750
736
|
this.connecting.delete(workspaceId);
|
|
751
737
|
});
|
|
752
738
|
this.connecting.set(workspaceId, attempt);
|
|
753
739
|
return attempt;
|
|
754
740
|
}
|
|
755
|
-
/**
|
|
756
|
-
* Rebind every blank session of the current Workspace to the now-active
|
|
757
|
-
* tag's preset. Blank sessions carried over from the other tag would
|
|
758
|
-
* otherwise sit hidden in this tag's filtered list; a non-blank session
|
|
759
|
-
* stays exactly as it is (the Host refuses non-blank switches anyway).
|
|
760
|
-
*/
|
|
761
|
-
rebindBlanksAfterTagSwitch() {
|
|
762
|
-
const current = this.mainReference?.sessionId;
|
|
763
|
-
const workspace = current === void 0 ? void 0 : this.workspaces.list.getSnapshot().items.find((item) => item.sessionIds.includes(current));
|
|
764
|
-
if (workspace === void 0) return;
|
|
765
|
-
for (const id of workspace.sessionIds) if (this.sessions.list.getSnapshot().byId[id]?.blank === true) this.rebindBlankToActiveTag(id);
|
|
766
|
-
}
|
|
767
|
-
/**
|
|
768
|
-
* Switch one blank session to the active tag's preset when the preset it
|
|
769
|
-
* was created under does not show under this tag. Fire-and-forget: the
|
|
770
|
-
* session stays usable either way, and a `locked` verdict means it engaged
|
|
771
|
-
* mid-rebind, so its own preset stands.
|
|
772
|
-
* @param id - the blank session to align.
|
|
773
|
-
*/
|
|
774
|
-
rebindBlankToActiveTag(id) {
|
|
775
|
-
const summary = this.sessions.list.getSnapshot().byId[id];
|
|
776
|
-
if (summary === void 0) return;
|
|
777
|
-
const tag = this.workbench.state.getSnapshot().active;
|
|
778
|
-
if (this.workbench.shows(summary.projectionValues?.agentPreset, tag)) return;
|
|
779
|
-
this.agentPresets.select(id, this.workbench.presetFor(tag)).catch((reason) => {
|
|
780
|
-
console.warn(`blank session ${id} kept its own preset:`, reason);
|
|
781
|
-
});
|
|
782
|
-
}
|
|
783
|
-
adoptBlankSessionPreset(presetId) {
|
|
784
|
-
const current = this.mainReference?.sessionId;
|
|
785
|
-
if (current === void 0) return;
|
|
786
|
-
if (this.sessions.list.getSnapshot().byId[current]?.blank !== true) return;
|
|
787
|
-
this.agentPresets.select(current, presetId).catch((reason) => {
|
|
788
|
-
console.warn(`blank session ${current} kept its own preset:`, reason);
|
|
789
|
-
});
|
|
790
|
-
}
|
|
791
741
|
openSession(target) {
|
|
792
742
|
this.replaceMain(target, this.lifetime.signal);
|
|
793
743
|
}
|
|
@@ -961,112 +911,6 @@ window.__ModuleLoader__.load({
|
|
|
961
911
|
return selected;
|
|
962
912
|
}
|
|
963
913
|
//#endregion
|
|
964
|
-
//#region \0qilin-css:/home/runner/work/QiLin/QiLin/packages/client/ui-workspace/src/client/AgentPresetChip.module.css.mjs
|
|
965
|
-
const css$5 = "._2_v9Qa_chip{max-width:min(100%,360px);min-height:28px;color:var(--qilin-alias-label-primary);cursor:pointer;background:0 0;border:none;border-radius:16px;align-items:center;gap:4px;padding:0 8px;font-size:13px;font-weight:500;line-height:20px;display:inline-flex}._2_v9Qa_chip:hover,._2_v9Qa_chip[aria-expanded=true]{background:var(--qilin-alias-interactive-bg-hover)}._2_v9Qa_icon{color:var(--qilin-alias-label-primary);flex:none}._2_v9Qa_label{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}._2_v9Qa_chevron{color:var(--qilin-alias-label-caption);flex:none}._2_v9Qa_item{flex-direction:column;gap:2px;min-width:0;display:flex}._2_v9Qa_itemName{font-weight:500}._2_v9Qa_itemDesc{color:var(--qilin-alias-label-secondary);text-overflow:ellipsis;white-space:nowrap;font-size:12px;line-height:18px;overflow:hidden}._2_v9Qa_menuAnchor{z-index:10}";
|
|
966
|
-
const tagId$5 = "@qilin-agent/client-ui-workspace/AgentPresetChip.module.css";
|
|
967
|
-
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$5) + "]") === null) {
|
|
968
|
-
const tag = document.createElement("style");
|
|
969
|
-
tag.dataset.plugin = "@qilin-agent/client-ui-workspace";
|
|
970
|
-
tag.dataset.pluginCss = tagId$5;
|
|
971
|
-
tag.textContent = css$5;
|
|
972
|
-
document.head.appendChild(tag);
|
|
973
|
-
}
|
|
974
|
-
var AgentPresetChip_module_css_default = {
|
|
975
|
-
"chevron": "_2_v9Qa_chevron",
|
|
976
|
-
"chip": "_2_v9Qa_chip",
|
|
977
|
-
"icon": "_2_v9Qa_icon",
|
|
978
|
-
"item": "_2_v9Qa_item",
|
|
979
|
-
"itemDesc": "_2_v9Qa_itemDesc",
|
|
980
|
-
"itemName": "_2_v9Qa_itemName",
|
|
981
|
-
"label": "_2_v9Qa_label",
|
|
982
|
-
"menuAnchor": "_2_v9Qa_menuAnchor"
|
|
983
|
-
};
|
|
984
|
-
//#endregion
|
|
985
|
-
//#region lib/types/client/AgentPresetChip.js
|
|
986
|
-
/**
|
|
987
|
-
* The hero run-mode chip, beside the workspace picker on the new-task screen:
|
|
988
|
-
* which preset the next task in this workbench tag composes from (D3). The
|
|
989
|
-
* general and coding tags carry their own defaults (standard / ptc); the chip
|
|
990
|
-
* exists so the creator preset stays one pick away. The choice is remembered
|
|
991
|
-
* per tag through the workbench state, and the on-screen blank session is
|
|
992
|
-
* rebound immediately so the staged task already carries it.
|
|
993
|
-
*
|
|
994
|
-
* The chip hides while the roster is unavailable, failed, or offers fewer
|
|
995
|
-
* than two choices for the tag — a selector over one entry is noise.
|
|
996
|
-
*/
|
|
997
|
-
/**
|
|
998
|
-
* Render the run-mode chip.
|
|
999
|
-
* @param props - the bound workbench and roster selector hooks, the tag
|
|
1000
|
-
* vocabulary and pick actions, and the locale seat.
|
|
1001
|
-
* @returns the chip, or null when there is nothing to choose.
|
|
1002
|
-
*/
|
|
1003
|
-
function AgentPresetChip({ useWorkbench, useRoster, tagChoices, pick, t }) {
|
|
1004
|
-
const workbench = useWorkbench((snapshot) => snapshot);
|
|
1005
|
-
const roster = useRoster((snapshot) => snapshot);
|
|
1006
|
-
const [open, setOpen] = (0, react.useState)(false);
|
|
1007
|
-
const tag = workbench.active;
|
|
1008
|
-
const options = (0, react.useMemo)(() => {
|
|
1009
|
-
const byId = new Map(roster.presets.map((preset) => [preset.id, preset]));
|
|
1010
|
-
const shipped = tagChoices(tag).map((id) => byId.get(id)).filter((preset) => preset !== void 0);
|
|
1011
|
-
const known = new Set([...tagChoices("general"), ...tagChoices("coding")]);
|
|
1012
|
-
const custom = roster.presets.filter((preset) => !known.has(preset.id));
|
|
1013
|
-
return [...shipped, ...custom];
|
|
1014
|
-
}, [
|
|
1015
|
-
roster.presets,
|
|
1016
|
-
tag,
|
|
1017
|
-
tagChoices
|
|
1018
|
-
]);
|
|
1019
|
-
if (roster.status !== "ready" || options.length < 2) return null;
|
|
1020
|
-
const currentId = workbench.presets[tag];
|
|
1021
|
-
const currentName = options.find((option) => option.id === currentId)?.name ?? currentId;
|
|
1022
|
-
return (0, react_jsx_runtime.jsx)(_qilin_agent_client_ui_primitives.Menu, {
|
|
1023
|
-
open,
|
|
1024
|
-
onClose: () => {
|
|
1025
|
-
setOpen(false);
|
|
1026
|
-
},
|
|
1027
|
-
items: options.map((option) => ({
|
|
1028
|
-
id: option.id,
|
|
1029
|
-
label: (0, react_jsx_runtime.jsxs)("span", {
|
|
1030
|
-
className: AgentPresetChip_module_css_default.item,
|
|
1031
|
-
children: [(0, react_jsx_runtime.jsx)("span", {
|
|
1032
|
-
className: AgentPresetChip_module_css_default.itemName,
|
|
1033
|
-
children: option.name ?? option.id
|
|
1034
|
-
}), option.description !== void 0 && (0, react_jsx_runtime.jsx)("span", {
|
|
1035
|
-
className: AgentPresetChip_module_css_default.itemDesc,
|
|
1036
|
-
children: option.description
|
|
1037
|
-
})]
|
|
1038
|
-
})
|
|
1039
|
-
})),
|
|
1040
|
-
selectedId: currentId,
|
|
1041
|
-
onSelect: (id) => {
|
|
1042
|
-
setOpen(false);
|
|
1043
|
-
pick(id);
|
|
1044
|
-
},
|
|
1045
|
-
align: "start",
|
|
1046
|
-
portal: true,
|
|
1047
|
-
className: AgentPresetChip_module_css_default.menuAnchor,
|
|
1048
|
-
anchor: (0, react_jsx_runtime.jsxs)("button", {
|
|
1049
|
-
type: "button",
|
|
1050
|
-
className: AgentPresetChip_module_css_default.chip,
|
|
1051
|
-
"aria-label": t("preset.aria"),
|
|
1052
|
-
"aria-haspopup": "menu",
|
|
1053
|
-
"aria-expanded": open,
|
|
1054
|
-
title: t("preset.hint"),
|
|
1055
|
-
onClick: () => {
|
|
1056
|
-
setOpen((value) => !value);
|
|
1057
|
-
},
|
|
1058
|
-
children: [
|
|
1059
|
-
(0, react_jsx_runtime.jsx)(_qilin_agent_client_ui_primitives.IconAgentPresetOutline16, { className: AgentPresetChip_module_css_default.icon }),
|
|
1060
|
-
(0, react_jsx_runtime.jsx)("span", {
|
|
1061
|
-
className: AgentPresetChip_module_css_default.label,
|
|
1062
|
-
children: currentName
|
|
1063
|
-
}),
|
|
1064
|
-
(0, react_jsx_runtime.jsx)(_qilin_agent_client_ui_primitives.IconChevronDownOutline14, { className: AgentPresetChip_module_css_default.chevron })
|
|
1065
|
-
]
|
|
1066
|
-
})
|
|
1067
|
-
});
|
|
1068
|
-
}
|
|
1069
|
-
//#endregion
|
|
1070
914
|
//#region ../../../node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs
|
|
1071
915
|
function r(e) {
|
|
1072
916
|
var t, f, n = "";
|
|
@@ -1082,129 +926,6 @@ window.__ModuleLoader__.load({
|
|
|
1082
926
|
return n;
|
|
1083
927
|
}
|
|
1084
928
|
//#endregion
|
|
1085
|
-
//#region \0qilin-css:/home/runner/work/QiLin/QiLin/packages/client/ui-workspace/src/client/rows/WorkbenchSwitch.module.css.mjs
|
|
1086
|
-
const css$4 = ".n6Fpha_switch{align-items:center;gap:6px;display:inline-flex}.n6Fpha_tab{height:28px;color:var(--qilin-alias-label-secondary);font-size:var(--dsh-content-font-size-secondary,13px);corner-shape:round;cursor:pointer;transition:background var(--ds-transition-duration-fast) var(--ds-ease-in-out);background:0 0;border:1px solid #0000;border-radius:999px;flex:none;justify-content:center;align-items:center;gap:5px;padding:0 8px;line-height:1;display:inline-flex}.n6Fpha_tab:hover{background:var(--qilin-alias-interactive-bg-hover)}.n6Fpha_activePill{color:var(--qilin-alias-brand-primary-new-colorprimary-new-color);border-color:currentColor;padding:0 11px}.n6Fpha_inactiveIcon{width:28px;padding:0}.n6Fpha_label{white-space:nowrap}";
|
|
1087
|
-
const tagId$4 = "@qilin-agent/client-ui-workspace/WorkbenchSwitch.module.css";
|
|
1088
|
-
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$4) + "]") === null) {
|
|
1089
|
-
const tag = document.createElement("style");
|
|
1090
|
-
tag.dataset.plugin = "@qilin-agent/client-ui-workspace";
|
|
1091
|
-
tag.dataset.pluginCss = tagId$4;
|
|
1092
|
-
tag.textContent = css$4;
|
|
1093
|
-
document.head.appendChild(tag);
|
|
1094
|
-
}
|
|
1095
|
-
var WorkbenchSwitch_module_css_default = {
|
|
1096
|
-
"activePill": "n6Fpha_activePill",
|
|
1097
|
-
"inactiveIcon": "n6Fpha_inactiveIcon",
|
|
1098
|
-
"label": "n6Fpha_label",
|
|
1099
|
-
"switch": "n6Fpha_switch",
|
|
1100
|
-
"tab": "n6Fpha_tab"
|
|
1101
|
-
};
|
|
1102
|
-
//#endregion
|
|
1103
|
-
//#region lib/types/client/rows/WorkbenchSwitch.js
|
|
1104
|
-
/** Constant visual order: coding first (left), general second (right). */
|
|
1105
|
-
const ENTRIES = ["coding", "general"];
|
|
1106
|
-
/**
|
|
1107
|
-
* Render the two-tag switch. Both tags stay mounted and reachable — only the
|
|
1108
|
-
* label of the inactive one is hidden — so the tab semantics of the previous
|
|
1109
|
-
* segmented control carry over: roving tab stop on the selected tag,
|
|
1110
|
-
* Left/Right to move selection.
|
|
1111
|
-
* @param props.value - the active tag.
|
|
1112
|
-
* @param props.onChange - selection requested by click or Left/Right.
|
|
1113
|
-
* @param props.labels - localized tag names, keyed by tag; the inactive
|
|
1114
|
-
* button's accessible name (its label is hidden).
|
|
1115
|
-
* @param props.ariaLabel - localized accessible name for the tab list.
|
|
1116
|
-
* @param props.panelId - DOM id of the panel the tabs control.
|
|
1117
|
-
* @returns the tab list, without its panel.
|
|
1118
|
-
*/
|
|
1119
|
-
function WorkbenchSwitch({ value, onChange, labels, ariaLabel, panelId }) {
|
|
1120
|
-
const onKeyDown = (event, index) => {
|
|
1121
|
-
let next;
|
|
1122
|
-
switch (event.key) {
|
|
1123
|
-
case "ArrowLeft":
|
|
1124
|
-
next = (index + ENTRIES.length - 1) % ENTRIES.length;
|
|
1125
|
-
break;
|
|
1126
|
-
case "ArrowRight":
|
|
1127
|
-
next = (index + 1) % ENTRIES.length;
|
|
1128
|
-
break;
|
|
1129
|
-
default: return;
|
|
1130
|
-
}
|
|
1131
|
-
event.preventDefault();
|
|
1132
|
-
event.stopPropagation();
|
|
1133
|
-
const tablist = event.currentTarget.parentElement;
|
|
1134
|
-
const nextTag = ENTRIES[next];
|
|
1135
|
-
/* v8 ignore next -- the event comes from a mounted direct child and next is bounded by the fixed pair. */
|
|
1136
|
-
if (tablist === null || nextTag === void 0) return;
|
|
1137
|
-
tablist.querySelectorAll("[role=\"tab\"]").item(next).focus();
|
|
1138
|
-
onChange(nextTag);
|
|
1139
|
-
};
|
|
1140
|
-
return (0, react_jsx_runtime.jsx)("div", {
|
|
1141
|
-
role: "tablist",
|
|
1142
|
-
"aria-label": ariaLabel,
|
|
1143
|
-
className: WorkbenchSwitch_module_css_default.switch,
|
|
1144
|
-
children: ENTRIES.map((tag, index) => {
|
|
1145
|
-
const active = value === tag;
|
|
1146
|
-
return (0, react_jsx_runtime.jsxs)("button", {
|
|
1147
|
-
type: "button",
|
|
1148
|
-
role: "tab",
|
|
1149
|
-
id: `workbench-tab-${tag}`,
|
|
1150
|
-
"aria-selected": active,
|
|
1151
|
-
"aria-controls": panelId,
|
|
1152
|
-
"aria-label": labels[tag],
|
|
1153
|
-
tabIndex: active ? 0 : -1,
|
|
1154
|
-
title: labels[tag],
|
|
1155
|
-
className: clsx(WorkbenchSwitch_module_css_default.tab, active ? WorkbenchSwitch_module_css_default.activePill : WorkbenchSwitch_module_css_default.inactiveIcon),
|
|
1156
|
-
onClick: () => {
|
|
1157
|
-
onChange(tag);
|
|
1158
|
-
},
|
|
1159
|
-
onKeyDown: (event) => {
|
|
1160
|
-
onKeyDown(event, index);
|
|
1161
|
-
},
|
|
1162
|
-
children: [tag === "coding" ? (0, react_jsx_runtime.jsx)(_qilin_agent_client_ui_primitives.IconTerminalOutline16, { size: 14 }) : (0, react_jsx_runtime.jsx)(_qilin_agent_client_ui_primitives.IconSparkle16, { size: 14 }), active && (0, react_jsx_runtime.jsx)("span", {
|
|
1163
|
-
className: WorkbenchSwitch_module_css_default.label,
|
|
1164
|
-
children: labels[tag]
|
|
1165
|
-
})]
|
|
1166
|
-
}, tag);
|
|
1167
|
-
})
|
|
1168
|
-
});
|
|
1169
|
-
}
|
|
1170
|
-
//#endregion
|
|
1171
|
-
//#region \0qilin-css:/home/runner/work/QiLin/QiLin/packages/client/ui-workspace/src/client/WorkbenchSwitchSeat.module.css.mjs
|
|
1172
|
-
const css$3 = ".ASIh6a_seat{flex:none;padding:0 12px 8px}";
|
|
1173
|
-
const tagId$3 = "@qilin-agent/client-ui-workspace/WorkbenchSwitchSeat.module.css";
|
|
1174
|
-
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$3) + "]") === null) {
|
|
1175
|
-
const tag = document.createElement("style");
|
|
1176
|
-
tag.dataset.plugin = "@qilin-agent/client-ui-workspace";
|
|
1177
|
-
tag.dataset.pluginCss = tagId$3;
|
|
1178
|
-
tag.textContent = css$3;
|
|
1179
|
-
document.head.appendChild(tag);
|
|
1180
|
-
}
|
|
1181
|
-
var WorkbenchSwitchSeat_module_css_default = { "seat": "ASIh6a_seat" };
|
|
1182
|
-
//#endregion
|
|
1183
|
-
//#region lib/types/client/WorkbenchSwitchSeat.js
|
|
1184
|
-
/**
|
|
1185
|
-
* Render the switch seat.
|
|
1186
|
-
* @param props - shell owner share (wide), the bound workbench selector hook,
|
|
1187
|
-
* the switch callback, and the locale seat.
|
|
1188
|
-
* @returns the switch row, or null on the rail.
|
|
1189
|
-
*/
|
|
1190
|
-
function WorkbenchSwitchSeat({ wide, useWorkbench, onWorkbenchSwitch, t }) {
|
|
1191
|
-
const workbench = useWorkbench((state) => state);
|
|
1192
|
-
if (!wide) return null;
|
|
1193
|
-
return (0, react_jsx_runtime.jsx)("div", {
|
|
1194
|
-
className: WorkbenchSwitchSeat_module_css_default.seat,
|
|
1195
|
-
children: (0, react_jsx_runtime.jsx)(WorkbenchSwitch, {
|
|
1196
|
-
value: workbench.active,
|
|
1197
|
-
onChange: onWorkbenchSwitch,
|
|
1198
|
-
labels: {
|
|
1199
|
-
general: t("workbench.general"),
|
|
1200
|
-
coding: t("workbench.coding")
|
|
1201
|
-
},
|
|
1202
|
-
ariaLabel: t("workbench.tabs.aria"),
|
|
1203
|
-
panelId: "workbench-list-panel"
|
|
1204
|
-
})
|
|
1205
|
-
});
|
|
1206
|
-
}
|
|
1207
|
-
//#endregion
|
|
1208
929
|
//#region \0qilin-css:/home/runner/work/QiLin/QiLin/packages/client/ui-workspace/src/client/rows/Rows.module.css.mjs
|
|
1209
930
|
const css$2 = ".RrwzeW_projectRow,.RrwzeW_sessionRow{padding:0 8px;cursor:pointer;user-select:none;color:var(--qilin-alias-label-primary);border-radius:8px;align-items:center;gap:6px;padding-inline-start:calc(8px + var(--dsh-workspace-indent,0px));display:flex}.RrwzeW_projectRow:hover,.RrwzeW_sessionRow:hover,.RrwzeW_sessionRow.RrwzeW_selected{background:var(--qilin-alias-interactive-bg-hover)}.RrwzeW_searchResultRow{box-sizing:border-box;cursor:pointer;text-align:left;width:100%;min-height:48px;color:var(--qilin-alias-label-primary);background:0 0;border:none;border-radius:8px;flex-direction:column;align-items:stretch;padding:4px 8px;display:flex}.RrwzeW_searchResultRow:hover,.RrwzeW_searchResultRow.RrwzeW_selected{background:var(--qilin-alias-interactive-bg-hover)}.RrwzeW_searchResultHeading{align-items:center;min-width:0;display:flex}.RrwzeW_searchResultTitle{text-overflow:ellipsis;white-space:nowrap;flex:0 auto;min-width:0;margin-left:4px;font-size:14px;line-height:20px;overflow:hidden}.RrwzeW_searchResultMeta{align-items:center;gap:6px;min-width:0;margin-left:20px;display:flex}.RrwzeW_searchResultWorkspace,.RrwzeW_searchResultSnippet{text-overflow:ellipsis;white-space:nowrap;font-size:12px;line-height:17px;overflow:hidden}.RrwzeW_searchResultWorkspace{max-width:40%;color:var(--qilin-alias-label-tertiary);flex:none}.RrwzeW_searchResultSnippet{min-width:0;color:var(--qilin-alias-label-secondary);flex:1}.RrwzeW_projectRow{box-sizing:border-box;align-items:center;height:34px}.RrwzeW_projectRow .RrwzeW_rowActions{height:20px}.RrwzeW_sessionRow{height:32px;animation:RrwzeW_row-in .15s var(--ds-ease-in-out);gap:0}.RrwzeW_sessionRow .RrwzeW_title{margin:0 6px 0 4px}@keyframes RrwzeW_row-in{0%{opacity:0}}.RrwzeW_slot{width:16px;height:20px;color:var(--qilin-alias-label-tertiary);flex:none;justify-content:center;align-items:center;display:inline-flex}.RrwzeW_visuallyHidden{clip:rect(0 0 0 0);white-space:nowrap;width:1px;height:1px;position:absolute;overflow:hidden}.RrwzeW_folderActive{color:var(--qilin-alias-state-business-primary)}.RrwzeW_projectRow .RrwzeW_chevron{display:none}.RrwzeW_projectRow:hover .RrwzeW_chevron{display:inline-flex}.RrwzeW_projectRow:hover .RrwzeW_folder{display:none}.RrwzeW_arrow{transition:transform .15s var(--ds-ease-in-out)}.RrwzeW_arrowOpen{transform:rotate(90deg)}.RrwzeW_projectText{flex-direction:column;flex:1;gap:2px;min-width:0;display:flex}.RrwzeW_title{text-overflow:ellipsis;white-space:nowrap;min-width:0;font-size:14px;line-height:20px;overflow:hidden}.RrwzeW_renameInput{border:.5px solid var(--qilin-alias-border-l4);background:var(--qilin-alias-button-elevated-fill);min-width:0;color:inherit;border-radius:4px;outline:none;padding:0 2px;font-size:14px;line-height:20px}.RrwzeW_sessionRow .RrwzeW_title{scroll-behavior:smooth;flex:1}@media (hover:hover){.RrwzeW_sessionRow:hover .RrwzeW_title{text-overflow:clip}}.RrwzeW_meta{text-overflow:ellipsis;white-space:nowrap;color:var(--qilin-alias-label-tertiary);font-size:12px;line-height:20px;overflow:hidden}.RrwzeW_time{color:var(--qilin-alias-label-tertiary);flex:none;font-size:12px;line-height:20px}.RrwzeW_dot{flex:none}.RrwzeW_pinIndicator{width:16px;height:20px;color:var(--qilin-alias-label-caption);flex:none;justify-content:center;align-items:center;margin-left:6px;display:inline-flex}.RrwzeW_sessionRow:hover .RrwzeW_pinIndicator,.RrwzeW_sessionRow.RrwzeW_menuOpen .RrwzeW_pinIndicator{display:none}.RrwzeW_rowActions{flex:none;align-items:center;gap:12px;display:none}.RrwzeW_projectRow:hover .RrwzeW_rowActions,.RrwzeW_sessionRow:hover .RrwzeW_rowActions,.RrwzeW_projectRow.RrwzeW_menuOpen .RrwzeW_rowActions,.RrwzeW_sessionRow.RrwzeW_menuOpen .RrwzeW_rowActions{display:inline-flex}.RrwzeW_sessionRow:hover .RrwzeW_time,.RrwzeW_sessionRow.RrwzeW_menuOpen .RrwzeW_time{display:none}.RrwzeW_projectRow.RrwzeW_menuOpen,.RrwzeW_sessionRow.RrwzeW_menuOpen{background:var(--qilin-alias-interactive-bg-hover)}.RrwzeW_sessionRow.RrwzeW_dropBefore,.RrwzeW_sessionRow.RrwzeW_dropAfter{position:relative}.RrwzeW_sessionRow.RrwzeW_dropBefore:before,.RrwzeW_sessionRow.RrwzeW_dropAfter:after{content:\"\";z-index:1;background:linear-gradient(55deg, transparent calc(50% - 1px), var(--qilin-alias-state-business-primary) calc(50% - 1px) calc(50% + 1px), transparent calc(50% + 1px)) 0 0 / 5px 7px no-repeat, linear-gradient(125deg, transparent calc(50% - 1px), var(--qilin-alias-state-business-primary) calc(50% - 1px) calc(50% + 1px), transparent calc(50% + 1px)) 0 5px / 5px 7px no-repeat, linear-gradient(var(--qilin-alias-state-business-primary) 0 0) 4px 5px / calc(100% - 4px) 2px no-repeat;pointer-events:none;height:12px;position:absolute;left:0;right:4px}.RrwzeW_sessionRow.RrwzeW_dropBefore:before{top:-7px}.RrwzeW_sessionRow.RrwzeW_dropAfter:after{bottom:-7px}.RrwzeW_hoverContent{flex-direction:column;gap:8px;display:flex}.RrwzeW_hoverTitle{color:#fff;overflow-wrap:break-word;font-size:14px;line-height:20px}.RrwzeW_hoverPath{color:#cfd3d6;word-break:break-all;font-size:12px;line-height:16px}.RrwzeW_hoverTime{color:#cfd3d6;font-size:12px;line-height:16px}.RrwzeW_hoverStatus{color:#adb2b8;align-items:center;gap:8px;font-size:12px;line-height:20px;display:flex}.RrwzeW_iconButton{cursor:pointer;width:16px;height:16px;color:var(--qilin-alias-label-tertiary);background:0 0;border:none;border-radius:4px;flex:none;justify-content:center;align-items:center;padding:0;display:inline-flex}.RrwzeW_iconButton:hover{color:var(--qilin-alias-label-primary)}.RrwzeW_chevron{color:var(--qilin-alias-label-caption)}@media (prefers-reduced-motion:reduce){.RrwzeW_sessionRow,.RrwzeW_arrow{transition:none;animation:none}.RrwzeW_sessionRow .RrwzeW_title{scroll-behavior:auto}}";
|
|
1210
931
|
const tagId$2 = "@qilin-agent/client-ui-workspace/Rows.module.css";
|
|
@@ -3099,7 +2820,6 @@ window.__ModuleLoader__.load({
|
|
|
3099
2820
|
]
|
|
3100
2821
|
}),
|
|
3101
2822
|
(0, react_jsx_runtime.jsx)("div", {
|
|
3102
|
-
id: "workbench-list-panel",
|
|
3103
2823
|
className: WorkspaceBrowser_module_css_default.listArea,
|
|
3104
2824
|
children: wide && (normalizedQuery !== "" ? (0, react_jsx_runtime.jsx)(SearchResults, {
|
|
3105
2825
|
usePanelInfo,
|
|
@@ -3323,11 +3043,6 @@ window.__ModuleLoader__.load({
|
|
|
3323
3043
|
"shortcut.noCompletedTurn": "当前会话没有已结束的轮次",
|
|
3324
3044
|
"section.workspaces": "工作区",
|
|
3325
3045
|
"section.sessions": "会话",
|
|
3326
|
-
"workbench.tabs.aria": "切换工作台",
|
|
3327
|
-
"workbench.general": "通用",
|
|
3328
|
-
"workbench.coding": "编码",
|
|
3329
|
-
"preset.aria": "运行模式",
|
|
3330
|
-
"preset.hint": "选择新任务使用的运行模式",
|
|
3331
3046
|
"viewOptions.label": "视图选项",
|
|
3332
3047
|
"groupBy.label": "分组方式",
|
|
3333
3048
|
"groupBy.workspace": "按工作区",
|
|
@@ -3404,11 +3119,6 @@ window.__ModuleLoader__.load({
|
|
|
3404
3119
|
"shortcut.noCompletedTurn": "This session has no completed turn",
|
|
3405
3120
|
"section.workspaces": "Workspaces",
|
|
3406
3121
|
"section.sessions": "Sessions",
|
|
3407
|
-
"workbench.tabs.aria": "Switch workbench",
|
|
3408
|
-
"workbench.general": "General",
|
|
3409
|
-
"workbench.coding": "Coding",
|
|
3410
|
-
"preset.aria": "Run mode",
|
|
3411
|
-
"preset.hint": "Choose the run mode for new tasks",
|
|
3412
3122
|
"viewOptions.label": "View options",
|
|
3413
3123
|
"groupBy.label": "Group by",
|
|
3414
3124
|
"groupBy.workspace": "WorkSpace",
|
|
@@ -3493,8 +3203,6 @@ window.__ModuleLoader__.load({
|
|
|
3493
3203
|
"locale",
|
|
3494
3204
|
"remote",
|
|
3495
3205
|
"remote.directoryPicker",
|
|
3496
|
-
"remote.agentPresets",
|
|
3497
|
-
"workbench",
|
|
3498
3206
|
"layout",
|
|
3499
3207
|
"shortcuts"
|
|
3500
3208
|
];
|
|
@@ -3507,24 +3215,19 @@ window.__ModuleLoader__.load({
|
|
|
3507
3215
|
function apply(ctx) {
|
|
3508
3216
|
const sessions = ctx.get("sessions");
|
|
3509
3217
|
const workspaces = ctx.get("workspaces");
|
|
3510
|
-
const workbench = ctx.get("workbench");
|
|
3511
3218
|
const viewHandle = createWorkspaceViewStore();
|
|
3512
3219
|
const viewInstance = viewHandle.create();
|
|
3513
3220
|
const viewStore = {
|
|
3514
3221
|
...viewHandle,
|
|
3515
3222
|
create: () => viewInstance
|
|
3516
3223
|
};
|
|
3517
|
-
const uiWorkspace = new UiWorkspaceService(ctx, ctx.remote.directoryPicker,
|
|
3224
|
+
const uiWorkspace = new UiWorkspaceService(ctx, ctx.remote.directoryPicker, workspaces, sessions, viewInstance.actions);
|
|
3518
3225
|
ctx.slots.provideRoot({ hooks: { workspaces: workspaces.list } });
|
|
3519
3226
|
ctx.effect(() => ctx.locale.register(NS, {
|
|
3520
3227
|
zh,
|
|
3521
3228
|
en
|
|
3522
3229
|
}), "ui-workspace: dictionaries");
|
|
3523
3230
|
const shortcutControls = createWorkspaceShortcutControls();
|
|
3524
|
-
const onWorkbenchSwitch = (tag) => {
|
|
3525
|
-
workbench.setActive(tag);
|
|
3526
|
-
uiWorkspace.rebindBlanksAfterTagSwitch();
|
|
3527
|
-
};
|
|
3528
3231
|
const searchSessions = async (query, signal) => {
|
|
3529
3232
|
const result = await sessions.search(query, signal);
|
|
3530
3233
|
if (!result.ok) throw new Error(result.error.message);
|
|
@@ -3591,14 +3294,6 @@ window.__ModuleLoader__.load({
|
|
|
3591
3294
|
createWorkspace: (input) => workspaces.create(input),
|
|
3592
3295
|
hooks: { directoryFlow: pickerFlowSource }
|
|
3593
3296
|
});
|
|
3594
|
-
ctx.slots.inject("sidebar.workbench", () => ctx.slots.register({
|
|
3595
|
-
name: "sidebar.workbench",
|
|
3596
|
-
inject: () => ({
|
|
3597
|
-
hooks: { workbench: workbench.state },
|
|
3598
|
-
onWorkbenchSwitch
|
|
3599
|
-
}),
|
|
3600
|
-
locale: NS
|
|
3601
|
-
}, WorkbenchSwitchSeat));
|
|
3602
3297
|
ctx.slots.inject("sidebar.workspaces", () => ctx.slots.register({
|
|
3603
3298
|
name: "sidebar.workspaces",
|
|
3604
3299
|
children: {
|
|
@@ -3628,65 +3323,6 @@ window.__ModuleLoader__.load({
|
|
|
3628
3323
|
inject: pickerInjected,
|
|
3629
3324
|
locale: NS
|
|
3630
3325
|
}, WorkspacePicker));
|
|
3631
|
-
const rosterStore = (0, _qilin_agent_client_store.createSnapshotStore)({
|
|
3632
|
-
status: "idle",
|
|
3633
|
-
presets: []
|
|
3634
|
-
});
|
|
3635
|
-
let rosterGeneration = 0;
|
|
3636
|
-
const loadRoster = () => {
|
|
3637
|
-
const generation = ++rosterGeneration;
|
|
3638
|
-
ctx.remote.agentPresets.list().then((result) => {
|
|
3639
|
-
if (generation !== rosterGeneration) return;
|
|
3640
|
-
if (!result.ok && result.error.code === "gateway/invocation-unavailable") {
|
|
3641
|
-
rosterStore.set({
|
|
3642
|
-
status: "ready",
|
|
3643
|
-
presets: []
|
|
3644
|
-
});
|
|
3645
|
-
return;
|
|
3646
|
-
}
|
|
3647
|
-
if (!result.ok) {
|
|
3648
|
-
rosterStore.set({
|
|
3649
|
-
status: "failed",
|
|
3650
|
-
presets: []
|
|
3651
|
-
});
|
|
3652
|
-
return;
|
|
3653
|
-
}
|
|
3654
|
-
rosterStore.set({
|
|
3655
|
-
status: "ready",
|
|
3656
|
-
presets: result.value.presets.filter((preset) => preset.broken === void 0).map((preset) => ({
|
|
3657
|
-
id: preset.id,
|
|
3658
|
-
...preset.name === void 0 ? {} : { name: preset.name },
|
|
3659
|
-
...preset.description === void 0 ? {} : { description: preset.description }
|
|
3660
|
-
}))
|
|
3661
|
-
});
|
|
3662
|
-
}).catch(() => {
|
|
3663
|
-
if (generation === rosterGeneration) rosterStore.set({
|
|
3664
|
-
status: "failed",
|
|
3665
|
-
presets: []
|
|
3666
|
-
});
|
|
3667
|
-
});
|
|
3668
|
-
};
|
|
3669
|
-
ctx.effect(() => {
|
|
3670
|
-
loadRoster();
|
|
3671
|
-
return ctx.on("connection/reset", loadRoster);
|
|
3672
|
-
}, "ui-workspace: preset roster refresh");
|
|
3673
|
-
const pickPreset = (presetId) => {
|
|
3674
|
-
workbench.setPresetFor(workbench.state.getSnapshot().active, presetId);
|
|
3675
|
-
uiWorkspace.adoptBlankSessionPreset(presetId);
|
|
3676
|
-
};
|
|
3677
|
-
ctx.slots.inject("conversation.hero.agentPreset", () => ctx.slots.register({
|
|
3678
|
-
name: "conversation.hero.agentPreset",
|
|
3679
|
-
priority: -1,
|
|
3680
|
-
inject: () => ({
|
|
3681
|
-
hooks: {
|
|
3682
|
-
workbench: workbench.state,
|
|
3683
|
-
roster: rosterStore
|
|
3684
|
-
},
|
|
3685
|
-
tagChoices: (tag) => workbench.tagChoices(tag),
|
|
3686
|
-
pick: pickPreset
|
|
3687
|
-
}),
|
|
3688
|
-
locale: NS
|
|
3689
|
-
}, AgentPresetChip));
|
|
3690
3326
|
}
|
|
3691
3327
|
//#endregion
|
|
3692
3328
|
exports.apply = apply;
|
|
@@ -27,7 +27,6 @@ import type { SessionSearchResultItem } from '@qilin-agent/api-session-controlle
|
|
|
27
27
|
import type { RemoteHostFacts } from '@qilin-agent/api-remotes/client';
|
|
28
28
|
import type { WorkspaceId, WorkspaceView } from '@qilin-agent/api-workspace-controller/client';
|
|
29
29
|
import type { SessionId } from '@qilin-agent/session/types';
|
|
30
|
-
import type { WorkbenchState, WorkbenchTag } from '@qilin-agent/client-ui-workbench/client';
|
|
31
30
|
import type { createWorkspaceViewStore } from '../stores.ts';
|
|
32
31
|
import type { ShortcutCatalogEntry } from '@qilin-agent/client-shortcuts/client';
|
|
33
32
|
import type { WorkspaceShortcutState } from '../shortcuts.ts';
|
|
@@ -192,61 +191,6 @@ export type WorkspaceBrowserInjected = {
|
|
|
192
191
|
path: string;
|
|
193
192
|
}) => Promise<WorkspaceView>;
|
|
194
193
|
};
|
|
195
|
-
/**
|
|
196
|
-
* Injected share of the sidebar-top workbench switch: the tag selection and
|
|
197
|
-
* the switch callback (the same record-and-rebind path the browser list
|
|
198
|
-
* filters through).
|
|
199
|
-
*/
|
|
200
|
-
export type WorkbenchSwitchInjected = {
|
|
201
|
-
hooks: {
|
|
202
|
-
/** The workbench tag selection and per-tag preset memory (the `workbench` service state). */
|
|
203
|
-
workbench: HostObservable<WorkbenchState>;
|
|
204
|
-
};
|
|
205
|
-
/** Switch the workbench tag (see {@link WorkspaceBrowserInjected.onWorkbenchSwitch}). */
|
|
206
|
-
onWorkbenchSwitch: (tag: WorkbenchTag) => void;
|
|
207
|
-
};
|
|
208
|
-
/** One preset row of the run-mode chip's menu: the fields the roster wire carries and the chip shows. */
|
|
209
|
-
export interface AgentPresetChoice {
|
|
210
|
-
/** The preset id new tasks are created with. */
|
|
211
|
-
readonly id: string;
|
|
212
|
-
/** Display name from the preset's own manifest; absent falls back to the id. */
|
|
213
|
-
readonly name?: string;
|
|
214
|
-
/** One-line description shown under the menu name. */
|
|
215
|
-
readonly description?: string;
|
|
216
|
-
}
|
|
217
|
-
/** The roster snapshot the chip's menu renders; an empty list hides the chip. */
|
|
218
|
-
export interface AgentPresetRosterState {
|
|
219
|
-
/** Read outcome: idle before the first read, failed keeps the chip hidden. */
|
|
220
|
-
readonly status: 'idle' | 'ready' | 'failed';
|
|
221
|
-
/** The deployment's presets (an optional service yields the empty list). */
|
|
222
|
-
readonly presets: readonly AgentPresetChoice[];
|
|
223
|
-
}
|
|
224
|
-
/**
|
|
225
|
-
* Injected share of the hero run-mode chip: the workbench state (active tag
|
|
226
|
-
* and each tag's remembered new-task preset), the live roster, and the pick
|
|
227
|
-
* action that records the tag's choice and rebinds the on-screen blank
|
|
228
|
-
* session.
|
|
229
|
-
*/
|
|
230
|
-
export type AgentPresetChipInjected = {
|
|
231
|
-
hooks: {
|
|
232
|
-
/** The workbench tag selection and per-tag preset memory (the `workbench` service state). */
|
|
233
|
-
workbench: HostObservable<WorkbenchState>;
|
|
234
|
-
/** The preset roster snapshot; `failed` and empty rosters hide the chip. */
|
|
235
|
-
roster: HostObservable<AgentPresetRosterState>;
|
|
236
|
-
};
|
|
237
|
-
/**
|
|
238
|
-
* The shipped preset ids one tag's menu offers, in menu order — the
|
|
239
|
-
* workbench owner's vocabulary, reached as a service callback so this
|
|
240
|
-
* package imports no cross-plugin value (the purity gate forbids one).
|
|
241
|
-
*/
|
|
242
|
-
tagChoices: (tag: WorkbenchTag) => readonly string[];
|
|
243
|
-
/** Record one tag's new-task preset choice and align the current blank session. */
|
|
244
|
-
pick: (presetId: string) => void;
|
|
245
|
-
};
|
|
246
|
-
/** Full run-mode chip props: hero owner share + injected state + the locale seat. */
|
|
247
|
-
export type AgentPresetChipProps = PropsRuntime<'conversation.hero.agentPreset'> & PropsHooks<AgentPresetChipInjected['hooks']> & Omit<AgentPresetChipInjected, 'hooks'> & PropsLocale<'workspace'>;
|
|
248
|
-
/** Full switch-seat props: shell owner share + injected selection + the locale seat. */
|
|
249
|
-
export type WorkbenchSwitchSeatProps = PropsRuntime<'sidebar.workbench'> & PropsHooks<WorkbenchSwitchInjected['hooks']> & Omit<WorkbenchSwitchInjected, 'hooks'> & PropsLocale<'workspace'>;
|
|
250
194
|
/** Full browser props: shell owner share + viewing store + injected actions + the locale seat. */
|
|
251
195
|
export type WorkspaceBrowserProps = PropsRuntime<'sidebar.workspaces'> & PropsRenderSlots<'sidebar.workspaces.directoryFlow' | 'sidebar.session.row.leading' | 'sidebar.session.row.hover'> & PropsStore<ReturnType<typeof createWorkspaceViewStore>> & Omit<WorkspaceBrowserInjected, 'hooks'> & PropsHooks<WorkspaceBrowserInjected['hooks']> & PropsLocale<'workspace'>;
|
|
252
196
|
/**
|
|
@@ -13,7 +13,7 @@ import type { WorkspaceSnapshot } from '@qilin-agent/api-workspace-controller/cl
|
|
|
13
13
|
import type { SnapshotSelectorHook } from '@qilin-agent/client-ui-slots';
|
|
14
14
|
import { type WorkspaceKey } from './locales.ts';
|
|
15
15
|
export type { MainSelection, UiWorkspace } from './navigation.ts';
|
|
16
|
-
export type {
|
|
16
|
+
export type { DirectoryFlowOwnerProps, DirectoryFlowSlotName, DirectoryPickingHooks, DirectoryPickingInjected, SessionRowScheduleOwnerProps, WorkspaceBrowserInjected, WorkspaceBrowserProps, WorkspacePickerInjected, WorkspacePickerProps, } from './contract/slots.ts';
|
|
17
17
|
export type { WorkspaceKey } from './locales.ts';
|
|
18
18
|
declare module '@qilin-agent/client-ui-slots' {
|
|
19
19
|
interface GlobalStandardProps {
|
|
@@ -14,11 +14,6 @@ export declare const zh: {
|
|
|
14
14
|
'shortcut.noCompletedTurn': string;
|
|
15
15
|
'section.workspaces': string;
|
|
16
16
|
'section.sessions': string;
|
|
17
|
-
'workbench.tabs.aria': string;
|
|
18
|
-
'workbench.general': string;
|
|
19
|
-
'workbench.coding': string;
|
|
20
|
-
'preset.aria': string;
|
|
21
|
-
'preset.hint': string;
|
|
22
17
|
'viewOptions.label': string;
|
|
23
18
|
'groupBy.label': string;
|
|
24
19
|
'groupBy.workspace': string;
|
|
@@ -97,11 +92,6 @@ export declare const en: {
|
|
|
97
92
|
'shortcut.noCompletedTurn': string;
|
|
98
93
|
'section.workspaces': string;
|
|
99
94
|
'section.sessions': string;
|
|
100
|
-
'workbench.tabs.aria': string;
|
|
101
|
-
'workbench.general': string;
|
|
102
|
-
'workbench.coding': string;
|
|
103
|
-
'preset.aria': string;
|
|
104
|
-
'preset.hint': string;
|
|
105
95
|
'viewOptions.label': string;
|
|
106
96
|
'groupBy.label': string;
|
|
107
97
|
'groupBy.workspace': string;
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
/** Workspace archive and directory UI capability. */
|
|
2
2
|
import { Service, type Context } from '@qilin-agent/kylin';
|
|
3
|
-
import type { ClientRemote, DirectoryListing, RemoteFailure
|
|
3
|
+
import type { ClientRemote, DirectoryListing, RemoteFailure } from '@qilin-agent/api-remotes/client';
|
|
4
4
|
import type { ISessions, SessionTarget } from '@qilin-agent/api-session-controller/client';
|
|
5
5
|
import { type ObservableSnapshot } from '@qilin-agent/client-store';
|
|
6
6
|
import type { SubagentAddress } from '@qilin-agent/subagent/client';
|
|
7
7
|
import type { IWorkspaces, WorkspaceId } from '@qilin-agent/api-workspace-controller/client';
|
|
8
8
|
import type { SessionId } from '@qilin-agent/session/types';
|
|
9
|
-
import type { Workbench } from '@qilin-agent/client-ui-workbench/client';
|
|
10
9
|
import type { WorkspaceViewStoreActions } from './stores.ts';
|
|
11
10
|
/** The main-pane selection a navigation action publishes: one Session, or one direct-parent subagent address. */
|
|
12
11
|
export interface MainSelection {
|
|
@@ -51,13 +50,6 @@ export interface UiWorkspace {
|
|
|
51
50
|
* @param workspaceId - explicit target; absent inherits the current or most recent Workspace.
|
|
52
51
|
*/
|
|
53
52
|
startSession(workspaceId?: WorkspaceId): void;
|
|
54
|
-
/**
|
|
55
|
-
* Switch the current blank Session to an explicitly picked new-task preset
|
|
56
|
-
* (the hero chip's per-tag choice; the next new task already names it at
|
|
57
|
-
* create). A started or absent Session keeps its composition.
|
|
58
|
-
* @param presetId - the picked preset id.
|
|
59
|
-
*/
|
|
60
|
-
adoptBlankSessionPreset(presetId: string): void;
|
|
61
53
|
/**
|
|
62
54
|
* Archive a Session and clear it when it is the current selection.
|
|
63
55
|
* @param sessionId - Session to archive.
|
|
@@ -111,26 +103,9 @@ export declare class DirectoryBrowseError extends Error {
|
|
|
111
103
|
/** @param rpcError - Host directory business failure. */
|
|
112
104
|
constructor(rpcError: RemoteFailure);
|
|
113
105
|
}
|
|
114
|
-
/**
|
|
115
|
-
* The preset-switch caller the browsing region consumes: the one Remote method
|
|
116
|
-
* the blank-session tag rebind needs, stated structurally so consumers pass the
|
|
117
|
-
* live namespace or a test double without a cast.
|
|
118
|
-
*/
|
|
119
|
-
export interface AgentPresetSwitcher {
|
|
120
|
-
/**
|
|
121
|
-
* Switch one blank session's agent composition to a preset.
|
|
122
|
-
* @param id - the blank session to recompose.
|
|
123
|
-
* @param agentPreset - the preset id to compose from.
|
|
124
|
-
* @returns the recorded preset id, or a failure (`agent-preset/locked` once
|
|
125
|
-
* the session has started).
|
|
126
|
-
*/
|
|
127
|
-
select(id: SessionId, agentPreset: string): Promise<RemoteResult<string>>;
|
|
128
|
-
}
|
|
129
106
|
/** Implements Workspace archive and directory UI operations. */
|
|
130
107
|
declare class UiWorkspaceService extends Service implements UiWorkspace {
|
|
131
108
|
private readonly directoryPicker;
|
|
132
|
-
private readonly agentPresets;
|
|
133
|
-
private readonly workbench;
|
|
134
109
|
private readonly workspaces;
|
|
135
110
|
private readonly sessions;
|
|
136
111
|
private readonly view;
|
|
@@ -146,32 +121,12 @@ declare class UiWorkspaceService extends Service implements UiWorkspace {
|
|
|
146
121
|
/**
|
|
147
122
|
* @param ctx - Client root Context.
|
|
148
123
|
* @param directoryPicker - the directory-picking Remote namespace.
|
|
149
|
-
* @param agentPresets - the preset-switch caller, for the blank-session
|
|
150
|
-
* tag rebind (D3: a blank session may switch presets; a started one may not).
|
|
151
|
-
* @param workbench - the tag state owner, supplying each new task's preset
|
|
152
|
-
* and the visibility fold the reuse rule checks.
|
|
153
124
|
* @param workspaces - pure Workspace Controller.
|
|
154
125
|
* @param sessions - pure Session Controller.
|
|
155
126
|
* @param view - the browser's viewing-store write set, which owns saved Session order.
|
|
156
127
|
*/
|
|
157
|
-
constructor(ctx: Context, directoryPicker: ClientRemote['directoryPicker'],
|
|
128
|
+
constructor(ctx: Context, directoryPicker: ClientRemote['directoryPicker'], workspaces: IWorkspaces, sessions: ISessions, view: Pick<WorkspaceViewStoreActions, 'pinSessionOrder'>);
|
|
158
129
|
connectWorkspace(workspaceId: WorkspaceId): Promise<SessionId>;
|
|
159
|
-
/**
|
|
160
|
-
* Rebind every blank session of the current Workspace to the now-active
|
|
161
|
-
* tag's preset. Blank sessions carried over from the other tag would
|
|
162
|
-
* otherwise sit hidden in this tag's filtered list; a non-blank session
|
|
163
|
-
* stays exactly as it is (the Host refuses non-blank switches anyway).
|
|
164
|
-
*/
|
|
165
|
-
rebindBlanksAfterTagSwitch(): void;
|
|
166
|
-
/**
|
|
167
|
-
* Switch one blank session to the active tag's preset when the preset it
|
|
168
|
-
* was created under does not show under this tag. Fire-and-forget: the
|
|
169
|
-
* session stays usable either way, and a `locked` verdict means it engaged
|
|
170
|
-
* mid-rebind, so its own preset stands.
|
|
171
|
-
* @param id - the blank session to align.
|
|
172
|
-
*/
|
|
173
|
-
private rebindBlankToActiveTag;
|
|
174
|
-
adoptBlankSessionPreset(presetId: string): void;
|
|
175
130
|
openSession(target: SessionTarget): void;
|
|
176
131
|
openWorkspace(workspaceId: WorkspaceId, beforeOpen?: (sessionId: SessionId) => void): Promise<void>;
|
|
177
132
|
forkSession(sessionId: SessionId): Promise<void>;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qilin-agent/client-ui-workspace",
|
|
3
3
|
"description": "Workspace picker plugin: one WorkspacePicker registered into the sidebar and empty-state workspace slots",
|
|
4
|
-
"version": "3.1.
|
|
4
|
+
"version": "3.1.5",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -41,8 +41,7 @@
|
|
|
41
41
|
"@qilin-agent/client-ui-layout",
|
|
42
42
|
"@qilin-agent/client-ui-renderer",
|
|
43
43
|
"@qilin-agent/client-ui-session",
|
|
44
|
-
"@qilin-agent/client-ui-sidebar"
|
|
45
|
-
"@qilin-agent/client-ui-workbench"
|
|
44
|
+
"@qilin-agent/client-ui-sidebar"
|
|
46
45
|
],
|
|
47
46
|
"platform": "web"
|
|
48
47
|
}
|
|
@@ -55,28 +54,27 @@
|
|
|
55
54
|
"@types/react": "~18.3.1",
|
|
56
55
|
"clsx": "^2.0.0",
|
|
57
56
|
"react": "^18.2.0",
|
|
58
|
-
"@qilin-agent/api-remotes": "3.1.
|
|
59
|
-
"@qilin-agent/api-session-controller": "3.1.
|
|
60
|
-
"@qilin-agent/
|
|
61
|
-
"@qilin-agent/client-
|
|
62
|
-
"@qilin-agent/client-
|
|
63
|
-
"@qilin-agent/
|
|
64
|
-
"@qilin-agent/client-
|
|
65
|
-
"@qilin-agent/client-
|
|
66
|
-
"@qilin-agent/client-ui-conversation": "3.1.
|
|
67
|
-
"@qilin-agent/client-ui-layout": "3.1.
|
|
68
|
-
"@qilin-agent/client-ui-primitives": "3.1.
|
|
69
|
-
"@qilin-agent/client-ui-
|
|
70
|
-
"@qilin-agent/client-ui-sidebar": "3.1.
|
|
71
|
-
"@qilin-agent/client-ui-
|
|
72
|
-
"@qilin-agent/client-ui-slots": "3.1.3",
|
|
73
|
-
"@qilin-agent/schedule": "3.1.3",
|
|
74
|
-
"@qilin-agent/session": "3.1.3",
|
|
75
|
-
"@qilin-agent/client-ui-workbench": "3.1.3",
|
|
76
|
-
"@qilin-agent/typert-protocol": "3.1.3",
|
|
77
|
-
"@qilin-agent/subagent": "3.1.3",
|
|
57
|
+
"@qilin-agent/api-remotes": "3.1.5",
|
|
58
|
+
"@qilin-agent/api-session-controller": "3.1.5",
|
|
59
|
+
"@qilin-agent/client-shortcuts": "3.1.5",
|
|
60
|
+
"@qilin-agent/client-locale": "3.1.5",
|
|
61
|
+
"@qilin-agent/client-connection": "3.1.5",
|
|
62
|
+
"@qilin-agent/api-workspace-controller": "3.1.5",
|
|
63
|
+
"@qilin-agent/client-store": "3.1.5",
|
|
64
|
+
"@qilin-agent/client-test-runtime": "3.1.5",
|
|
65
|
+
"@qilin-agent/client-ui-conversation": "3.1.5",
|
|
66
|
+
"@qilin-agent/client-ui-layout": "3.1.5",
|
|
67
|
+
"@qilin-agent/client-ui-primitives": "3.1.5",
|
|
68
|
+
"@qilin-agent/client-ui-renderer": "3.1.5",
|
|
69
|
+
"@qilin-agent/client-ui-sidebar": "3.1.5",
|
|
70
|
+
"@qilin-agent/client-ui-slots": "3.1.5",
|
|
78
71
|
"@qilin-agent/kylin": "~4.0.3",
|
|
79
|
-
"@qilin-agent/
|
|
72
|
+
"@qilin-agent/client-ui-session": "3.1.5",
|
|
73
|
+
"@qilin-agent/schedule": "3.1.5",
|
|
74
|
+
"@qilin-agent/subagent": "3.1.5",
|
|
75
|
+
"@qilin-agent/typert-protocol": "3.1.5",
|
|
76
|
+
"@qilin-agent/session": "3.1.5",
|
|
77
|
+
"@qilin-agent/util-workspace-path": "3.1.5"
|
|
80
78
|
},
|
|
81
79
|
"files": [
|
|
82
80
|
"lib/index.js",
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { ReactNode } from 'react';
|
|
2
|
-
import type { AgentPresetChipProps } from './contract/slots.ts';
|
|
3
|
-
/**
|
|
4
|
-
* Render the run-mode chip.
|
|
5
|
-
* @param props - the bound workbench and roster selector hooks, the tag
|
|
6
|
-
* vocabulary and pick actions, and the locale seat.
|
|
7
|
-
* @returns the chip, or null when there is nothing to choose.
|
|
8
|
-
*/
|
|
9
|
-
export declare function AgentPresetChip({ useWorkbench, useRoster, tagChoices, pick, t }: AgentPresetChipProps): ReactNode;
|
|
10
|
-
//# sourceMappingURL=AgentPresetChip.d.ts.map
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The sidebar-top workbench switch seat: the mutual-hide switch between the
|
|
3
|
-
* brand row and New Session. The shell renders the seat only while the column
|
|
4
|
-
* is wide; the switch itself keeps the browser's list panel as its aria panel.
|
|
5
|
-
*/
|
|
6
|
-
import type { ReactNode } from 'react';
|
|
7
|
-
import type { WorkbenchSwitchSeatProps } from './contract/slots.ts';
|
|
8
|
-
/**
|
|
9
|
-
* Render the switch seat.
|
|
10
|
-
* @param props - shell owner share (wide), the bound workbench selector hook,
|
|
11
|
-
* the switch callback, and the locale seat.
|
|
12
|
-
* @returns the switch row, or null on the rail.
|
|
13
|
-
*/
|
|
14
|
-
export declare function WorkbenchSwitchSeat({ wide, useWorkbench, onWorkbenchSwitch, t }: WorkbenchSwitchSeatProps): ReactNode;
|
|
15
|
-
//# sourceMappingURL=WorkbenchSwitchSeat.d.ts.map
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The dual-workbench switch: the active tag renders as an outlined pill with
|
|
3
|
-
* icon and label, the inactive tag collapses to an icon-only button. Visual
|
|
4
|
-
* order is constant (coding left, general right); the pill and icon roles
|
|
5
|
-
* swap with the active tag.
|
|
6
|
-
*/
|
|
7
|
-
import type { ReactNode } from 'react';
|
|
8
|
-
import type { WorkbenchTag } from '@qilin-agent/client-ui-workbench/client';
|
|
9
|
-
/**
|
|
10
|
-
* Render the two-tag switch. Both tags stay mounted and reachable — only the
|
|
11
|
-
* label of the inactive one is hidden — so the tab semantics of the previous
|
|
12
|
-
* segmented control carry over: roving tab stop on the selected tag,
|
|
13
|
-
* Left/Right to move selection.
|
|
14
|
-
* @param props.value - the active tag.
|
|
15
|
-
* @param props.onChange - selection requested by click or Left/Right.
|
|
16
|
-
* @param props.labels - localized tag names, keyed by tag; the inactive
|
|
17
|
-
* button's accessible name (its label is hidden).
|
|
18
|
-
* @param props.ariaLabel - localized accessible name for the tab list.
|
|
19
|
-
* @param props.panelId - DOM id of the panel the tabs control.
|
|
20
|
-
* @returns the tab list, without its panel.
|
|
21
|
-
*/
|
|
22
|
-
export declare function WorkbenchSwitch({ value, onChange, labels, ariaLabel, panelId }: {
|
|
23
|
-
value: WorkbenchTag;
|
|
24
|
-
onChange: (tag: WorkbenchTag) => void;
|
|
25
|
-
labels: Readonly<Record<WorkbenchTag, string>>;
|
|
26
|
-
ariaLabel: string;
|
|
27
|
-
panelId: string;
|
|
28
|
-
}): ReactNode;
|
|
29
|
-
//# sourceMappingURL=WorkbenchSwitch.d.ts.map
|