@lesliechan721/aw 0.1.0-beta.27 → 0.1.0-beta.29
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/src/commands/status-v6.d.ts +3 -0
- package/dist/src/commands/status-v6.js +37 -10
- package/dist/src/commands/status-v6.js.map +1 -1
- package/dist/src/portable/skills-cli.js +35 -4
- package/dist/src/portable/skills-cli.js.map +1 -1
- package/dist/src/tui/catalog-sources/screens.js +5 -5
- package/dist/src/tui/catalog-sources/screens.js.map +1 -1
- package/dist/src/tui/console-app-v4.js +469 -139
- package/dist/src/tui/console-app-v4.js.map +1 -1
- package/dist/src/tui/controller-runtime.js +16 -8
- package/dist/src/tui/controller-runtime.js.map +1 -1
- package/dist/src/tui/controller.d.ts +31 -0
- package/dist/src/tui/controller.js +119 -19
- package/dist/src/tui/controller.js.map +1 -1
- package/dist/src/utils/plugin-intent-state.d.ts +15 -0
- package/dist/src/utils/plugin-intent-state.js +34 -3
- package/dist/src/utils/plugin-intent-state.js.map +1 -1
- package/package.json +3 -3
|
@@ -43,11 +43,13 @@ function pluginFilterLabel(filter) {
|
|
|
43
43
|
function paginationActions(options) {
|
|
44
44
|
return [
|
|
45
45
|
{
|
|
46
|
+
actionId: 'pagination-previous',
|
|
46
47
|
label: 'p 上一页',
|
|
47
48
|
disabled: options.offset <= 0 ? '已在第一页' : undefined,
|
|
48
49
|
run: () => options.move(-1),
|
|
49
50
|
},
|
|
50
51
|
{
|
|
52
|
+
actionId: 'pagination-next',
|
|
51
53
|
label: 'n 下一页',
|
|
52
54
|
disabled: options.offset + options.pageRows >= options.total ? '已在最后一页' : undefined,
|
|
53
55
|
run: () => options.move(1),
|
|
@@ -1091,6 +1093,10 @@ export function ConsoleAppV4(props) {
|
|
|
1091
1093
|
const [sourceDraft, setSourceDraft] = useState();
|
|
1092
1094
|
const [batchDraft, setBatchDraft] = useState();
|
|
1093
1095
|
const [batchTargetOffset, setBatchTargetOffset] = useState(0);
|
|
1096
|
+
const [portableResultDetailOpen, setPortableResultDetailOpen] = useState(false);
|
|
1097
|
+
const [portableResultDetailOffset, setPortableResultDetailOffset] = useState(0);
|
|
1098
|
+
const portableResultDetailPairKey = useRef(undefined);
|
|
1099
|
+
const portableResultDetailReturnFocus = useRef(0);
|
|
1094
1100
|
const [expandedDependencyPluginIds, setExpandedDependencyPluginIds] = useState();
|
|
1095
1101
|
const [sourceInput, setSourceInput] = useState('');
|
|
1096
1102
|
const [sourceInputError, setSourceInputError] = useState();
|
|
@@ -1106,6 +1112,7 @@ export function ConsoleAppV4(props) {
|
|
|
1106
1112
|
const [sourceDependenciesExpanded, setSourceDependenciesExpanded] = useState(false);
|
|
1107
1113
|
const [portableAgentInput, setPortableAgentInput] = useState('');
|
|
1108
1114
|
const [portableSelectionView, setPortableSelectionView] = useState('all');
|
|
1115
|
+
const [portableToolsOpen, setPortableToolsOpen] = useState(false);
|
|
1109
1116
|
const [reportSaveMode, setReportSaveMode] = useState(false);
|
|
1110
1117
|
const [reportSavePath, setReportSavePath] = useState('');
|
|
1111
1118
|
const [reportSaveResult, setReportSaveResult] = useState();
|
|
@@ -1114,6 +1121,7 @@ export function ConsoleAppV4(props) {
|
|
|
1114
1121
|
const dynamicMenuFocus = useRef(undefined);
|
|
1115
1122
|
const pluginListFocusId = useRef(undefined);
|
|
1116
1123
|
const dependencyGraphContexts = useRef(new Map());
|
|
1124
|
+
const selectedDependencyReferenceIndex = useRef(0);
|
|
1117
1125
|
const externalDraftRevision = useRef({ config: 0, source: 0, batch: 0 });
|
|
1118
1126
|
const previousExternalDraftValues = useRef({
|
|
1119
1127
|
configDrafts, configCandidate, objectDrafts, changedObjectDraftKeys, sourceDraft, batchDraft,
|
|
@@ -1164,6 +1172,11 @@ export function ConsoleAppV4(props) {
|
|
|
1164
1172
|
const timer = setInterval(() => setClockTick((value) => value + 1), 1_000);
|
|
1165
1173
|
return () => clearInterval(timer);
|
|
1166
1174
|
}, [busy, route.name === 'progress' ? route.operationId : '']);
|
|
1175
|
+
useEffect(() => {
|
|
1176
|
+
setPortableResultDetailOpen(false);
|
|
1177
|
+
setPortableResultDetailOffset(0);
|
|
1178
|
+
portableResultDetailPairKey.current = undefined;
|
|
1179
|
+
}, [route.name, route.name === 'result' ? route.operationId : '']);
|
|
1167
1180
|
const tooSmall = policy.mode === 'too-small';
|
|
1168
1181
|
const requestExit = (request) => {
|
|
1169
1182
|
if (exitSent.current)
|
|
@@ -1852,6 +1865,10 @@ export function ConsoleAppV4(props) {
|
|
|
1852
1865
|
setSourceReferenceSummary({ blocked: true, inventoryComplete: false, dependencies: [] }); });
|
|
1853
1866
|
return () => abort.abort();
|
|
1854
1867
|
}, [props.controller, route.name, route.name === 'sourceRemoveBlocked' ? route.sourceId : '']);
|
|
1868
|
+
useEffect(() => {
|
|
1869
|
+
if (route.name !== 'portableSkillSelect')
|
|
1870
|
+
setPortableToolsOpen(false);
|
|
1871
|
+
}, [route.name]);
|
|
1855
1872
|
const screenId = resolveConsoleV4ScreenId(snapshot, props.controller, overlay, tooSmall, searchFocus);
|
|
1856
1873
|
const portableVariantCandidates = route.name === 'portableSkillSelect' && snapshot.portableDraft
|
|
1857
1874
|
? snapshot.portableDraft.candidates.filter(portableScopeVariantsDiffer)
|
|
@@ -1862,6 +1879,7 @@ export function ConsoleAppV4(props) {
|
|
|
1862
1879
|
: snapshot.portableDraft.candidates
|
|
1863
1880
|
: [];
|
|
1864
1881
|
const supportsTechnicalDetails = snapshot.phase === 'error'
|
|
1882
|
+
|| Boolean(snapshot.projectIntentIssue)
|
|
1865
1883
|
|| Boolean(route.name === 'reviewPreparing' && snapshot.reviewPreparation?.code)
|
|
1866
1884
|
|| Boolean(route.name === 'progress' && snapshot.progress.messages.length > 0)
|
|
1867
1885
|
|| Boolean(route.name === 'review' && snapshot.activeReview?.technicalDetails?.length)
|
|
@@ -1869,6 +1887,7 @@ export function ConsoleAppV4(props) {
|
|
|
1869
1887
|
&& issue.diagnostic.technical)
|
|
1870
1888
|
|| Boolean(route.name === 'pluginDependencies' && plugin)
|
|
1871
1889
|
|| Boolean(route.name === 'pluginDependencyNode' && plugin)
|
|
1890
|
+
|| route.name === 'catalogStoreRules'
|
|
1872
1891
|
|| portableVariantCandidates.length > 0
|
|
1873
1892
|
|| Boolean(route.name === 'portableDependencies' && plugin
|
|
1874
1893
|
&& props.controller.getPluginDependencyOverview(plugin.pluginId)?.dependencies.length)
|
|
@@ -1893,6 +1912,7 @@ export function ConsoleAppV4(props) {
|
|
|
1893
1912
|
let confirmationPagination;
|
|
1894
1913
|
let pluginRows = [];
|
|
1895
1914
|
let pinnedActions = [];
|
|
1915
|
+
let selectAllPortableCandidates;
|
|
1896
1916
|
let togglePluginListFilter;
|
|
1897
1917
|
let movePluginListSource;
|
|
1898
1918
|
let visibleConfigTabs = [];
|
|
@@ -1926,11 +1946,32 @@ export function ConsoleAppV4(props) {
|
|
|
1926
1946
|
: route.name === 'pluginDetail' ? policy.mode === 'compact' ? 6 : 8
|
|
1927
1947
|
: route.name === 'operationHistory' ? 4
|
|
1928
1948
|
: route.name === 'operationReportPreview' ? 5 : 0;
|
|
1949
|
+
let currentActionViewportLineBudget = pageActionBudget(actionViewportStaticRows);
|
|
1950
|
+
let portableResultDetailPagination;
|
|
1929
1951
|
const responsiveBudget = (compactRows, standardRows) => {
|
|
1930
1952
|
const baseline = policy.mode === 'compact' ? 18 : 24;
|
|
1931
1953
|
const base = policy.mode === 'compact' ? compactRows : standardRows;
|
|
1932
1954
|
return base + Math.max(0, size.rows - baseline);
|
|
1933
1955
|
};
|
|
1956
|
+
const sourceTechnicalPageRows = policy.mode === 'compact'
|
|
1957
|
+
? 1 : Math.max(1, responsiveBudget(5, 10) - 1);
|
|
1958
|
+
const resolveSourceTechnicalDiagnostic = (sourceId) => {
|
|
1959
|
+
const overview = props.controller.getSourceOverview(sourceId);
|
|
1960
|
+
return sourceDiagnostic(sourceId, overview.health?.state ?? overview.source?.state, overview.detail, props.controller.getCatalogGeneration(sourceId), props.controller.getCatalogFreshness(sourceId)) ?? {
|
|
1961
|
+
severity: 'warning',
|
|
1962
|
+
title: '来源解析详情',
|
|
1963
|
+
userMessage: '来源当前可用。',
|
|
1964
|
+
impact: [{ state: 'preserved', message: '当前来源状态没有阻止操作。' }],
|
|
1965
|
+
nextStep: '返回来源详情。',
|
|
1966
|
+
technical: {
|
|
1967
|
+
code: 'catalogSourceReady',
|
|
1968
|
+
stage: 'resolve-source',
|
|
1969
|
+
sourceId,
|
|
1970
|
+
...(overview.detail?.requestedRef ? { requestedRef: overview.detail.requestedRef } : {}),
|
|
1971
|
+
...(overview.detail?.resolvedCommit ? { resolvedCommit: overview.detail.resolvedCommit } : {}),
|
|
1972
|
+
},
|
|
1973
|
+
};
|
|
1974
|
+
};
|
|
1934
1975
|
const moveBatchTargetPage = (total, pageRows, direction) => {
|
|
1935
1976
|
const lastOffset = Math.max(0, total - 1);
|
|
1936
1977
|
setBatchTargetOffset((value) => Math.min(lastOffset, Math.max(0, value + direction * pageRows)));
|
|
@@ -1964,8 +2005,16 @@ export function ConsoleAppV4(props) {
|
|
|
1964
2005
|
setActionError(undefined);
|
|
1965
2006
|
};
|
|
1966
2007
|
const toggleTechnical = () => {
|
|
2008
|
+
if (portableResultDetailOpen)
|
|
2009
|
+
setFocus(portableResultDetailReturnFocus.current);
|
|
2010
|
+
setPortableResultDetailOpen(false);
|
|
2011
|
+
setPortableResultDetailOffset(0);
|
|
1967
2012
|
setShowTechnical((value) => !value);
|
|
1968
|
-
|
|
2013
|
+
if (!(route.name === 'result' && snapshot.result
|
|
2014
|
+
&& 'operationKind' in snapshot.result
|
|
2015
|
+
&& snapshot.result.operationKind === 'portableInstall')) {
|
|
2016
|
+
setBatchTargetOffset(0);
|
|
2017
|
+
}
|
|
1969
2018
|
};
|
|
1970
2019
|
const restorePageContext = () => {
|
|
1971
2020
|
const restoredFrame = props.controller.snapshot.router.current;
|
|
@@ -3065,10 +3114,22 @@ export function ConsoleAppV4(props) {
|
|
|
3065
3114
|
else if (rendererFamily === 'home' && route.name === 'home') {
|
|
3066
3115
|
const home = snapshot.viewModel.home;
|
|
3067
3116
|
const projectReminder = snapshot.projectIntentReminder;
|
|
3117
|
+
const projectIntentIssue = snapshot.projectIntentIssue;
|
|
3068
3118
|
const projectPendingCount = (projectReminder?.actionableTargets.length ?? 0)
|
|
3069
3119
|
+ (projectReminder?.blockedTargets.length ?? 0);
|
|
3070
3120
|
context = '当前项目';
|
|
3071
3121
|
actions = [
|
|
3122
|
+
...(projectIntentIssue ? [{
|
|
3123
|
+
actionId: 'project-intent-issue',
|
|
3124
|
+
label: projectIntentIssue.state === 'invalid'
|
|
3125
|
+
? '本项目插件声明无效'
|
|
3126
|
+
: '无法读取本项目插件声明',
|
|
3127
|
+
description: projectIntentIssue.state === 'invalid'
|
|
3128
|
+
? '本项目插件声明无效;修复后重新加载'
|
|
3129
|
+
: '无法读取本项目插件声明;检查项目位置或权限后重新加载',
|
|
3130
|
+
status: 'warning',
|
|
3131
|
+
run: () => toggleTechnical(),
|
|
3132
|
+
}] : []),
|
|
3072
3133
|
...(projectPendingCount > 0 ? [{
|
|
3073
3134
|
label: '项目插件',
|
|
3074
3135
|
description: projectReminder.actionableTargets.length > 0
|
|
@@ -3093,12 +3154,16 @@ export function ConsoleAppV4(props) {
|
|
|
3093
3154
|
run: () => go({ name: 'sourceList' }),
|
|
3094
3155
|
},
|
|
3095
3156
|
];
|
|
3096
|
-
content = _jsxs(Box, { flexDirection: "column", children: [
|
|
3157
|
+
content = _jsxs(Box, { flexDirection: "column", children: [projectIntentIssue && !showTechnical
|
|
3158
|
+
? _jsx(StaticRow, { status: "warning", title: projectIntentIssue.state === 'invalid'
|
|
3159
|
+
? '本项目插件声明无效'
|
|
3160
|
+
: '无法读取本项目插件声明', description: "\u5065\u5EB7\u6765\u6E90\u3001\u4E2A\u4EBA\u63D2\u4EF6\u548C\u5B89\u5168\u8BCA\u65AD\u4ECD\u53EF\u4F7F\u7528\u3002\u4FEE\u590D\u540E\u6309 H \u91CD\u65B0\u52A0\u8F7D\u3002" })
|
|
3161
|
+
: null, projectIntentIssue && showTechnical ? _jsxs(TechnicalDetails, { title: "\u9879\u76EE\u58F0\u660E\u8BCA\u65AD", children: [_jsx(StaticRow, { title: "\u72B6\u6001", meta: projectIntentIssue.state === 'invalid' ? '声明无效' : '无法读取', compact: true }), _jsx(StaticRow, { title: "\u9519\u8BEF\u4EE3\u7801", meta: projectIntentIssue.code, compact: true }), _jsx(StaticRow, { title: "\u8BF4\u660E", meta: sanitizeDiagnosticText(projectIntentIssue.message), compact: true })] }) : null, !showTechnical && projectPendingCount > 0
|
|
3097
3162
|
? _jsx(Callout, { status: "warning", title: `本项目有 ${projectPendingCount} 个插件目标尚未就绪`, description: `${projectReminder.actionableTargets.length} 个可同步;`
|
|
3098
3163
|
+ `${projectReminder.blockedTargets.length} 个需要先处理。` })
|
|
3099
|
-
: projectReminder && projectReminder.unconfirmedTargets.length > 0
|
|
3164
|
+
: !showTechnical && projectReminder && projectReminder.unconfirmedTargets.length > 0
|
|
3100
3165
|
? _jsx(Callout, { status: "info", title: "\u90E8\u5206\u9879\u76EE\u63D2\u4EF6\u72B6\u6001\u65E0\u6CD5\u786E\u8BA4", description: "\u6CA1\u6709\u628A\u672A\u89C2\u6D4B\u72B6\u6001\u89E3\u91CA\u4E3A\u7F3A\u5931\u3002\u8BF7\u68C0\u67E5\u6765\u6E90\u6216\u5DE5\u5177\u72B6\u6001\u540E\u91CD\u65B0\u52A0\u8F7D\u3002" })
|
|
3101
|
-
: null, _jsxs(StatusCard, { status: home.issueCount > 0 || home.unavailableSourceCount > 0 ? 'warning' : 'success', title: "\u5F53\u524D\u72B6\u6001", children: [_jsx(ResultRow, { title: `已添加 ${home.installedPlugins} 个插件`, status: "muted" }), _jsx(ResultRow, { title: `${home.issueCount} 项需要处理`, status: home.issueCount > 0 ? 'warning' : 'muted' }), home.unavailableSourceCount > 0 ? _jsx(ResultRow, { title: `${home.unavailableSourceCount} 个来源不可用`, status: "error" }) : null, home.catalogCheckingCount > 0 ? _jsx(ResultRow, { title: `${home.catalogCheckingCount} 个插件来源正在检查`, status: "muted" }) : null, home.catalogUpdateCount > 0 ? _jsx(ResultRow, { title: `${home.catalogUpdateCount} 个插件来源有更新`, status: "warning" }) : null, home.pluginUpdateCount > 0 ? _jsx(ResultRow, { title: `${home.pluginUpdateCount} 个插件可更新`, status: "warning" }) : null, home.catalogRecoveryCount > 0 ? _jsx(ResultRow, { title: `${home.catalogRecoveryCount} 个插件来源需要检查或恢复`, status: "warning" }) : null] }), _jsx(SemanticRows, { actions: actions, focus: focus, kind: "task", compact: policy.mode === 'compact' })] });
|
|
3166
|
+
: null, !showTechnical ? _jsxs(StatusCard, { status: home.issueCount > 0 || home.unavailableSourceCount > 0 ? 'warning' : 'success', title: "\u5F53\u524D\u72B6\u6001", children: [_jsx(ResultRow, { title: `已添加 ${home.installedPlugins} 个插件`, status: "muted" }), _jsx(ResultRow, { title: `${home.issueCount} 项需要处理`, status: home.issueCount > 0 ? 'warning' : 'muted' }), home.unavailableSourceCount > 0 ? _jsx(ResultRow, { title: `${home.unavailableSourceCount} 个来源不可用`, status: "error" }) : null, home.catalogCheckingCount > 0 ? _jsx(ResultRow, { title: `${home.catalogCheckingCount} 个插件来源正在检查`, status: "muted" }) : null, home.catalogUpdateCount > 0 ? _jsx(ResultRow, { title: `${home.catalogUpdateCount} 个插件来源有更新`, status: "warning" }) : null, home.pluginUpdateCount > 0 ? _jsx(ResultRow, { title: `${home.pluginUpdateCount} 个插件可更新`, status: "warning" }) : null, home.catalogRecoveryCount > 0 ? _jsx(ResultRow, { title: `${home.catalogRecoveryCount} 个插件来源需要检查或恢复`, status: "warning" }) : null] }) : null, _jsx(SemanticRows, { actions: actions, focus: focus, kind: "task", compact: policy.mode === 'compact' })] });
|
|
3102
3167
|
}
|
|
3103
3168
|
else if (route.name === 'pluginList') {
|
|
3104
3169
|
const sourceId = route.sourceId ?? 'all';
|
|
@@ -3877,20 +3942,44 @@ export function ConsoleAppV4(props) {
|
|
|
3877
3942
|
skillName: candidate.name,
|
|
3878
3943
|
}),
|
|
3879
3944
|
}));
|
|
3880
|
-
|
|
3881
|
-
|
|
3882
|
-
|
|
3883
|
-
|
|
3884
|
-
|
|
3945
|
+
selectAllPortableCandidates = { actionId: 'portable-selection-select-all', label: '全选当前结果', run: () => {
|
|
3946
|
+
for (const candidate of visibleCandidates) {
|
|
3947
|
+
if (!candidate.selected)
|
|
3948
|
+
props.controller.togglePortableSkill(candidate.name);
|
|
3949
|
+
}
|
|
3950
|
+
setPortableToolsOpen(false);
|
|
3951
|
+
} };
|
|
3952
|
+
const selectionToolActions = [
|
|
3953
|
+
selectAllPortableCandidates,
|
|
3954
|
+
{ actionId: 'portable-selection-filter', label: portableSelectionView === 'selected' ? '查看全部候选' : `只看已选(${draft.selectedCount})`, run: () => {
|
|
3885
3955
|
setPortableSelectionView((current) => current === 'all' ? 'selected' : 'all');
|
|
3956
|
+
setPortableToolsOpen(false);
|
|
3957
|
+
setFocus(0);
|
|
3958
|
+
setScrollOffset(0);
|
|
3959
|
+
} },
|
|
3960
|
+
{ actionId: 'portable-selection-clear', label: '清空选择', disabled: draft.selectedCount === 0 ? '当前没有已选 Skill' : undefined, run: () => {
|
|
3961
|
+
props.controller.clearPortableSkills();
|
|
3962
|
+
setPortableToolsOpen(false);
|
|
3963
|
+
setFocus(0);
|
|
3964
|
+
setScrollOffset(0);
|
|
3965
|
+
} },
|
|
3966
|
+
...(plugin.dependencySummary?.totalCount ? [{ actionId: 'portable-selection-dependencies', label: '查看依赖关系', run: () => go({ name: 'portableDependencies', pluginId: plugin.pluginId }) }] : []),
|
|
3967
|
+
{ actionId: 'portable-selection-tools-back', label: '返回 Skills 列表', run: () => {
|
|
3968
|
+
setPortableToolsOpen(false);
|
|
3886
3969
|
setFocus(0);
|
|
3887
3970
|
setScrollOffset(0);
|
|
3888
3971
|
} },
|
|
3889
|
-
{ label: '清空选择', disabled: draft.selectedCount === 0 ? '当前没有已选 Skill' : undefined, run: () => props.controller.clearPortableSkills() },
|
|
3890
|
-
...(plugin.dependencySummary?.totalCount ? [{ label: '查看依赖关系', run: () => go({ name: 'portableDependencies', pluginId: plugin.pluginId }) }] : []),
|
|
3891
3972
|
];
|
|
3892
|
-
const
|
|
3893
|
-
|
|
3973
|
+
const continueAction = { actionId: 'portable-selection-continue', label: `继续(${draft.selectedCount})`, meta: draft.canContinue ? undefined : '至少选择一个 Skill', disabled: draft.canContinue ? undefined : '至少选择一个 Skill', run: continuePortableSelection };
|
|
3974
|
+
const openToolsAction = { actionId: 'portable-selection-tools', label: '选择工具', run: () => {
|
|
3975
|
+
setPortableToolsOpen(true);
|
|
3976
|
+
setFocusZone('content');
|
|
3977
|
+
setFocus(0);
|
|
3978
|
+
setScrollOffset(0);
|
|
3979
|
+
} };
|
|
3980
|
+
pinnedActions = [continueAction, openToolsAction];
|
|
3981
|
+
actions = portableToolsOpen ? selectionToolActions : candidateActions;
|
|
3982
|
+
const candidateViewport = portableSkillCandidateViewport(candidateActions, visibleCandidates, policy.mode === 'compact', focus, scrollOffset, pageActionBudget(2 + (portableVariantCandidates.length > 0 ? 3 : 0)));
|
|
3894
3983
|
const viewport = showTechnical
|
|
3895
3984
|
? { offset: focus < visibleCandidates.length ? focus : candidateViewport.offset, limit: 1 }
|
|
3896
3985
|
: candidateViewport;
|
|
@@ -3905,19 +3994,29 @@ export function ConsoleAppV4(props) {
|
|
|
3905
3994
|
const focusedVariant = variantCandidates.find((candidate) => candidate.name === visibleCandidates[focus]?.name);
|
|
3906
3995
|
const visibleVariant = visibleCandidateEntries.find((entry) => portableScopeVariantsDiffer(entry.candidate))?.candidate;
|
|
3907
3996
|
const technicalVariant = focusedVariant ?? visibleVariant ?? variantCandidates[0];
|
|
3908
|
-
help =
|
|
3909
|
-
|
|
3910
|
-
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
|
|
3914
|
-
|
|
3915
|
-
|
|
3916
|
-
|
|
3917
|
-
|
|
3918
|
-
|
|
3919
|
-
|
|
3920
|
-
|
|
3997
|
+
help = portableToolsOpen
|
|
3998
|
+
? '↑↓ 移动 · Enter 选择 · Tab 返回固定栏 · Esc 返回'
|
|
3999
|
+
: focusZone === 'actions'
|
|
4000
|
+
? '←→/↑↓ 移动操作 · Enter 选择 · Tab 返回列表 · c 继续 · Esc 返回'
|
|
4001
|
+
: '↑↓ 移动 · Space 切换 · Enter 查看摘要 · Tab 固定栏 · c 继续 · Esc 返回';
|
|
4002
|
+
content = _jsxs(Box, { flexDirection: "column", children: [_jsx(PinnedActionBar, { actions: pinnedActions.map((action) => ({
|
|
4003
|
+
id: action.actionId, label: action.label, disabled: Boolean(action.disabled),
|
|
4004
|
+
})), active: focusZone === 'actions', focus: pinnedActionFocus }), _jsxs(ContentViewport, { children: [portableToolsOpen
|
|
4005
|
+
? _jsx(SemanticRows, { actions: selectionToolActions, focus: focusZone === 'content' ? focus : -1, kind: "action", compact: policy.mode === 'compact' })
|
|
4006
|
+
: showTechnical ? visibleCandidateEntries.map(({ action, index }) => _jsx(ToggleRow, { title: action.label, selected: Boolean(action.selected), focused: focusZone === 'content' && focus === index, compact: true }, String(action.label))) : providerGroups.map((entries) => {
|
|
4007
|
+
const provider = entries[0].candidate;
|
|
4008
|
+
const relation = provider.relation === 'requested' ? '当前插件'
|
|
4009
|
+
: provider.relation === 'direct' ? '直接依赖插件' : '间接依赖插件';
|
|
4010
|
+
return _jsx(SectionCard, { title: provider.providerDisplayName, meta: relation, compact: policy.mode === 'compact', children: entries.map(({ action, index }) => _jsx(ToggleRow, { title: action.label, description: action.description, selected: Boolean(action.selected), focused: focusZone === 'content' && focus === index, compact: policy.mode === 'compact' }, String(action.label))) }, provider.providerPluginId);
|
|
4011
|
+
}), !portableToolsOpen && variantCandidates.length > 0
|
|
4012
|
+
? showTechnical
|
|
4013
|
+
? _jsx(StaticRow, { title: `! ${variantCandidates.length} 个 Skill 存在范围变体`, status: "warning", compact: true })
|
|
4014
|
+
: _jsx(Callout, { status: "warning", title: `! ${variantCandidates.length} 个 Skill 在不同安装范围会生成不同内容。选择范围后会重新确认最终内容。` })
|
|
4015
|
+
: null, !portableToolsOpen && visibleCandidates.length === 0
|
|
4016
|
+
? _jsx(StaticRow, { title: "\u6CA1\u6709\u5DF2\u9009 Skill", description: "\u9009\u62E9\u201C\u67E5\u770B\u5168\u90E8\u5019\u9009\u201D\u540E\u53EF\u7EE7\u7EED\u52FE\u9009", status: "muted", compact: true })
|
|
4017
|
+
: null, !portableToolsOpen && !draft.canContinue
|
|
4018
|
+
? _jsx(StaticRow, { title: "\u81F3\u5C11\u9009\u62E9\u4E00\u4E2A Skill", status: "warning", compact: true })
|
|
4019
|
+
: null, !portableToolsOpen && showTechnical && technicalVariant ? _jsxs(TechnicalDetails, { title: "\u8303\u56F4\u53D8\u4F53", children: [_jsx(StaticRow, { title: `${technicalVariant.name} · ${portableScopeVariantLabel('project', technicalVariant.scopeDetails.project)}`, compact: true }, `${technicalVariant.name}:project`), _jsx(StaticRow, { title: `${technicalVariant.name} · ${portableScopeVariantLabel('user', technicalVariant.scopeDetails.user)}`, compact: true }, `${technicalVariant.name}:user`), variantCandidates.length > 1 ? _jsx(StaticRow, { title: `另有 ${variantCandidates.length - 1} 个 Skill 的范围变体已折叠`, status: "muted", compact: true }) : null] }) : null] })] });
|
|
3921
4020
|
}
|
|
3922
4021
|
else if (route.name === 'portableSkillSummary' && plugin && snapshot.portableDraft) {
|
|
3923
4022
|
const candidate = snapshot.portableDraft.candidates.find((entry) => entry.name === route.skillName);
|
|
@@ -4012,7 +4111,7 @@ export function ConsoleAppV4(props) {
|
|
|
4012
4111
|
: overview?.dependents ?? [];
|
|
4013
4112
|
const dependencyCount = overview?.dependencies.length ?? 0;
|
|
4014
4113
|
const dependentCount = visibleDependents.length;
|
|
4015
|
-
const dependentLimit = responsiveBudget(
|
|
4114
|
+
const dependentLimit = responsiveBudget(1, 3);
|
|
4016
4115
|
const dependencyRows = (entries, limit, dependent = false, offset = 0) => {
|
|
4017
4116
|
const safeOffset = Math.min(offset, Math.max(0, entries.length - 1));
|
|
4018
4117
|
const visible = entries.slice(safeOffset, safeOffset + limit);
|
|
@@ -4026,7 +4125,7 @@ export function ConsoleAppV4(props) {
|
|
|
4026
4125
|
context = '已阻止';
|
|
4027
4126
|
title = `无法移除 ${plugin.displayName}`;
|
|
4028
4127
|
description = '仍有插件依赖它。请先处理依赖者,再重新尝试。';
|
|
4029
|
-
|
|
4128
|
+
const blockedRemovalActions = [
|
|
4030
4129
|
{ label: '查看完整依赖关系', run: () => {
|
|
4031
4130
|
props.controller.replace({ name: 'pluginDependencies', pluginId: plugin.pluginId });
|
|
4032
4131
|
setFocus(0);
|
|
@@ -4035,11 +4134,23 @@ export function ConsoleAppV4(props) {
|
|
|
4035
4134
|
{ label: '返回插件详情', run: back },
|
|
4036
4135
|
{ label: showTechnical ? '隐藏技术详情' : '技术详情', run: () => toggleTechnical() },
|
|
4037
4136
|
];
|
|
4137
|
+
const blockedRemovalPagination = !showTechnical && visibleDependents.length > dependentLimit
|
|
4138
|
+
? paginationActions({
|
|
4139
|
+
offset: batchTargetOffset,
|
|
4140
|
+
total: visibleDependents.length,
|
|
4141
|
+
pageRows: dependentLimit,
|
|
4142
|
+
move: (direction) => moveBatchTargetPage(visibleDependents.length, dependentLimit, direction),
|
|
4143
|
+
})
|
|
4144
|
+
: [];
|
|
4145
|
+
actions = [...blockedRemovalPagination, ...blockedRemovalActions];
|
|
4146
|
+
if (blockedRemovalPagination.length > 0) {
|
|
4147
|
+
referenceDetailPagination = { total: visibleDependents.length, pageRows: dependentLimit };
|
|
4148
|
+
}
|
|
4038
4149
|
const blockedRemovalViewport = actionViewport(actions, policy.mode === 'compact', focus, scrollOffset, pageActionBudget(5));
|
|
4039
4150
|
if (!showTechnical && visibleDependents.length > dependentLimit) {
|
|
4040
|
-
help = '
|
|
4151
|
+
help = 'p/n 查看全部被依赖关系 · ↑↓ 移动 · Enter 选择 · Esc 返回';
|
|
4041
4152
|
}
|
|
4042
|
-
content = _jsxs(Box, { flexDirection: "column", children: [_jsx(
|
|
4153
|
+
content = _jsxs(Box, { flexDirection: "column", children: [_jsx(StaticRow, { title: `${dependentCount} 个已安装插件仍在使用`, status: "error", compact: true }), _jsx(StaticRow, { title: "\u6CA1\u6709\u4FEE\u6539\u4EFB\u4F55\u5B89\u88C5\u3002", status: "muted", compact: true }), showTechnical ? null : _jsxs(_Fragment, { children: [_jsx(StaticRow, { title: "\u4F7F\u7528\u8FD9\u4E2A\u4F9D\u8D56\u7684\u63D2\u4EF6", meta: "\u53CD\u5411\u5F15\u7528", compact: true }), dependencyRows(visibleDependents, dependentLimit, true, batchTargetOffset)] }), _jsx(SemanticRows, { actions: actions, focus: focus, kind: "action", compact: policy.mode === 'compact', offset: blockedRemovalViewport.offset, limit: blockedRemovalViewport.limit }), showTechnical ? _jsx(IssueTechnicalDetails, { details: [{
|
|
4043
4154
|
code: 'dependencyStillRequired',
|
|
4044
4155
|
message: '已安装插件仍在使用这个依赖;请先处理依赖者。',
|
|
4045
4156
|
}], compact: policy.mode === 'compact' }) : null] });
|
|
@@ -4222,9 +4333,10 @@ export function ConsoleAppV4(props) {
|
|
|
4222
4333
|
description = showTechnical
|
|
4223
4334
|
? '显示当前选择的完整引用字段。'
|
|
4224
4335
|
: '这些位置的所需依赖当前可用,且本次检查发现它们同时满足依赖声明和安装位置。';
|
|
4225
|
-
|
|
4226
|
-
|
|
4227
|
-
const
|
|
4336
|
+
if (!showTechnical && references[focus])
|
|
4337
|
+
selectedDependencyReferenceIndex.current = focus;
|
|
4338
|
+
const selectedReferenceIndex = Math.min(selectedDependencyReferenceIndex.current, Math.max(0, references.length - 1));
|
|
4339
|
+
const selectedReference = references[selectedReferenceIndex];
|
|
4228
4340
|
const referenceIdLines = (label, pluginId) => {
|
|
4229
4341
|
const prefix = `${label} · `;
|
|
4230
4342
|
return wrapConsoleText(pluginId, Math.max(1, size.columns - 10 - stringWidth(prefix)))
|
|
@@ -4247,8 +4359,24 @@ export function ConsoleAppV4(props) {
|
|
|
4247
4359
|
total: referenceDetailLines.length,
|
|
4248
4360
|
pageRows: referenceDetailPageRows,
|
|
4249
4361
|
} : undefined;
|
|
4362
|
+
const referencePaginationActions = showTechnical
|
|
4363
|
+
&& referenceDetailLines.length > referenceDetailPageRows
|
|
4364
|
+
? paginationActions({
|
|
4365
|
+
offset: referenceDetailOffset,
|
|
4366
|
+
total: referenceDetailLines.length,
|
|
4367
|
+
pageRows: referenceDetailPageRows,
|
|
4368
|
+
move: (direction) => moveBatchTargetPage(referenceDetailLines.length, referenceDetailPageRows, direction),
|
|
4369
|
+
})
|
|
4370
|
+
: [];
|
|
4371
|
+
actions = [
|
|
4372
|
+
...(showTechnical && referenceActions[selectedReferenceIndex]
|
|
4373
|
+
? [referenceActions[selectedReferenceIndex]] : referenceActions),
|
|
4374
|
+
...referencePaginationActions,
|
|
4375
|
+
{ label: '返回节点详情', run: back },
|
|
4376
|
+
];
|
|
4377
|
+
const referenceViewport = actionViewport(actions, policy.mode === 'compact', focus, scrollOffset, responsiveBudget(3, 6));
|
|
4250
4378
|
help = showTechnical
|
|
4251
|
-
? '
|
|
4379
|
+
? 'p/n 查看当前位置详情 · ↑↓ 移动 · Enter 选择 · d 隐藏技术详情 · Esc 返回节点详情'
|
|
4252
4380
|
: '↑↓ 查看全部位置 · d 技术详情 · Enter 返回节点详情 · Esc 返回节点详情';
|
|
4253
4381
|
content = _jsxs(Box, { flexDirection: "column", children: [showTechnical ? null
|
|
4254
4382
|
: _jsx(StaticRow, { title: "\u672C\u6B21\u68C0\u67E5", value: "\u53EA\u68C0\u67E5\u5F53\u524D\u9879\u76EE\u548C\u4E2A\u4EBA\u4F4D\u7F6E\uFF1B\u5176\u4ED6\u9879\u76EE\u672A\u68C0\u67E5", status: "muted", compact: true }), showTechnical && referenceDetailOffset > 0
|
|
@@ -5971,15 +6099,16 @@ export function ConsoleAppV4(props) {
|
|
|
5971
6099
|
: totals ? `${totals.reclaimableBytes} bytes` : '正在检查';
|
|
5972
6100
|
actions = [
|
|
5973
6101
|
{
|
|
6102
|
+
actionId: 'catalog-store-prune-preview',
|
|
5974
6103
|
label: '预览安全清理',
|
|
5975
6104
|
description: totals ? `${totals.reclaimableEntries} 个可回收项 · ${sizeText}` : '先读取当前存储状态',
|
|
5976
6105
|
...(totals && totals.reclaimableEntries > 0
|
|
5977
6106
|
? { run: () => beginReview({ kind: 'catalogStorePrune' }) }
|
|
5978
6107
|
: { disabled: catalogStoreError ? '当前无法读取本地存储' : totals ? '没有可回收项' : '正在检查' }),
|
|
5979
6108
|
},
|
|
5980
|
-
{ label: '查看保留规则', description: '
|
|
5981
|
-
{ label: '重新检查', description: '重新读取当前本地存储', run: () => setCatalogStoreRefresh((value) => value + 1) },
|
|
5982
|
-
{ label: '返回来源列表', run: back },
|
|
6109
|
+
{ actionId: 'catalog-store-rules', label: '查看保留规则', description: '了解哪些目录会保留,以及旧版本何时可以清理', run: () => go({ name: 'catalogStoreRules' }) },
|
|
6110
|
+
{ actionId: 'catalog-store-refresh', label: '重新检查', description: '重新读取当前本地存储', run: () => setCatalogStoreRefresh((value) => value + 1) },
|
|
6111
|
+
{ actionId: 'catalog-store-back', label: '返回来源列表', run: back },
|
|
5983
6112
|
];
|
|
5984
6113
|
content = _jsxs(Box, { flexDirection: "column", children: [catalogStoreError
|
|
5985
6114
|
? _jsx(Callout, { status: "warning", title: "\u672C\u5730\u5B58\u50A8\u68C0\u67E5\u5931\u8D25", description: "\u672A\u6267\u884C\u5220\u9664\u3002\u8BF7\u68C0\u67E5 Catalog \u914D\u7F6E\u548C\u672C\u5730\u5B58\u50A8\u540E\u91CD\u8BD5\u3002" })
|
|
@@ -5990,9 +6119,13 @@ export function ConsoleAppV4(props) {
|
|
|
5990
6119
|
else if (route.name === 'catalogStoreRules') {
|
|
5991
6120
|
breadcrumb = '插件来源 / 本地存储 / 保留规则';
|
|
5992
6121
|
title = '安全清理规则';
|
|
5993
|
-
description =
|
|
5994
|
-
|
|
5995
|
-
|
|
6122
|
+
description = policy.mode === 'compact'
|
|
6123
|
+
? '' : '清理前会再次检查每个项目,只删除能够确认安全的旧内容。';
|
|
6124
|
+
actions = [
|
|
6125
|
+
{ actionId: 'catalog-store-rules-technical', label: showTechnical ? '隐藏技术详情' : '技术详情', run: () => toggleTechnical() },
|
|
6126
|
+
{ actionId: 'catalog-store-rules-back', label: '返回存储概览', run: back },
|
|
6127
|
+
];
|
|
6128
|
+
content = _jsxs(Box, { flexDirection: "column", children: [!showTechnical ? _jsxs(_Fragment, { children: [_jsx(SectionCard, { title: "\u59CB\u7EC8\u4FDD\u7559 \u00B7 \u5F53\u524D\u4F7F\u7528\u7684\u76EE\u5F55\u4E0D\u4F1A\u5220\u9664", children: _jsx(StaticRow, { title: "\u4E0D\u5C5E\u4E8E AW\u3001\u65E0\u6CD5\u786E\u8BA4\u5B89\u5168\u6216\u4ECD\u5728\u4F7F\u7528\u7684\u5185\u5BB9\u4F1A\u4FDD\u7559", status: "muted", compact: true }) }), _jsxs(SectionCard, { title: "\u6EE1\u8DB3\u65F6\u95F4\u548C\u5B8C\u6574\u9A8C\u8BC1\u540E\u53EF\u56DE\u6536", children: [_jsx(StaticRow, { title: "\u65E7\u7248\u672C\u6EE1\u8DB3\u4FDD\u7559\u671F\u9650\u540E\u624D\u6E05\u7406", compact: true }), _jsx(StaticRow, { title: "\u672A\u5B8C\u6210\u7684\u4E0B\u8F7D\u6216\u66FF\u6362\u5185\u5BB9\u81F3\u5C11\u4FDD\u7559 24 \u5C0F\u65F6", compact: true }), _jsx(StaticRow, { title: "\u9694\u79BB\u5185\u5BB9\u81F3\u5C11\u4FDD\u7559 24 \u5C0F\u65F6", compact: true }), _jsx(StaticRow, { title: "\u5BF9\u5E94\u6B63\u5F0F\u7248\u672C\u5B8C\u6574\u53EF\u7528\u540E\u624D\u6E05\u7406", compact: true })] })] }) : null, showTechnical ? _jsxs(TechnicalDetails, { title: "\u6E05\u7406\u5224\u5B9A\u8BC1\u636E", children: [_jsx(StaticRow, { title: "\u9501", meta: "AW_HOME \u5199\u9501\u5185\u91CD\u65B0\u68C0\u67E5", compact: true }), _jsx(StaticRow, { title: "\u6B63\u5F0F\u76EE\u5F55\u7248\u672C", meta: "\u975E Active \u9879\u4FDD\u7559 30 \u5929", compact: true }), _jsx(StaticRow, { title: "staging\u3001replacement\u3001delete claim", meta: "\u4FDD\u7559 24 \u5C0F\u65F6", compact: true }), _jsx(StaticRow, { title: "quarantine", meta: "\u4FDD\u7559 24 \u5C0F\u65F6\uFF1B\u5BF9\u5E94\u6B63\u5F0F\u76EE\u5F55\u7248\u672C\u5FC5\u987B\u5B8C\u6574\u5065\u5EB7", compact: true }), _jsx(StaticRow, { title: "\u4FDD\u7559\u8282\u70B9", meta: "foreign\u3001\u7B26\u53F7\u94FE\u63A5\u3001unsafe\u3001\u635F\u574F\u6216\u672A\u77E5\u9879\u76EE", compact: true })] }) : null, _jsx(SemanticRows, { actions: actions, focus: focus, kind: "action", compact: policy.mode === 'compact' })] });
|
|
5996
6129
|
}
|
|
5997
6130
|
else if (route.name === 'sourceDetail') {
|
|
5998
6131
|
const overview = props.controller.getSourceOverview(route.sourceId);
|
|
@@ -6032,14 +6165,18 @@ export function ConsoleAppV4(props) {
|
|
|
6032
6165
|
: logicalIdentityChanged ? '来源发布身份已变化。请编辑来源,或移除后重新添加。'
|
|
6033
6166
|
: '来源没有可用的启用版本。可在这里取得并启用。';
|
|
6034
6167
|
help = '↑↓ 移动 · Enter 选择 · Esc 返回';
|
|
6168
|
+
if (policy.mode === 'compact')
|
|
6169
|
+
description = '';
|
|
6035
6170
|
const generationAction = logicalIdentityChanged ? []
|
|
6036
6171
|
: generationState === 'incompatible' ? [{
|
|
6172
|
+
actionId: 'source-view-incompatible',
|
|
6037
6173
|
label: '查看不兼容详情',
|
|
6038
6174
|
description: '显示所需和缺少的功能支持',
|
|
6039
6175
|
status: 'error',
|
|
6040
6176
|
run: () => go({ name: 'sourceTechnical', sourceId: route.sourceId }),
|
|
6041
6177
|
}]
|
|
6042
6178
|
: generationState === 'repairRequired' ? [{
|
|
6179
|
+
actionId: 'source-repair',
|
|
6043
6180
|
label: '重新下载旧版本并精确修复',
|
|
6044
6181
|
description: '使用当前启用版本的精确提交;成功后保持此版本',
|
|
6045
6182
|
disabled: activationBlocked ? `请先处理:${sourceOperationBlockLabel(activationBlocked)}` : undefined,
|
|
@@ -6049,6 +6186,7 @@ export function ConsoleAppV4(props) {
|
|
|
6049
6186
|
sourceId: route.sourceId,
|
|
6050
6187
|
}),
|
|
6051
6188
|
}, ...(freshness?.state === 'incompatible' ? [] : [{
|
|
6189
|
+
actionId: 'source-replace-damaged',
|
|
6052
6190
|
label: '使用待检查版本替换损坏版本',
|
|
6053
6191
|
description: '旧版本无法取得时使用;进入独立影响确认',
|
|
6054
6192
|
disabled: activationBlocked ? `请先处理:${sourceOperationBlockLabel(activationBlocked)}` : undefined,
|
|
@@ -6060,6 +6198,7 @@ export function ConsoleAppV4(props) {
|
|
|
6060
6198
|
}])]
|
|
6061
6199
|
: freshness?.state === 'incompatible' && generationState !== 'ready' ? []
|
|
6062
6200
|
: generationState !== 'ready' ? [{
|
|
6201
|
+
actionId: 'source-activate',
|
|
6063
6202
|
label: generationState === 'stateInvalid' ? '恢复状态并启用'
|
|
6064
6203
|
: generationState === 'configMismatch' ? '验证并切换' : '获取并启用',
|
|
6065
6204
|
description: '先准备只读的待检查版本确认;确认后才切换当前版本',
|
|
@@ -6073,8 +6212,9 @@ export function ConsoleAppV4(props) {
|
|
|
6073
6212
|
}]
|
|
6074
6213
|
: freshness?.state === 'updateAvailable' || freshness?.state === 'localChangesAvailable'
|
|
6075
6214
|
? [{
|
|
6215
|
+
actionId: 'source-update',
|
|
6076
6216
|
label: freshness.state === 'localChangesAvailable'
|
|
6077
|
-
? '
|
|
6217
|
+
? '应用本地内容变化' : `更新到 ${candidateVersion ?? '待检查版本'}`,
|
|
6078
6218
|
description: '进入确认;确认前不会切换当前版本',
|
|
6079
6219
|
disabled: activationBlocked ? `请先处理:${sourceOperationBlockLabel(activationBlocked)}` : undefined,
|
|
6080
6220
|
run: () => beginReview({ kind: 'catalogGeneration', action: 'update', sourceId: route.sourceId }),
|
|
@@ -6083,6 +6223,7 @@ export function ConsoleAppV4(props) {
|
|
|
6083
6223
|
|| freshness?.state === 'rollbackDetected'
|
|
6084
6224
|
|| freshness?.state === 'incompatible'
|
|
6085
6225
|
? [{
|
|
6226
|
+
actionId: 'source-view-version-problem',
|
|
6086
6227
|
label: freshness.state === 'versionConflict' ? '查看版本冲突'
|
|
6087
6228
|
: freshness.state === 'rollbackDetected' ? '查看回退详情' : '查看不兼容详情',
|
|
6088
6229
|
description: '普通更新已阻止;当前启用版本保持不变',
|
|
@@ -6090,15 +6231,17 @@ export function ConsoleAppV4(props) {
|
|
|
6090
6231
|
run: () => go({ name: 'sourceTechnical', sourceId: route.sourceId }),
|
|
6091
6232
|
}]
|
|
6092
6233
|
: [{
|
|
6234
|
+
actionId: 'source-check',
|
|
6093
6235
|
label: freshness?.state === 'checking' ? '正在检查' : '检查来源',
|
|
6094
6236
|
description: '检查这个来源;检测到变化或异常时完整验证',
|
|
6095
6237
|
disabled: freshness?.state === 'checking' ? '检查正在进行' : undefined,
|
|
6096
6238
|
run: () => props.controller.recheckCatalogSource(route.sourceId),
|
|
6097
6239
|
}];
|
|
6098
6240
|
const managementActions = [
|
|
6099
|
-
{ label: '来源设置', description: '下载方式、版本、自动检查和高级地址目录', run: () => openSourceEdit(route.sourceId) },
|
|
6241
|
+
{ actionId: 'source-settings', label: '来源设置', description: '下载方式、版本、自动检查和高级地址目录', run: () => openSourceEdit(route.sourceId) },
|
|
6100
6242
|
...(generationState === 'incompatible'
|
|
6101
6243
|
|| (freshness?.state === 'incompatible' && generationState !== 'ready') ? [] : [{
|
|
6244
|
+
actionId: 'source-set-primary',
|
|
6102
6245
|
label: generationState === 'ready' ? '设为主来源' : '启用并设为主来源',
|
|
6103
6246
|
description: generationState === 'ready' ? '只改变默认插件来源' : '先启用确认的待检查版本,再设为主来源',
|
|
6104
6247
|
disabled: detail?.primary ? '当前已经是主来源'
|
|
@@ -6114,20 +6257,22 @@ export function ConsoleAppV4(props) {
|
|
|
6114
6257
|
setPrimaryAfterActivation: true,
|
|
6115
6258
|
}),
|
|
6116
6259
|
}]),
|
|
6117
|
-
{ label: '移除来源', description: '移除来源配置', status: 'error', disabled: props.controller.listSources().length <= 1 ? '至少保留一个来源' : detail?.primary ? '主来源不能直接移除' : undefined, run: () => beginReview({ kind: 'sourceMutation', action: 'remove', sourceId: route.sourceId, changes: [{ title: `移除来源 ${route.sourceId}` }] }) },
|
|
6118
|
-
{ label: '技术详情', description: '查看脱敏错误代码和当前版本证据', run: () => go({ name: 'sourceTechnical', sourceId: route.sourceId }) },
|
|
6260
|
+
{ actionId: 'source-remove', label: '移除来源', description: '移除来源配置', status: 'error', disabled: props.controller.listSources().length <= 1 ? '至少保留一个来源' : detail?.primary ? '主来源不能直接移除' : undefined, run: () => beginReview({ kind: 'sourceMutation', action: 'remove', sourceId: route.sourceId, changes: [{ title: `移除来源 ${route.sourceId}` }] }) },
|
|
6261
|
+
{ actionId: 'source-technical', label: '技术详情', description: '查看脱敏错误代码和当前版本证据', run: () => go({ name: 'sourceTechnical', sourceId: route.sourceId }) },
|
|
6119
6262
|
...(generationState !== 'ready'
|
|
6120
6263
|
|| freshness?.state === 'updateAvailable'
|
|
6121
6264
|
|| freshness?.state === 'localChangesAvailable'
|
|
6122
6265
|
|| freshness?.state === 'versionConflict'
|
|
6123
6266
|
|| freshness?.state === 'rollbackDetected'
|
|
6124
6267
|
|| freshness?.state === 'incompatible' ? [{
|
|
6268
|
+
actionId: 'source-check',
|
|
6125
6269
|
label: freshness?.state === 'checking' ? '正在检查' : '检查来源',
|
|
6126
6270
|
description: '检查这个来源;检测到变化或异常时完整验证',
|
|
6127
6271
|
disabled: freshness?.state === 'checking' ? '检查正在进行' : undefined,
|
|
6128
6272
|
run: () => props.controller.recheckCatalogSource(route.sourceId),
|
|
6129
6273
|
}] : []),
|
|
6130
6274
|
{
|
|
6275
|
+
actionId: 'source-full-validate',
|
|
6131
6276
|
label: '完整验证',
|
|
6132
6277
|
description: '强制重新取得并完整验证这个来源',
|
|
6133
6278
|
disabled: freshness?.state === 'checking' ? '检查正在进行' : undefined,
|
|
@@ -6153,10 +6298,11 @@ export function ConsoleAppV4(props) {
|
|
|
6153
6298
|
&& (configuredSource.url.startsWith('git@') || configuredSource.url.startsWith('ssh://'))
|
|
6154
6299
|
? 'SSH' : 'HTTPS';
|
|
6155
6300
|
const versionPolicy = detail?.type === 'path' ? '当前本地内容'
|
|
6156
|
-
: detail?.refPolicy === 'cliChannel' ? '跟随 AW
|
|
6157
|
-
:
|
|
6301
|
+
: detail?.refPolicy === 'cliChannel' ? '跟随 AW 的稳定版或预览版目录'
|
|
6302
|
+
: '固定版本或 Git 引用';
|
|
6158
6303
|
const sourceCount = snapshot.viewModel?.sourceTabs.find((source) => source.id === route.sourceId)?.count;
|
|
6159
6304
|
const checkAction = {
|
|
6305
|
+
actionId: 'source-check',
|
|
6160
6306
|
label: freshness?.state === 'checking' ? '正在检查' : '检查来源',
|
|
6161
6307
|
description: '检查这个来源;检测到变化或异常时完整验证;不会自动启用更新',
|
|
6162
6308
|
disabled: freshness?.state === 'checking' ? '检查正在进行' : undefined,
|
|
@@ -6164,16 +6310,18 @@ export function ConsoleAppV4(props) {
|
|
|
6164
6310
|
};
|
|
6165
6311
|
actions = [
|
|
6166
6312
|
...sourcePrimaryAction,
|
|
6167
|
-
...(sourcePrimaryAction.some((action) => action.
|
|
6313
|
+
...(sourcePrimaryAction.some((action) => action.actionId === 'source-check')
|
|
6168
6314
|
? [] : [checkAction]),
|
|
6169
6315
|
{
|
|
6316
|
+
actionId: 'source-view-plugins',
|
|
6170
6317
|
label: '查看此来源插件',
|
|
6171
6318
|
description: sourceCount === undefined ? '插件数未知' : `${sourceCount} 个插件`,
|
|
6172
6319
|
run: () => go({ name: 'pluginList', mode: 'browse', sourceId: route.sourceId }),
|
|
6173
6320
|
},
|
|
6174
6321
|
managementActions[0],
|
|
6175
|
-
managementActions.find((action) => action.
|
|
6322
|
+
managementActions.find((action) => action.actionId === 'source-remove'),
|
|
6176
6323
|
{
|
|
6324
|
+
actionId: 'source-more',
|
|
6177
6325
|
label: '更多操作',
|
|
6178
6326
|
description: '替换候选、主来源和技术详情',
|
|
6179
6327
|
run: () => go({ name: 'sourceMore', sourceId: route.sourceId }),
|
|
@@ -6276,37 +6424,19 @@ export function ConsoleAppV4(props) {
|
|
|
6276
6424
|
content = _jsx(SemanticRows, { actions: actions, focus: focus, kind: "action", compact: policy.mode === 'compact', offset: viewport.offset, limit: viewport.limit });
|
|
6277
6425
|
}
|
|
6278
6426
|
else if (route.name === 'sourceTechnical') {
|
|
6279
|
-
const
|
|
6280
|
-
const detail = overview.detail;
|
|
6281
|
-
const state = overview.health?.state ?? overview.source?.state;
|
|
6282
|
-
const diagnostic = sourceDiagnostic(route.sourceId, state, detail, props.controller.getCatalogGeneration(route.sourceId), props.controller.getCatalogFreshness(route.sourceId)) ?? {
|
|
6283
|
-
severity: 'warning',
|
|
6284
|
-
title: '来源解析详情',
|
|
6285
|
-
userMessage: '来源当前可用。',
|
|
6286
|
-
impact: [{ state: 'preserved', message: '当前来源状态没有阻止操作。' }],
|
|
6287
|
-
nextStep: '返回来源详情。',
|
|
6288
|
-
technical: {
|
|
6289
|
-
code: 'catalogSourceReady',
|
|
6290
|
-
stage: 'resolve-source',
|
|
6291
|
-
sourceId: route.sourceId,
|
|
6292
|
-
...(detail?.requestedRef ? { requestedRef: detail.requestedRef } : {}),
|
|
6293
|
-
...(detail?.resolvedCommit ? { resolvedCommit: detail.resolvedCommit } : {}),
|
|
6294
|
-
},
|
|
6295
|
-
};
|
|
6427
|
+
const diagnostic = resolveSourceTechnicalDiagnostic(route.sourceId);
|
|
6296
6428
|
breadcrumb = `插件来源 / ${route.sourceId} / 技术详情`;
|
|
6297
6429
|
context = 'p 上一页 · n 下一页';
|
|
6298
6430
|
title = '来源技术诊断';
|
|
6299
6431
|
description = '';
|
|
6300
6432
|
help = 'p/n 或 PgUp/PgDn 查看全部技术详情 · Enter 选择 · Esc 返回';
|
|
6301
|
-
const
|
|
6302
|
-
? 1 : Math.max(1, responsiveBudget(5, 10) - 1);
|
|
6303
|
-
const sourceTechnicalLastOffset = Math.max(0, diagnosticDetailRowCount(diagnostic) - sourceTechnicalRows);
|
|
6433
|
+
const sourceTechnicalLastOffset = Math.max(0, diagnosticDetailRowCount(diagnostic) - sourceTechnicalPageRows);
|
|
6304
6434
|
actions = [
|
|
6305
|
-
{ label: 'p 上一页', run: () => setBatchTargetOffset((value) => Math.max(0, value -
|
|
6306
|
-
{ label: 'n 下一页', run: () => setBatchTargetOffset((value) => Math.min(sourceTechnicalLastOffset, value +
|
|
6435
|
+
{ label: 'p 上一页', run: () => setBatchTargetOffset((value) => Math.max(0, value - sourceTechnicalPageRows)) },
|
|
6436
|
+
{ label: 'n 下一页', run: () => setBatchTargetOffset((value) => Math.min(sourceTechnicalLastOffset, value + sourceTechnicalPageRows)) },
|
|
6307
6437
|
{ label: '返回来源详情', run: back },
|
|
6308
6438
|
];
|
|
6309
|
-
content = _jsxs(Box, { flexDirection: "column", children: [_jsx(DiagnosticSummary, { diagnostic: diagnostic, technical: true, compact: policy.mode === 'compact', offset: batchTargetOffset, limit:
|
|
6439
|
+
content = _jsxs(Box, { flexDirection: "column", children: [_jsx(DiagnosticSummary, { diagnostic: diagnostic, technical: true, compact: policy.mode === 'compact', offset: batchTargetOffset, limit: sourceTechnicalPageRows }), _jsx(SemanticRows, { actions: actions, focus: focus, kind: "action", compact: policy.mode === 'compact' })] });
|
|
6310
6440
|
}
|
|
6311
6441
|
else if (route.name === 'sourceAdd' && sourceDraft?.owner === route.owner) {
|
|
6312
6442
|
breadcrumb = sourceDraft.mode === 'add' ? '插件来源 / 添加' : `插件来源 / ${sourceDraft.sourceId} / 编辑`;
|
|
@@ -6514,15 +6644,24 @@ export function ConsoleAppV4(props) {
|
|
|
6514
6644
|
setBatchTargetOffset(0);
|
|
6515
6645
|
} }, { label: '返回来源详情', run: back }];
|
|
6516
6646
|
const countLabel = (value, unit) => value === undefined ? '未知' : `${value} ${unit}`;
|
|
6517
|
-
const referenceLimit = Math.max(1, pageActionBudget(
|
|
6647
|
+
const referenceLimit = Math.max(1, pageActionBudget(12));
|
|
6518
6648
|
const references = sourceReferenceSummary?.dependencies ?? [];
|
|
6519
6649
|
const referenceOffset = Math.min(batchTargetOffset, Math.max(0, references.length - 1));
|
|
6520
6650
|
const visibleReferences = references.slice(referenceOffset, referenceOffset + referenceLimit);
|
|
6521
6651
|
const hiddenReferences = Math.max(0, references.length - referenceOffset - visibleReferences.length);
|
|
6522
6652
|
if (sourceDependenciesExpanded && references.length > referenceLimit) {
|
|
6523
|
-
|
|
6653
|
+
actions.unshift(...paginationActions({
|
|
6654
|
+
offset: referenceOffset,
|
|
6655
|
+
total: references.length,
|
|
6656
|
+
pageRows: referenceLimit,
|
|
6657
|
+
move: (direction) => moveBatchTargetPage(references.length, referenceLimit, direction),
|
|
6658
|
+
}));
|
|
6659
|
+
referenceDetailPagination = { total: references.length, pageRows: referenceLimit };
|
|
6660
|
+
help = 'p/n 查看全部引用 · ↑↓ 移动 · Enter 选择 · Esc 返回';
|
|
6524
6661
|
}
|
|
6525
|
-
content = _jsxs(Box, { flexDirection: "column", children: [_jsx(Callout, { status: "error", title: sourceReferenceSummary?.inventoryComplete === false ? '引用清单不完整' : '发现活动引用' }), _jsxs(SectionCard, { title:
|
|
6662
|
+
content = _jsxs(Box, { flexDirection: "column", children: [_jsx(Callout, { status: "error", title: sourceReferenceSummary?.inventoryComplete === false ? '引用清单不完整' : '发现活动引用' }), _jsxs(SectionCard, { title: sourceDependenciesExpanded
|
|
6663
|
+
? referenceOffset > 0 ? `引用内容 · ↑ 前面还有 ${referenceOffset} 项` : '引用内容'
|
|
6664
|
+
: '引用汇总', children: [!sourceDependenciesExpanded ? _jsxs(_Fragment, { children: [_jsx(StaticRow, { title: "\u5B89\u88C5\u4F4D\u7F6E", meta: countLabel(sourceReferenceSummary?.installationCount, '个') }), _jsx(StaticRow, { title: "\u63D2\u4EF6\u8BBE\u7F6E", meta: countLabel(sourceReferenceSummary?.configCount, '份') }), _jsx(StaticRow, { title: "\u751F\u547D\u5468\u671F\u610F\u56FE", meta: countLabel(sourceReferenceSummary?.lifecycleCount, '项') }), _jsx(StaticRow, { title: "Marketplace", meta: countLabel(sourceReferenceSummary?.marketplaceCount, '个') })] }) : null, sourceDependenciesExpanded ? visibleReferences.map((dependency, index) => _jsx(StaticRow, { title: `${dependency.category} · ${dependency.pluginId ?? dependency.sourceId ?? '身份未知'}`, meta: `${dependency.platform ? platformLabel(dependency.platform) : ''}${dependency.scope ? ` · ${scopeLabel(dependency.scope)}` : ''}` }, `${dependency.category}:${dependency.pluginId ?? dependency.sourceId ?? referenceOffset + index}`)) : null, sourceDependenciesExpanded && hiddenReferences > 0 ? _jsx(StaticRow, { title: `↓ 后面还有 ${hiddenReferences} 项`, status: "muted", compact: true }) : null] }), _jsx(SemanticRows, { actions: actions, focus: focus, kind: "action", compact: policy.mode === 'compact' })] });
|
|
6526
6665
|
}
|
|
6527
6666
|
else if (route.name === 'issueList') {
|
|
6528
6667
|
const issues = props.controller.listUserIssues();
|
|
@@ -6625,9 +6764,26 @@ export function ConsoleAppV4(props) {
|
|
|
6625
6764
|
|| entry.id === 'keepUserScope' || entry.id === 'keepProjectScope' ? 'error' : undefined,
|
|
6626
6765
|
run: () => runIssueAction(entry),
|
|
6627
6766
|
}));
|
|
6767
|
+
const issueDetailRows = diagnosticDetailRowCount(issue.diagnostic);
|
|
6768
|
+
const issueDetailPageRows = policy.mode === 'compact'
|
|
6769
|
+
? 1
|
|
6770
|
+
: Math.max(1, responsiveBudget(5, 10) - 2);
|
|
6771
|
+
const issuePaginationActions = showTechnical && issueDetailRows > issueDetailPageRows
|
|
6772
|
+
? paginationActions({
|
|
6773
|
+
offset: batchTargetOffset,
|
|
6774
|
+
total: issueDetailRows,
|
|
6775
|
+
pageRows: issueDetailPageRows,
|
|
6776
|
+
move: (direction) => moveBatchTargetPage(issueDetailRows, issueDetailPageRows, direction),
|
|
6777
|
+
})
|
|
6778
|
+
: [];
|
|
6779
|
+
actions.push(...issuePaginationActions);
|
|
6780
|
+
if (issuePaginationActions.length > 0) {
|
|
6781
|
+
referenceDetailPagination = { total: issueDetailRows, pageRows: issueDetailPageRows };
|
|
6782
|
+
help = 'p/n 查看全部技术字段 · ↑↓ 移动 · Enter 选择 · Esc 返回';
|
|
6783
|
+
}
|
|
6628
6784
|
const issuePlugin = issue.pluginId ? props.controller.getPluginOverview(issue.pluginId) : undefined;
|
|
6629
6785
|
const issueOverview = issue.pluginId ? props.controller.getPluginDependencyOverview(issue.pluginId) : undefined;
|
|
6630
|
-
const issueDiagnosticSummary = _jsx(DiagnosticSummary, { diagnostic: issue.diagnostic, technical: showTechnical, offset: showTechnical ? batchTargetOffset : undefined, limit: showTechnical ?
|
|
6786
|
+
const issueDiagnosticSummary = _jsx(DiagnosticSummary, { diagnostic: issue.diagnostic, technical: showTechnical, offset: showTechnical ? batchTargetOffset : undefined, limit: showTechnical ? issueDetailPageRows : undefined, compact: policy.mode === 'compact' || issue.category.startsWith('dependency')
|
|
6631
6787
|
|| issue.category === 'scopeConflict' });
|
|
6632
6788
|
const issueActionViewport = actionViewport(actions, policy.mode === 'compact', focus, scrollOffset, pageActionBudget(6));
|
|
6633
6789
|
const compactTechnicalActionViewport = policy.mode === 'compact' && showTechnical
|
|
@@ -6646,6 +6802,7 @@ export function ConsoleAppV4(props) {
|
|
|
6646
6802
|
{ label: '查看完整依赖关系', run: () => go({ name: 'pluginDependencies', pluginId: issuePlugin.pluginId }) },
|
|
6647
6803
|
{ label: '返回插件详情', run: () => go({ name: 'pluginDetail', pluginId: issuePlugin.pluginId }) },
|
|
6648
6804
|
...(issueHasTechnicalDetails ? [{ label: showTechnical ? '隐藏技术详情' : '技术详情', run: () => toggleTechnical() }] : []),
|
|
6805
|
+
...issuePaginationActions,
|
|
6649
6806
|
];
|
|
6650
6807
|
const dependencyBlockedViewport = policy.mode === 'compact' && showTechnical
|
|
6651
6808
|
? { offset: Math.min(Math.max(0, focus - 1), Math.max(0, actions.length - 2)), limit: 2 }
|
|
@@ -6686,6 +6843,7 @@ export function ConsoleAppV4(props) {
|
|
|
6686
6843
|
} },
|
|
6687
6844
|
{ label: '查看依赖关系', run: () => go({ name: 'pluginDependencies', pluginId: issuePlugin.pluginId }) },
|
|
6688
6845
|
...(issueHasTechnicalDetails ? [{ label: showTechnical ? '隐藏技术详情' : '技术详情', run: () => toggleTechnical() }] : []),
|
|
6846
|
+
...issuePaginationActions,
|
|
6689
6847
|
];
|
|
6690
6848
|
const unsupportedTargetViewport = policy.mode === 'compact' && showTechnical
|
|
6691
6849
|
? { offset: Math.min(Math.max(0, focus - 1), Math.max(0, actions.length - 2)), limit: 2 }
|
|
@@ -7337,6 +7495,8 @@ export function ConsoleAppV4(props) {
|
|
|
7337
7495
|
const portableOperation = operationKind === 'portableInstall';
|
|
7338
7496
|
const portableReceipt = result.state === 'succeeded' || result.state === 'partial'
|
|
7339
7497
|
? result.summary.portable : undefined;
|
|
7498
|
+
const portableResultScope = portableReceipt?.scope ?? result.portableIntent?.scope;
|
|
7499
|
+
const portableResultAgentMode = portableReceipt?.agentMode ?? result.portableIntent?.agentMode;
|
|
7340
7500
|
const portableInstallFailed = portableReceipt?.failureCode === 'portableSkillsCliInstallFailed';
|
|
7341
7501
|
const portableOriginIsDetail = 'returnRoute' in result
|
|
7342
7502
|
&& result.returnRoute?.name === 'pluginDetail';
|
|
@@ -7749,27 +7909,11 @@ export function ConsoleAppV4(props) {
|
|
|
7749
7909
|
: target.state === 'skipped' ? 1 : target.relation === 'requested' ? 2 : 3;
|
|
7750
7910
|
return priority(left) - priority(right);
|
|
7751
7911
|
});
|
|
7752
|
-
const
|
|
7753
|
-
? portableReceipt?.selectedSkills.length ?? snapshot.portableResultSkills?.length ?? 0
|
|
7754
|
-
: 0);
|
|
7755
|
-
if (resultPaginationTotal > 1) {
|
|
7756
|
-
actions.push(...paginationActions({
|
|
7757
|
-
offset: batchTargetOffset,
|
|
7758
|
-
total: resultPaginationTotal,
|
|
7759
|
-
pageRows: 1,
|
|
7760
|
-
move: (direction) => moveBatchTargetPage(resultPaginationTotal, 1, direction),
|
|
7761
|
-
}));
|
|
7762
|
-
referenceDetailPagination = { total: resultPaginationTotal, pageRows: 1 };
|
|
7763
|
-
}
|
|
7764
|
-
const resultActionViewport = actionViewport(actions, true, focus, scrollOffset, pageActionBudget(8));
|
|
7912
|
+
const baseResultPaginationTotal = Math.max(resultTargets.length, taskSummary?.rootResults.reduce((count, root) => count + 1 + (taskSummary.requestedTargets.filter((target) => target.pluginId === root.pluginId).length), 0) ?? 0, (resultSummary?.batch?.rootResults.length ?? 0) + resultTargets.length);
|
|
7765
7913
|
const resultExtraRows = (resultSummary?.elapsedMs !== undefined ? 1 : 0)
|
|
7766
7914
|
+ visibleMessages.length
|
|
7767
7915
|
+ visibleChanges.length
|
|
7768
7916
|
+ (partial && hasPreservedTarget && resultTargets.some((target) => target.state === 'skipped') ? 1 : 0);
|
|
7769
|
-
const resultTargetLimit = prefixRowLimit(prioritizedTargets.map(() => policy.mode === 'compact' ? 1 : 2), pageActionBudget() - 3 - resultActionViewport.limit - resultExtraRows);
|
|
7770
|
-
const resultTargetOffset = Math.min(batchTargetOffset, Math.max(0, prioritizedTargets.length - 1));
|
|
7771
|
-
const visibleResultTargets = prioritizedTargets.slice(resultTargetOffset, resultTargetOffset + resultTargetLimit);
|
|
7772
|
-
const hiddenResultTargets = Math.max(0, resultTargets.length - resultTargetOffset - visibleResultTargets.length);
|
|
7773
7917
|
const portableSelectedSkills = portableReceipt?.selectedSkills
|
|
7774
7918
|
?? snapshot.portableResultSkills
|
|
7775
7919
|
?? [];
|
|
@@ -7795,10 +7939,12 @@ export function ConsoleAppV4(props) {
|
|
|
7795
7939
|
for (const target of portableReceipt?.unknown ?? []) {
|
|
7796
7940
|
addPortablePair({ skill: target.skill, ...(target.agent ? { agent: target.agent } : {}), state: 'unknown' });
|
|
7797
7941
|
}
|
|
7798
|
-
|
|
7799
|
-
|
|
7800
|
-
|
|
7801
|
-
|
|
7942
|
+
if (!(portableReceipt && 'attemptedTargets' in portableReceipt)) {
|
|
7943
|
+
for (const skill of portableSelectedSkills) {
|
|
7944
|
+
const represented = [...portablePairs.values()].some((pair) => pair.skill === skill);
|
|
7945
|
+
if (!represented)
|
|
7946
|
+
addPortablePair({ skill, state: 'unknown' });
|
|
7947
|
+
}
|
|
7802
7948
|
}
|
|
7803
7949
|
const prioritizedPortablePairs = [...portablePairs.values()].sort((left, right) => {
|
|
7804
7950
|
const priority = { unknown: 0, missing: 1, verified: 2 };
|
|
@@ -7806,29 +7952,157 @@ export function ConsoleAppV4(props) {
|
|
|
7806
7952
|
|| left.skill.localeCompare(right.skill, 'en')
|
|
7807
7953
|
|| (left.agent ?? '').localeCompare(right.agent ?? '', 'en');
|
|
7808
7954
|
});
|
|
7809
|
-
const
|
|
7810
|
-
const
|
|
7955
|
+
const portableSkillLimit = 1;
|
|
7956
|
+
const resultPaginationTotal = result.operationKind === 'portableInstall'
|
|
7957
|
+
? prioritizedPortablePairs.length
|
|
7958
|
+
: baseResultPaginationTotal;
|
|
7959
|
+
const resultPageRows = result.operationKind === 'portableInstall' ? portableSkillLimit : 1;
|
|
7811
7960
|
const portableSkillOffset = Math.min(batchTargetOffset, Math.max(0, prioritizedPortablePairs.length - 1));
|
|
7812
7961
|
const visiblePortablePairs = prioritizedPortablePairs.slice(portableSkillOffset, portableSkillOffset + portableSkillLimit);
|
|
7813
|
-
const
|
|
7962
|
+
const portableResultRange = prioritizedPortablePairs.length > 0
|
|
7963
|
+
? `第 ${portableSkillOffset + 1}–${portableSkillOffset + visiblePortablePairs.length} 项,共 ${prioritizedPortablePairs.length} 项`
|
|
7964
|
+
: undefined;
|
|
7965
|
+
const portablePairStateLabel = (pair) => blocked ? result.writeMayHaveCompleted ? '结果未知' : '未执行'
|
|
7966
|
+
: pair.state === 'unknown' ? '结果未知'
|
|
7967
|
+
: pair.state === 'missing' ? '确认缺失' : '已验证';
|
|
7968
|
+
const selectedPortablePair = portableResultDetailOpen
|
|
7969
|
+
? prioritizedPortablePairs.find((pair) => portablePairKey(pair) === portableResultDetailPairKey.current)
|
|
7970
|
+
: visiblePortablePairs[0];
|
|
7971
|
+
const wrapPortableField = (label, value) => {
|
|
7972
|
+
const chunks = wrapConsoleText(value, Math.max(12, size.columns - stringWidth(label) - 14));
|
|
7973
|
+
return chunks.map((line, index) => `${label} ${index + 1}/${chunks.length} · ${line}`);
|
|
7974
|
+
};
|
|
7975
|
+
const portableResultDetailLines = selectedPortablePair ? [
|
|
7976
|
+
...wrapPortableField('Skill', selectedPortablePair.skill),
|
|
7977
|
+
...wrapPortableField('Agent', selectedPortablePair.agent ?? '无法确认'),
|
|
7978
|
+
`状态 · ${portablePairStateLabel(selectedPortablePair)}`,
|
|
7979
|
+
...(portableResultScope ? [`范围 · ${scopeLabel(portableResultScope)}`] : []),
|
|
7980
|
+
...(portableReceipt?.recovery
|
|
7981
|
+
? wrapPortableField('安全恢复', portableReceipt.recovery) : []),
|
|
7982
|
+
...(portableReceipt?.failureCode
|
|
7983
|
+
? wrapPortableField('failure code', portableReceipt.failureCode) : []),
|
|
7984
|
+
...(portableReceipt ? [`verification missing · ${portableReceipt.missing.length}`] : []),
|
|
7985
|
+
...(portableReceipt ? wrapPortableField('Skills CLI version', portableReceipt.skillsCliVersion) : []),
|
|
7986
|
+
...(portableReceipt
|
|
7987
|
+
? wrapPortableField('materialization digest', portableReceipt.materializationDigest) : []),
|
|
7988
|
+
...(resultSummary?.elapsedMs !== undefined ? [`elapsed · ${resultSummary.elapsedMs} ms`] : []),
|
|
7989
|
+
] : ['当前结果已变化。请返回结果摘要。'];
|
|
7990
|
+
const portableResultDetailPageRows = responsiveBudget(5, 10);
|
|
7991
|
+
const safePortableResultDetailOffset = Math.min(portableResultDetailOffset, Math.max(0, portableResultDetailLines.length - 1));
|
|
7992
|
+
const visiblePortableResultDetailLines = portableResultDetailLines.slice(safePortableResultDetailOffset, safePortableResultDetailOffset + portableResultDetailPageRows);
|
|
7993
|
+
if (portableOperation && portableResultDetailOpen) {
|
|
7994
|
+
title = '当前结果完整字段';
|
|
7995
|
+
description = '按行显示当前 Skill、Agent、状态和技术证据。';
|
|
7996
|
+
help = 'p/n 阅读全部字段 · ↑↓ 移动 · Enter 选择 · Esc 返回结果摘要';
|
|
7997
|
+
const detailPaginationActions = portableResultDetailLines.length > portableResultDetailPageRows
|
|
7998
|
+
? paginationActions({
|
|
7999
|
+
offset: safePortableResultDetailOffset,
|
|
8000
|
+
total: portableResultDetailLines.length,
|
|
8001
|
+
pageRows: portableResultDetailPageRows,
|
|
8002
|
+
move: (direction) => setPortableResultDetailOffset((value) => Math.min(Math.max(0, portableResultDetailLines.length - 1), Math.max(0, value + direction * portableResultDetailPageRows))),
|
|
8003
|
+
})
|
|
8004
|
+
: [];
|
|
8005
|
+
actions = [
|
|
8006
|
+
...detailPaginationActions,
|
|
8007
|
+
{ label: '返回结果摘要', run: () => {
|
|
8008
|
+
setPortableResultDetailOpen(false);
|
|
8009
|
+
setPortableResultDetailOffset(0);
|
|
8010
|
+
setFocus(portableResultDetailReturnFocus.current);
|
|
8011
|
+
setScrollOffset(0);
|
|
8012
|
+
} },
|
|
8013
|
+
];
|
|
8014
|
+
portableResultDetailPagination = {
|
|
8015
|
+
total: portableResultDetailLines.length,
|
|
8016
|
+
pageRows: portableResultDetailPageRows,
|
|
8017
|
+
};
|
|
8018
|
+
}
|
|
8019
|
+
else if (portableOperation) {
|
|
8020
|
+
const detailAction = selectedPortablePair ? {
|
|
8021
|
+
actionId: 'portable-result-full-fields',
|
|
8022
|
+
label: '查看当前结果完整字段',
|
|
8023
|
+
run: () => {
|
|
8024
|
+
portableResultDetailPairKey.current = portablePairKey(selectedPortablePair);
|
|
8025
|
+
portableResultDetailReturnFocus.current = focus;
|
|
8026
|
+
setPortableResultDetailOpen(true);
|
|
8027
|
+
setPortableResultDetailOffset(0);
|
|
8028
|
+
setFocus(0);
|
|
8029
|
+
setScrollOffset(0);
|
|
8030
|
+
},
|
|
8031
|
+
} : undefined;
|
|
8032
|
+
const pagination = resultPaginationTotal > 1 ? paginationActions({
|
|
8033
|
+
offset: batchTargetOffset,
|
|
8034
|
+
total: resultPaginationTotal,
|
|
8035
|
+
pageRows: resultPageRows,
|
|
8036
|
+
move: (direction) => moveBatchTargetPage(resultPaginationTotal, resultPageRows, direction),
|
|
8037
|
+
}) : [];
|
|
8038
|
+
actions = [
|
|
8039
|
+
...actions.slice(0, 1),
|
|
8040
|
+
...pagination,
|
|
8041
|
+
...(detailAction ? [detailAction] : []),
|
|
8042
|
+
...actions.slice(1),
|
|
8043
|
+
];
|
|
8044
|
+
if (pagination.length > 0) {
|
|
8045
|
+
referenceDetailPagination = { total: resultPaginationTotal, pageRows: resultPageRows };
|
|
8046
|
+
}
|
|
8047
|
+
}
|
|
8048
|
+
else if (resultPaginationTotal > 1) {
|
|
8049
|
+
actions.push(...paginationActions({
|
|
8050
|
+
offset: batchTargetOffset,
|
|
8051
|
+
total: resultPaginationTotal,
|
|
8052
|
+
pageRows: resultPageRows,
|
|
8053
|
+
move: (direction) => moveBatchTargetPage(resultPaginationTotal, resultPageRows, direction),
|
|
8054
|
+
}));
|
|
8055
|
+
referenceDetailPagination = { total: resultPaginationTotal, pageRows: resultPageRows };
|
|
8056
|
+
}
|
|
8057
|
+
const portableTechnicalFieldCount = portableReceipt
|
|
8058
|
+
? 3 + (portableReceipt.failureCode ? 1 : 0)
|
|
8059
|
+
+ (policy.mode === 'compact' ? 0 : resultSummary?.elapsedMs !== undefined ? 1 : 0)
|
|
8060
|
+
: 1;
|
|
8061
|
+
const portableFixedRows = showTechnical
|
|
8062
|
+
? 1 + portableSkillLimit + 1
|
|
8063
|
+
+ (portableResultAgentMode === 'automatic' ? 1 : 0)
|
|
8064
|
+
+ (portableReceipt?.recovery ? 1 : 0)
|
|
8065
|
+
+ 1 + portableTechnicalFieldCount
|
|
8066
|
+
: 3 + portableSkillLimit + 1
|
|
8067
|
+
+ (portableResultAgentMode === 'automatic' ? 1 : 0)
|
|
8068
|
+
+ (portableReceipt?.recovery ? 1 : 0);
|
|
8069
|
+
currentActionViewportLineBudget = pageActionBudget(portableOperation
|
|
8070
|
+
? portableResultDetailOpen
|
|
8071
|
+
? visiblePortableResultDetailLines.length
|
|
8072
|
+
+ (safePortableResultDetailOffset > 0 ? 1 : 0)
|
|
8073
|
+
+ (safePortableResultDetailOffset + visiblePortableResultDetailLines.length
|
|
8074
|
+
< portableResultDetailLines.length ? 1 : 0)
|
|
8075
|
+
: portableFixedRows
|
|
8076
|
+
: resultPaginationTotal > 1 ? 7 : 8);
|
|
8077
|
+
const resultActionViewport = actionViewport(actions, true, focus, scrollOffset, currentActionViewportLineBudget);
|
|
8078
|
+
const resultTargetLimit = Math.max(1, prefixRowLimit(prioritizedTargets.map(() => policy.mode === 'compact' ? 1 : 2), pageActionBudget() - 3 - resultActionViewport.limit - resultExtraRows));
|
|
8079
|
+
const resultTargetOffset = Math.min(batchTargetOffset, Math.max(0, prioritizedTargets.length - 1));
|
|
8080
|
+
const visibleResultTargets = prioritizedTargets.slice(resultTargetOffset, resultTargetOffset + resultTargetLimit);
|
|
8081
|
+
const hiddenResultTargets = Math.max(0, resultTargets.length - resultTargetOffset - visibleResultTargets.length);
|
|
8082
|
+
const portableTechnicalSummary = showTechnical;
|
|
7814
8083
|
const portableRows = visiblePortablePairs.map((pair) => {
|
|
7815
8084
|
const status = blocked || pair.state !== 'verified' ? 'warning' : 'success';
|
|
7816
|
-
const stateLabel =
|
|
7817
|
-
|
|
7818
|
-
: pair.state === 'missing' ? '确认缺失'
|
|
7819
|
-
: '已验证';
|
|
7820
|
-
const meta = `Agent:${pair.agent ?? '无法确认'} · ${stateLabel}`;
|
|
8085
|
+
const stateLabel = portablePairStateLabel(pair);
|
|
8086
|
+
const meta = `${stateLabel} · Agent:${pair.agent ?? '无法确认'}`;
|
|
7821
8087
|
return _jsx(ResultRow, { title: pair.skill, meta: meta, status: status, compact: true }, portablePairKey(pair));
|
|
7822
8088
|
});
|
|
7823
|
-
const
|
|
7824
|
-
|
|
7825
|
-
|
|
7826
|
-
|
|
7827
|
-
|
|
7828
|
-
|
|
7829
|
-
|
|
7830
|
-
|
|
7831
|
-
|
|
8089
|
+
const portableTechnicalRows = portableReceipt
|
|
8090
|
+
? [
|
|
8091
|
+
...(portableReceipt.failureCode
|
|
8092
|
+
? [_jsx(StaticRow, { title: "failure code", meta: portableReceipt.failureCode, compact: true }, "failure-code")]
|
|
8093
|
+
: []),
|
|
8094
|
+
_jsx(StaticRow, { title: "verification missing", meta: policy.mode === 'compact' && resultSummary?.elapsedMs !== undefined
|
|
8095
|
+
? `${portableReceipt.missing.length} · elapsed ${resultSummary.elapsedMs} ms`
|
|
8096
|
+
: String(portableReceipt.missing.length), compact: true }, "verification-missing"),
|
|
8097
|
+
_jsx(StaticRow, { title: "Skills CLI version", meta: portableReceipt.skillsCliVersion, compact: true }, "skills-cli-version"),
|
|
8098
|
+
_jsx(StaticRow, { title: "materialization digest", meta: portableReceipt.materializationDigest, compact: true }, "materialization-digest"),
|
|
8099
|
+
...(policy.mode !== 'compact' && resultSummary?.elapsedMs !== undefined
|
|
8100
|
+
? [_jsx(StaticRow, { title: "elapsed", meta: `${resultSummary.elapsedMs} ms`, compact: true }, "elapsed")]
|
|
8101
|
+
: []),
|
|
8102
|
+
]
|
|
8103
|
+
: [
|
|
8104
|
+
_jsx(StaticRow, { title: "failure code", meta: 'code' in result ? result.code : 'operationFailed', compact: true }, "failure-code"),
|
|
8105
|
+
];
|
|
7832
8106
|
const resetDispositionText = resultSummary?.resetDisposition === 'absent'
|
|
7833
8107
|
? '设置层原本不存在;没有删除内容'
|
|
7834
8108
|
: resultSummary?.resetDisposition === 'deletedFile'
|
|
@@ -7908,14 +8182,19 @@ export function ConsoleAppV4(props) {
|
|
|
7908
8182
|
const visibleTaskResultRows = rootResultRows.slice(taskResultOffset, taskResultOffset + taskResultLimit);
|
|
7909
8183
|
if (taskOperation || batchOperation || resultTargets.length > resultTargetLimit
|
|
7910
8184
|
|| prioritizedPortablePairs.length > portableSkillLimit) {
|
|
7911
|
-
help = '
|
|
8185
|
+
help = 'p/n 查看全部项目 · ↑↓ 移动 · Enter 选择 · Esc 返回';
|
|
7912
8186
|
}
|
|
7913
8187
|
content = taskOperation || batchOperation ? _jsxs(Box, { flexDirection: "column", children: [_jsxs(ResultCard, { status: resultStatus, title: "\u6240\u9009\u63D2\u4EF6\u7ED3\u679C", children: [taskResultOffset > 0 ? _jsx(StaticRow, { title: `↑ 前面还有 ${taskResultOffset} 项`, status: "muted", compact: true }) : null, visibleTaskResultRows, rootResultRows.length > taskResultOffset + visibleTaskResultRows.length
|
|
7914
|
-
? _jsx(StaticRow, { title: "\u2193 \u540E\u9762\u8FD8\u6709", meta: `${rootResultRows.length - taskResultOffset - visibleTaskResultRows.length} 项`, status: "muted", compact: true }) : null] }), _jsx(SemanticRows, { actions: actions, focus: focus, kind: "action", compact: true, offset: resultActionViewport.offset, limit: resultActionViewport.limit })] }) : portableOperation ? _jsxs(Box, { flexDirection: "column", children: [
|
|
7915
|
-
|
|
7916
|
-
|
|
7917
|
-
|
|
7918
|
-
|
|
8188
|
+
? _jsx(StaticRow, { title: "\u2193 \u540E\u9762\u8FD8\u6709", meta: `${rootResultRows.length - taskResultOffset - visibleTaskResultRows.length} 项`, status: "muted", compact: true }) : null] }), _jsx(SemanticRows, { actions: actions, focus: focus, kind: "action", compact: true, offset: resultActionViewport.offset, limit: resultActionViewport.limit })] }) : portableOperation ? _jsxs(Box, { flexDirection: "column", children: [portableResultDetailOpen ? _jsxs(_Fragment, { children: [safePortableResultDetailOffset > 0
|
|
8189
|
+
? _jsx(StaticRow, { title: `↑ 前面还有 ${safePortableResultDetailOffset} 行`, status: "muted", compact: true }) : null, visiblePortableResultDetailLines.map((line, index) => _jsx(StaticRow, { title: line, compact: true }, `${safePortableResultDetailOffset + index}:${line}`)), safePortableResultDetailOffset + visiblePortableResultDetailLines.length
|
|
8190
|
+
< portableResultDetailLines.length
|
|
8191
|
+
? _jsx(StaticRow, { title: `↓ 后面还有 ${portableResultDetailLines.length
|
|
8192
|
+
- safePortableResultDetailOffset - visiblePortableResultDetailLines.length} 行`, status: "muted", compact: true })
|
|
8193
|
+
: null] }) : portableTechnicalSummary ? _jsxs(_Fragment, { children: [_jsx(StaticRow, { title: blocked ? '安装未开始或结果未确认' : partial ? '部分 Skills 未确认' : '通用 Skills 安装结果', meta: portableResultRange, status: resultStatus, compact: true }), portableRows, portableResultScope ? _jsx(StaticRow, { title: "\u8303\u56F4", meta: scopeLabel(portableResultScope), compact: true }) : null, portableResultAgentMode === 'automatic'
|
|
8194
|
+
? _jsx(StaticRow, { title: "Agent", meta: "Skills CLI \u9ED8\u8BA4\u9009\u62E9", compact: true }) : null, portableReceipt?.recovery ? _jsx(StaticRow, { title: `安全恢复:${portableReceipt.recovery}`, status: "warning", compact: true }) : null, _jsx(StaticRow, { title: "\u6280\u672F\u8BE6\u60C5", status: "muted", compact: true }), portableTechnicalRows] }) : _jsx(_Fragment, { children: _jsxs(ResultCard, { status: resultStatus, title: blocked ? '安装未开始或结果未确认' : partial ? '部分 Skills 未确认' : '通用 Skills 安装结果', meta: portableResultRange, children: [portableRows, portableResultScope ? _jsx(StaticRow, { title: "\u8303\u56F4", meta: scopeLabel(portableResultScope), compact: true }) : null, portableResultAgentMode === 'automatic'
|
|
8195
|
+
? _jsx(StaticRow, { title: "Agent", meta: "Skills CLI \u9ED8\u8BA4\u9009\u62E9", compact: true }) : null, portableReceipt?.recovery
|
|
8196
|
+
? _jsx(StaticRow, { title: `安全恢复:${portableReceipt.recovery}`, status: "warning", compact: true })
|
|
8197
|
+
: null] }) }), _jsx(SemanticRows, { actions: actions, focus: focus, kind: "action", compact: true, offset: resultActionViewport.offset, limit: resultActionViewport.limit })] }) : _jsxs(Box, { flexDirection: "column", children: [_jsxs(ResultCard, { status: resultStatus, title: blockedDependencyFailure ? '依赖安装没有完成' : blocked ? result.writeMayHaveCompleted ? '结果未确认' : '操作未完成' : sourceOperation ? '来源配置写入已完成' : dependencyTargets ? partial ? '依赖安装没有全部完成' : '操作已完成' : resultSummary?.message ?? '状态已变化,请重新确认', meta: resultTargets.length > 0 ? `${resultTargets.length} 个目标` : undefined, children: [resetDispositionText ? _jsx(StaticRow, { title: resetDispositionText, status: "success", compact: true }) : null, configGroupRows, resultTargetOffset > 0 ? _jsx(StaticRow, { title: `↑ 前面还有 ${resultTargetOffset} 个目标`, status: "muted", compact: true }) : null, visibleResultTargets.map((target) => { const state = operationTargetStateLabel(target.state); const relation = target.relation === 'requested' ? '你选择的插件' : target.relation === 'direct' ? '直接依赖' : target.relation === 'transitive' ? '间接依赖' : undefined; return _jsx(ResultRow, { title: resultTargetName(target), description: relation, meta: state.label, status: state.status ?? 'muted', compact: policy.mode === 'compact' }, `${target.pluginId ?? ''}:${target.platform}:${target.scope}`); }), hiddenResultTargets > 0 ? _jsx(StaticRow, { title: "\u2193 \u540E\u9762\u8FD8\u6709", meta: `${hiddenResultTargets} 个目标`, status: "muted", compact: true }) : null, partial && hasPreservedTarget && resultTargets.some((target) => target.state === 'skipped') ? _jsx(StaticRow, { title: "\u672A\u6267\u884C\u7684\u76EE\u6807\u6CA1\u6709\u5199\u5165\uFF1B\u5DF2\u5B8C\u6210\u6216\u5DF2\u4FDD\u7559\u7684\u76EE\u6807\u4FDD\u6301\u53EF\u7528\u3002", status: "muted", compact: true }) : null, configOperation && partial && !invalidConfigResult ? _jsx(Callout, { status: "warning", title: "\u6062\u590D\u6307\u5F15", description: "\u5DF2\u4FDD\u5B58\u7684\u8BBE\u7F6E\u5C42\u4E0D\u4F1A\u91CD\u5199\u3002\u5931\u8D25\u7684\u4FDD\u5B58\u5C42\u4FDD\u7559\u8349\u7A3F\uFF1B\u5E94\u7528\u5931\u8D25\u65F6\u53EA\u91CD\u8BD5\u5E94\u7528\u3002" }) : null, resultSummary?.elapsedMs !== undefined ? _jsx(StaticRow, { title: "\u5DF2\u7528\u65F6", meta: `${Math.floor(resultSummary.elapsedMs / 1_000)}s` }) : null, visibleMessages.map((message, index) => _jsx(StaticRow, { title: productResultMessage(message), status: "muted", compact: true }, `${index}:${message}`))] }), _jsx(SemanticRows, { actions: actions, focus: focus, kind: "action", compact: true, offset: resultActionViewport.offset, limit: resultActionViewport.limit })] });
|
|
7919
8198
|
}
|
|
7920
8199
|
else if (route.name === 'pluginContent' && plugin) {
|
|
7921
8200
|
const overview = props.controller.getPluginContentOverview(plugin.pluginId);
|
|
@@ -7994,15 +8273,22 @@ export function ConsoleAppV4(props) {
|
|
|
7994
8273
|
});
|
|
7995
8274
|
const detailRowBudget = responsiveBudget(9, 15);
|
|
7996
8275
|
const capabilityRowCount = plugin.capabilityUnsupported ? 4 : 0;
|
|
7997
|
-
const componentRowBudget = Math.max(1, detailRowBudget -
|
|
8276
|
+
const componentRowBudget = Math.max(1, detailRowBudget - 4 - plugin.installedPlacements.length - capabilityRowCount);
|
|
7998
8277
|
const componentLimit = prioritizedComponents.length > componentRowBudget
|
|
7999
|
-
?
|
|
8278
|
+
? 1
|
|
8000
8279
|
: componentRowBudget;
|
|
8001
8280
|
const componentOffset = Math.min(batchTargetOffset, Math.max(0, prioritizedComponents.length - 1));
|
|
8002
8281
|
const visibleComponents = prioritizedComponents.slice(componentOffset, componentOffset + componentLimit);
|
|
8003
8282
|
const hiddenComponents = Math.max(0, prioritizedComponents.length - componentOffset - visibleComponents.length);
|
|
8004
8283
|
if (prioritizedComponents.length > componentLimit) {
|
|
8005
|
-
|
|
8284
|
+
actions.push(...paginationActions({
|
|
8285
|
+
offset: componentOffset,
|
|
8286
|
+
total: prioritizedComponents.length,
|
|
8287
|
+
pageRows: componentLimit,
|
|
8288
|
+
move: (direction) => moveBatchTargetPage(prioritizedComponents.length, componentLimit, direction),
|
|
8289
|
+
}));
|
|
8290
|
+
referenceDetailPagination = { total: prioritizedComponents.length, pageRows: componentLimit };
|
|
8291
|
+
help = 'p/n 查看全部组件 · ↑↓ 移动 · Enter 选择 · Esc 返回';
|
|
8006
8292
|
}
|
|
8007
8293
|
content = _jsxs(Box, { flexDirection: "column", children: [_jsxs(TechnicalDetails, { children: [_jsx(StaticRow, { title: "canonical pluginId", meta: plugin.pluginId }), _jsx(StaticRow, { title: "\u6765\u6E90", meta: plugin.sourceId }), plugin.capabilityUnsupported ? _jsxs(_Fragment, { children: [_jsx(StaticRow, { title: "failure code", meta: "awCapabilityUnsupported" }), _jsx(StaticRow, { title: "capability \u72B6\u6001", meta: "\u5F53\u524D AW CLI \u4E0D\u652F\u6301", status: "error" }), _jsx(StaticRow, { title: "\u7F3A\u5C11 capability", meta: plugin.missingCapabilities?.join('、') ?? 'Status 未提供具体 capability' }), _jsx(StaticRow, { title: "\u6062\u590D\u65B9\u5411", meta: plugin.capabilityRecovery ?? '升级 AW CLI 到支持所需 capability 的版本后重试。' })] }) : null, plugin.installedPlacements.map((placement) => _jsx(StaticRow, { title: `${platformLabel(placement.platform)} target`, meta: placementStatus(placement).value }, placement.platform)), componentOffset > 0 ? _jsx(StaticRow, { title: `↑ 前面还有 ${componentOffset} 个组件`, status: "muted", compact: true }) : null, visibleComponents.map((component) => _jsx(StaticRow, { title: `组件 · ${component.state === 'absent' ? '缺失' : component.state}${component.errorCode ? ` · ${component.errorCode}` : ''} · ${component.key} · ${platformLabel(component.platform)} · ${component.shared ? '平台共享' : scopeLabel(component.scope)}` }, `${component.platform}:${component.shared ? 'shared' : component.scope}:${component.key}`)), hiddenComponents > 0 ? _jsx(StaticRow, { title: `↓ 后面还有 ${hiddenComponents} 个组件`, status: "muted", compact: true }) : null] }), _jsx(SemanticRows, { actions: actions, focus: focus, kind: "action", compact: policy.mode === 'compact' })] });
|
|
8008
8294
|
}
|
|
@@ -8286,9 +8572,13 @@ export function ConsoleAppV4(props) {
|
|
|
8286
8572
|
if (key.escape || key.return || input.toLowerCase() === 'b' || input === '?') {
|
|
8287
8573
|
setOverlay(undefined);
|
|
8288
8574
|
}
|
|
8289
|
-
else if (key.ctrl && input.toLowerCase() === 'c') {
|
|
8575
|
+
else if (input.toLowerCase() === 'q' || (key.ctrl && input.toLowerCase() === 'c')) {
|
|
8290
8576
|
setExitAfterBusy(true);
|
|
8291
8577
|
}
|
|
8578
|
+
else if (sessionNavigation) {
|
|
8579
|
+
setOverlay(undefined);
|
|
8580
|
+
requestSessionNavigation(sessionNavigation);
|
|
8581
|
+
}
|
|
8292
8582
|
}
|
|
8293
8583
|
else if (key.escape && props.pendingSessionNavigation) {
|
|
8294
8584
|
props.onCancelPendingSessionNavigation?.();
|
|
@@ -8324,6 +8614,9 @@ export function ConsoleAppV4(props) {
|
|
|
8324
8614
|
if (key.escape || input.toLowerCase() === 'b') {
|
|
8325
8615
|
closeProjectReminder();
|
|
8326
8616
|
}
|
|
8617
|
+
else if (input.toLowerCase() === 'q' || (key.ctrl && input.toLowerCase() === 'c')) {
|
|
8618
|
+
requestConfirmedExit(closeProjectReminder);
|
|
8619
|
+
}
|
|
8327
8620
|
else if (props.onSessionNavigation && (input === 'h' || input === 'H')) {
|
|
8328
8621
|
closeProjectReminder();
|
|
8329
8622
|
requestSessionNavigation(input === 'H' ? 'reload' : 'home');
|
|
@@ -8446,7 +8739,7 @@ export function ConsoleAppV4(props) {
|
|
|
8446
8739
|
return;
|
|
8447
8740
|
}
|
|
8448
8741
|
if (overlay) {
|
|
8449
|
-
if (key.ctrl && input.toLowerCase() === 'c') {
|
|
8742
|
+
if (input.toLowerCase() === 'q' || (key.ctrl && input.toLowerCase() === 'c')) {
|
|
8450
8743
|
if (overlay === 'sessionNavigation')
|
|
8451
8744
|
continueEditingFromSessionNavigation();
|
|
8452
8745
|
setDiscardForSessionNavigation(undefined);
|
|
@@ -8454,6 +8747,11 @@ export function ConsoleAppV4(props) {
|
|
|
8454
8747
|
requestConfirmedExit(overlay === 'help' ? () => setOverlay(undefined) : undefined);
|
|
8455
8748
|
return;
|
|
8456
8749
|
}
|
|
8750
|
+
if (overlay === 'help' && props.onSessionNavigation && (input === 'h' || input === 'H')) {
|
|
8751
|
+
setOverlay(undefined);
|
|
8752
|
+
requestSessionNavigation(input === 'H' ? 'reload' : 'home');
|
|
8753
|
+
return;
|
|
8754
|
+
}
|
|
8457
8755
|
if (overlay === 'help' && input.toLowerCase() === 'o') {
|
|
8458
8756
|
setOverlay(undefined);
|
|
8459
8757
|
go({ name: 'operationHistory' });
|
|
@@ -8558,8 +8856,20 @@ export function ConsoleAppV4(props) {
|
|
|
8558
8856
|
setReportSaveError(undefined);
|
|
8559
8857
|
return;
|
|
8560
8858
|
}
|
|
8859
|
+
if ((key.pageUp || key.pageDown || input.toLowerCase() === 'p' || input.toLowerCase() === 'n')
|
|
8860
|
+
&& route.name === 'result' && portableResultDetailOpen
|
|
8861
|
+
&& portableResultDetailPagination) {
|
|
8862
|
+
const { total, pageRows } = portableResultDetailPagination;
|
|
8863
|
+
const direction = key.pageUp || input.toLowerCase() === 'p' ? -1 : 1;
|
|
8864
|
+
setPortableResultDetailOffset((value) => Math.min(Math.max(0, total - 1), Math.max(0, value + direction * pageRows)));
|
|
8865
|
+
return;
|
|
8866
|
+
}
|
|
8561
8867
|
if ((key.pageUp || key.pageDown || input.toLowerCase() === 'p' || input.toLowerCase() === 'n')
|
|
8562
8868
|
&& (route.name === 'pluginContent'
|
|
8869
|
+
|| route.name === 'pluginTechnical'
|
|
8870
|
+
|| route.name === 'issueDetail' && showTechnical
|
|
8871
|
+
|| route.name === 'sourceRemoveBlocked' && sourceDependenciesExpanded
|
|
8872
|
+
|| route.name === 'pluginDependencies' && route.view === 'removeBlocked' && !showTechnical
|
|
8563
8873
|
|| route.name === 'pluginDependencyNode'
|
|
8564
8874
|
&& (route.view === 'references' || route.view === 'details')
|
|
8565
8875
|
|| route.name === 'configSave' && route.view === 'changes'
|
|
@@ -8593,11 +8903,9 @@ export function ConsoleAppV4(props) {
|
|
|
8593
8903
|
}
|
|
8594
8904
|
if ((key.pageUp || key.pageDown || input.toLowerCase() === 'p' || input.toLowerCase() === 'n')
|
|
8595
8905
|
&& route.name === 'sourceTechnical') {
|
|
8596
|
-
const
|
|
8597
|
-
|
|
8598
|
-
|
|
8599
|
-
const pageRows = responsiveBudget(5, 10);
|
|
8600
|
-
setBatchTargetOffset((value) => Math.min(Math.max(0, total - pageRows), Math.max(0, value + (key.pageUp || input.toLowerCase() === 'p' ? -pageRows : pageRows))));
|
|
8906
|
+
const total = diagnosticDetailRowCount(resolveSourceTechnicalDiagnostic(route.sourceId));
|
|
8907
|
+
setBatchTargetOffset((value) => Math.min(Math.max(0, total - sourceTechnicalPageRows), Math.max(0, value + (key.pageUp || input.toLowerCase() === 'p'
|
|
8908
|
+
? -sourceTechnicalPageRows : sourceTechnicalPageRows))));
|
|
8601
8909
|
return;
|
|
8602
8910
|
}
|
|
8603
8911
|
if ((key.pageUp || key.pageDown) && route.name === 'sourceRemoveBlocked'
|
|
@@ -8964,7 +9272,8 @@ export function ConsoleAppV4(props) {
|
|
|
8964
9272
|
}
|
|
8965
9273
|
if ((route.name === 'pluginList' || route.name === 'sourceList'
|
|
8966
9274
|
|| route.name === 'batchInstallPlatforms' || route.name === 'batchInstallScope'
|
|
8967
|
-
|| route.name === 'batchPlacement' && pinnedActions.length > 0
|
|
9275
|
+
|| route.name === 'batchPlacement' && pinnedActions.length > 0
|
|
9276
|
+
|| route.name === 'portableSkillSelect') && key.tab) {
|
|
8968
9277
|
setFocusZone((current) => current === 'content' ? 'actions' : 'content');
|
|
8969
9278
|
return;
|
|
8970
9279
|
}
|
|
@@ -9000,6 +9309,15 @@ export function ConsoleAppV4(props) {
|
|
|
9000
9309
|
runAction(pinnedActions[pinnedActionFocus]);
|
|
9001
9310
|
return;
|
|
9002
9311
|
}
|
|
9312
|
+
if (route.name === 'portableSkillSelect' && focusZone === 'actions'
|
|
9313
|
+
&& (key.upArrow || key.downArrow || key.leftArrow || key.rightArrow)) {
|
|
9314
|
+
setPinnedActionFocus((value) => moveFocus(pinnedActions, value, key.upArrow || key.leftArrow ? -1 : 1));
|
|
9315
|
+
return;
|
|
9316
|
+
}
|
|
9317
|
+
if (route.name === 'portableSkillSelect' && focusZone === 'actions' && key.return) {
|
|
9318
|
+
runAction(pinnedActions[pinnedActionFocus]);
|
|
9319
|
+
return;
|
|
9320
|
+
}
|
|
9003
9321
|
if ((route.name === 'batchInstallPlatforms' || route.name === 'batchInstallScope'
|
|
9004
9322
|
|| route.name === 'batchPlacement' && pinnedActions.length > 0)
|
|
9005
9323
|
&& focusZone === 'actions'
|
|
@@ -9083,6 +9401,17 @@ export function ConsoleAppV4(props) {
|
|
|
9083
9401
|
else if (input.toLowerCase() === 'd' && supportsTechnicalDetails) {
|
|
9084
9402
|
toggleTechnical();
|
|
9085
9403
|
}
|
|
9404
|
+
else if (globalAction === 'back' && route.name === 'result' && portableResultDetailOpen) {
|
|
9405
|
+
setPortableResultDetailOpen(false);
|
|
9406
|
+
setPortableResultDetailOffset(0);
|
|
9407
|
+
setFocus(portableResultDetailReturnFocus.current);
|
|
9408
|
+
setScrollOffset(0);
|
|
9409
|
+
}
|
|
9410
|
+
else if (globalAction === 'back' && route.name === 'portableSkillSelect' && portableToolsOpen) {
|
|
9411
|
+
setPortableToolsOpen(false);
|
|
9412
|
+
setFocus(0);
|
|
9413
|
+
setScrollOffset(0);
|
|
9414
|
+
}
|
|
9086
9415
|
else if (globalAction === 'back'
|
|
9087
9416
|
&& (route.name === 'configSave' || route.name === 'sourceSave')
|
|
9088
9417
|
&& route.view === 'changes') {
|
|
@@ -9249,18 +9578,19 @@ export function ConsoleAppV4(props) {
|
|
|
9249
9578
|
movePluginListSource?.(direction);
|
|
9250
9579
|
}
|
|
9251
9580
|
else if (input.toLowerCase() === 'c' && route.name === 'portableSkillSelect') {
|
|
9252
|
-
runAction(
|
|
9581
|
+
runAction(pinnedActions.find((action) => action.actionId === 'portable-selection-continue'));
|
|
9253
9582
|
}
|
|
9254
9583
|
else if (input.toLowerCase() === 'a' && route.name === 'portableSkillSelect') {
|
|
9255
|
-
|
|
9584
|
+
runAction(selectAllPortableCandidates);
|
|
9256
9585
|
}
|
|
9257
|
-
else if (input === ' ' && route.name === 'portableSkillSelect'
|
|
9586
|
+
else if (input === ' ' && route.name === 'portableSkillSelect'
|
|
9587
|
+
&& focusZone === 'content' && !portableToolsOpen) {
|
|
9258
9588
|
const candidate = portableVisibleCandidates[focus];
|
|
9259
9589
|
if (candidate)
|
|
9260
9590
|
props.controller.togglePortableSkill(candidate.name);
|
|
9261
9591
|
}
|
|
9262
9592
|
else if (key.upArrow || input.toLowerCase() === 'k') {
|
|
9263
|
-
if (route.name === 'pluginDependencyNode' && route.view === 'references') {
|
|
9593
|
+
if (route.name === 'pluginDependencyNode' && route.view === 'references' && !showTechnical) {
|
|
9264
9594
|
setBatchTargetOffset(0);
|
|
9265
9595
|
}
|
|
9266
9596
|
setFocus((value) => {
|
|
@@ -9276,10 +9606,10 @@ export function ConsoleAppV4(props) {
|
|
|
9276
9606
|
}
|
|
9277
9607
|
const viewport = route.name === 'batchSelection' && batchDraft?.stage === 'select'
|
|
9278
9608
|
? actionViewport(actions.slice(1), policy.mode === 'compact', Math.max(0, next - 1), Math.max(0, scrollOffset - 1), Math.max(1, pageActionBudget(5)))
|
|
9279
|
-
: route.name === 'portableSkillSelect' && snapshot.portableDraft
|
|
9609
|
+
: route.name === 'portableSkillSelect' && snapshot.portableDraft && !portableToolsOpen
|
|
9280
9610
|
? portableSkillCandidateViewport(actions.slice(0, portableVisibleCandidates.length), portableVisibleCandidates, policy.mode === 'compact', next, scrollOffset, pageActionBudget(actions.length - portableVisibleCandidates.length
|
|
9281
9611
|
+ (portableVariantCandidates.length > 0 ? 3 : 0)))
|
|
9282
|
-
: actionViewport(actions, route.name === 'pluginDetail' || policy.mode === 'compact', next, scrollOffset,
|
|
9612
|
+
: actionViewport(actions, route.name === 'pluginDetail' || policy.mode === 'compact', next, scrollOffset, currentActionViewportLineBudget);
|
|
9283
9613
|
if (route.name === 'pluginDependencies' && route.view !== 'removeBlocked') {
|
|
9284
9614
|
const projection = buildUnifiedDependencyGraphProjection({
|
|
9285
9615
|
overviews: props.controller.listPluginDependencyOverviews(),
|
|
@@ -9298,7 +9628,7 @@ export function ConsoleAppV4(props) {
|
|
|
9298
9628
|
});
|
|
9299
9629
|
}
|
|
9300
9630
|
else if (key.downArrow || input.toLowerCase() === 'j') {
|
|
9301
|
-
if (route.name === 'pluginDependencyNode' && route.view === 'references') {
|
|
9631
|
+
if (route.name === 'pluginDependencyNode' && route.view === 'references' && !showTechnical) {
|
|
9302
9632
|
setBatchTargetOffset(0);
|
|
9303
9633
|
}
|
|
9304
9634
|
setFocus((value) => {
|
|
@@ -9314,10 +9644,10 @@ export function ConsoleAppV4(props) {
|
|
|
9314
9644
|
}
|
|
9315
9645
|
const viewport = route.name === 'batchSelection' && batchDraft?.stage === 'select'
|
|
9316
9646
|
? actionViewport(actions.slice(1), policy.mode === 'compact', Math.max(0, next - 1), Math.max(0, scrollOffset - 1), Math.max(1, pageActionBudget(5)))
|
|
9317
|
-
: route.name === 'portableSkillSelect' && snapshot.portableDraft
|
|
9647
|
+
: route.name === 'portableSkillSelect' && snapshot.portableDraft && !portableToolsOpen
|
|
9318
9648
|
? portableSkillCandidateViewport(actions.slice(0, portableVisibleCandidates.length), portableVisibleCandidates, policy.mode === 'compact', next, scrollOffset, pageActionBudget(actions.length - portableVisibleCandidates.length
|
|
9319
9649
|
+ (portableVariantCandidates.length > 0 ? 3 : 0)))
|
|
9320
|
-
: actionViewport(actions, route.name === 'pluginDetail' || policy.mode === 'compact', next, scrollOffset,
|
|
9650
|
+
: actionViewport(actions, route.name === 'pluginDetail' || policy.mode === 'compact', next, scrollOffset, currentActionViewportLineBudget);
|
|
9321
9651
|
if (route.name === 'pluginDependencies' && route.view !== 'removeBlocked') {
|
|
9322
9652
|
const projection = buildUnifiedDependencyGraphProjection({
|
|
9323
9653
|
overviews: props.controller.listPluginDependencyOverviews(),
|