@pi-harness/pi-harness 0.1.7 → 0.1.8
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/apps/web/dist/assets/index-CCZGqUaU.css +2 -0
- package/apps/web/dist/assets/index-DZjjpslQ.js +20 -0
- package/apps/web/dist/index.html +2 -2
- package/apps/web/package.json +6 -6
- package/apps/web/src/style.css +148 -41
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/agent-teams.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/anchored-standard.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/annotation.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/archify.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/at-file.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/auto-mode.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/better-sidebar.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/browser-fetch.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/browser-session.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/canvas-draw.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/change-verifier.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/cleaner.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/cli-notifier.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/code2skill.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/colleague-skill.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/context-doctor.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/context.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/cost-meter.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/dependency-checker.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/docker-sandbox.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/fail-logger.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/genui.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/git-time-capsule.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/graph-memory.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/history-compressor.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/hol-guard.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/i18n-pair.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/image-compressor.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/llm-verifier.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/mcp-client.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/mcp-panel.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/memory.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/mirage-bridge.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/mock-server.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/modlens.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/module-search.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/obsidian-sync.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/openpets.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/plan-execute.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/plugin-check.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/plugin-dev.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/plugin-finder.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/plugin-radar.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/plugin-stars.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/prompt-guard.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/prompt-library.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/readme-gen.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/recall-unread.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/reverse-skill.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/reviewer-bot.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/runtime-doctor.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/secure-audit.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/session-bookmarks.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/session-bridge.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/session-compare.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/session-export.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/session-insights.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/session-search.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/skill-catalog.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/skill-guard.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/sql-lens.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/synapse.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/tab-manager.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/taskboard.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/telemetry-blocker.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/test-harness.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/theme-studio.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/token-guard.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/turn-rewind.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/undo-savepoint.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/vision-toolkit.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/web-research.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/workspace-navigator.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/workspace-search.json +1 -1
- package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/yaml-validator.json +1 -1
- package/node_modules/@pi-harness/api-gateway/package.json +1 -1
- package/node_modules/@pi-harness/cli/package.json +1 -1
- package/node_modules/@pi-harness/core/package.json +1 -1
- package/node_modules/@pi-harness/host-webserver/package.json +1 -1
- package/node_modules/@pi-harness/web-app/package.json +1 -1
- package/package.json +6 -6
- package/packages/api-gateway/dist/marketplace-entries/official/agent-teams.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/anchored-standard.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/annotation.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/archify.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/at-file.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/auto-mode.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/better-sidebar.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/browser-fetch.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/browser-session.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/canvas-draw.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/change-verifier.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/cleaner.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/cli-notifier.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/code2skill.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/colleague-skill.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/context-doctor.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/context.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/cost-meter.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/dependency-checker.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/docker-sandbox.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/fail-logger.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/genui.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/git-time-capsule.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/graph-memory.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/history-compressor.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/hol-guard.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/i18n-pair.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/image-compressor.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/llm-verifier.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/mcp-client.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/mcp-panel.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/memory.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/mirage-bridge.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/mock-server.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/modlens.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/module-search.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/obsidian-sync.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/openpets.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/plan-execute.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/plugin-check.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/plugin-dev.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/plugin-finder.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/plugin-radar.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/plugin-stars.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/prompt-guard.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/prompt-library.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/readme-gen.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/recall-unread.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/reverse-skill.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/reviewer-bot.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/runtime-doctor.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/secure-audit.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/session-bookmarks.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/session-bridge.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/session-compare.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/session-export.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/session-insights.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/session-search.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/skill-catalog.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/skill-guard.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/sql-lens.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/synapse.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/tab-manager.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/taskboard.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/telemetry-blocker.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/test-harness.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/theme-studio.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/token-guard.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/turn-rewind.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/undo-savepoint.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/vision-toolkit.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/web-research.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/workspace-navigator.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/workspace-search.json +1 -1
- package/packages/api-gateway/dist/marketplace-entries/official/yaml-validator.json +1 -1
- package/packages/api-gateway/package.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/agent-teams.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/anchored-standard.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/annotation.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/archify.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/at-file.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/auto-mode.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/better-sidebar.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/browser-fetch.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/browser-session.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/canvas-draw.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/change-verifier.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/cleaner.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/cli-notifier.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/code2skill.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/colleague-skill.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/context-doctor.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/context.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/cost-meter.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/dependency-checker.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/docker-sandbox.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/fail-logger.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/genui.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/git-time-capsule.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/graph-memory.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/history-compressor.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/hol-guard.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/i18n-pair.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/image-compressor.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/llm-verifier.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/mcp-client.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/mcp-panel.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/memory.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/mirage-bridge.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/mock-server.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/modlens.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/module-search.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/obsidian-sync.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/openpets.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/plan-execute.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/plugin-check.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/plugin-dev.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/plugin-finder.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/plugin-radar.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/plugin-stars.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/prompt-guard.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/prompt-library.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/readme-gen.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/recall-unread.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/reverse-skill.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/reviewer-bot.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/runtime-doctor.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/secure-audit.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/session-bookmarks.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/session-bridge.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/session-compare.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/session-export.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/session-insights.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/session-search.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/skill-catalog.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/skill-guard.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/sql-lens.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/synapse.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/tab-manager.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/taskboard.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/telemetry-blocker.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/test-harness.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/theme-studio.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/token-guard.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/turn-rewind.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/undo-savepoint.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/vision-toolkit.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/web-research.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/workspace-navigator.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/workspace-search.json +1 -1
- package/packages/api-gateway/src/marketplace-entries/official/yaml-validator.json +1 -1
- package/packages/bundle-web-app/package.json +1 -1
- package/packages/cli/package.json +1 -1
- package/packages/client-web/dist/react-room.d.ts.map +1 -1
- package/packages/client-web/dist/react-room.js +128 -38
- package/packages/client-web/dist/react-room.js.map +1 -1
- package/packages/client-web/package.json +1 -1
- package/packages/client-web/src/react-room.tsx +220 -73
- package/packages/core/package.json +1 -1
- package/packages/host-webserver/package.json +1 -1
- package/apps/web/dist/assets/index-CkGv0zrr.css +0 -2
- package/apps/web/dist/assets/index-pMtwuwHh.js +0 -20
|
@@ -26,7 +26,7 @@ import { loadMarketplaceCatalog } from "./marketplace-catalog.js";
|
|
|
26
26
|
import { pluginStarsRows } from "./plugin-stars-view.js";
|
|
27
27
|
import { browserSessionTabs } from "./browser-session-view.js";
|
|
28
28
|
import { matchesPluginQuery } from "./plugin-search.js";
|
|
29
|
-
import {
|
|
29
|
+
import { readInstalledPluginDetailId } from "./plugin-navigation.js";
|
|
30
30
|
import { installedPluginCardContent } from "./plugin-card.js";
|
|
31
31
|
|
|
32
32
|
export type { ClientApi } from "./control-room.js";
|
|
@@ -741,12 +741,12 @@ function Details({ event, onClose, onCopy }: { event: Record<string, unknown> |
|
|
|
741
741
|
<aside className="details-panel">
|
|
742
742
|
<header>
|
|
743
743
|
<strong>{eventLabel(event)}</strong>
|
|
744
|
-
<button aria-label="关闭事件详情" onClick={onClose} type="button">
|
|
744
|
+
<button aria-label={fileDetail ? "关闭文件差异" : "关闭事件详情"} onClick={onClose} type="button">
|
|
745
745
|
×
|
|
746
746
|
</button>
|
|
747
747
|
</header>
|
|
748
748
|
<div className="details-body">
|
|
749
|
-
<div className=
|
|
749
|
+
<div className={`detail-stats ${fileDetail ? "is-file" : ""}`}>
|
|
750
750
|
{stats.map(([key, item]) => (
|
|
751
751
|
<div key={key}>
|
|
752
752
|
<small>{key}</small>
|
|
@@ -845,11 +845,22 @@ function Trajectory({ events, onSelect }: { events: readonly Record<string, unkn
|
|
|
845
845
|
);
|
|
846
846
|
}
|
|
847
847
|
|
|
848
|
-
function Files({
|
|
848
|
+
function Files({
|
|
849
|
+
files,
|
|
850
|
+
api,
|
|
851
|
+
onDiff,
|
|
852
|
+
onRefresh,
|
|
853
|
+
}: {
|
|
854
|
+
files: readonly ClientFile[];
|
|
855
|
+
api: ClientApi;
|
|
856
|
+
onDiff: (path: string) => Promise<void>;
|
|
857
|
+
onRefresh: () => void;
|
|
858
|
+
}) {
|
|
849
859
|
const additions = files.filter((file) => file.status.includes("A") || file.status === "??").length;
|
|
850
860
|
const deletions = files.filter((file) => file.status.includes("D")).length;
|
|
851
861
|
const [message, setMessage] = useState("");
|
|
852
862
|
const [busy, setBusy] = useState(false);
|
|
863
|
+
const [diffPending, setDiffPending] = useState<string>();
|
|
853
864
|
const [error, setError] = useState("");
|
|
854
865
|
const [revertConfirmOpen, setRevertConfirmOpen] = useState(false);
|
|
855
866
|
const commit = () => {
|
|
@@ -880,6 +891,14 @@ function Files({ files, api, onDiff, onRefresh }: { files: readonly ClientFile[]
|
|
|
880
891
|
.catch((cause: unknown) => setError(cause instanceof Error ? cause.message : String(cause)))
|
|
881
892
|
.finally(() => setBusy(false));
|
|
882
893
|
};
|
|
894
|
+
const openDiff = (path: string) => {
|
|
895
|
+
if (busy || diffPending) return;
|
|
896
|
+
setDiffPending(path);
|
|
897
|
+
setError("");
|
|
898
|
+
void onDiff(path)
|
|
899
|
+
.catch((cause: unknown) => setError(cause instanceof Error ? cause.message : String(cause)))
|
|
900
|
+
.finally(() => setDiffPending(undefined));
|
|
901
|
+
};
|
|
883
902
|
return (
|
|
884
903
|
<section className="view-panel files-view">
|
|
885
904
|
<div className="files-content">
|
|
@@ -895,8 +914,14 @@ function Files({ files, api, onDiff, onRefresh }: { files: readonly ClientFile[]
|
|
|
895
914
|
<b className={`file-kind ${file.label === "untracked" ? "new" : ""}`}>{file.label}</b>
|
|
896
915
|
<code>{file.path}</code>
|
|
897
916
|
<span className={file.status.includes("D") ? "del" : "add"}>{file.status}</span>
|
|
898
|
-
<button
|
|
899
|
-
|
|
917
|
+
<button
|
|
918
|
+
aria-label={`${diffPending === file.path ? "正在读取" : "查看"}${file.path}的差异`}
|
|
919
|
+
className="diff-button"
|
|
920
|
+
disabled={busy || diffPending !== undefined}
|
|
921
|
+
onClick={() => openDiff(file.path)}
|
|
922
|
+
type="button"
|
|
923
|
+
>
|
|
924
|
+
{diffPending === file.path ? "读取中…" : "查看差异"}
|
|
900
925
|
</button>
|
|
901
926
|
</div>
|
|
902
927
|
))
|
|
@@ -4071,6 +4096,77 @@ function PluginUninstallDialog({
|
|
|
4071
4096
|
);
|
|
4072
4097
|
}
|
|
4073
4098
|
|
|
4099
|
+
function PluginCategoryNav({
|
|
4100
|
+
label,
|
|
4101
|
+
categories,
|
|
4102
|
+
activeCategory,
|
|
4103
|
+
onChange,
|
|
4104
|
+
}: {
|
|
4105
|
+
label: string;
|
|
4106
|
+
categories: readonly ClientMarketplaceCategory[];
|
|
4107
|
+
activeCategory: string;
|
|
4108
|
+
onChange: (category: string) => void;
|
|
4109
|
+
}) {
|
|
4110
|
+
const navRef = useRef<HTMLElement>(null);
|
|
4111
|
+
const [canScrollLeft, setCanScrollLeft] = useState(false);
|
|
4112
|
+
const [canScrollRight, setCanScrollRight] = useState(false);
|
|
4113
|
+
const updateScrollState = useCallback(() => {
|
|
4114
|
+
const nav = navRef.current;
|
|
4115
|
+
if (!nav) return;
|
|
4116
|
+
const maximum = Math.max(0, nav.scrollWidth - nav.clientWidth);
|
|
4117
|
+
setCanScrollLeft(nav.scrollLeft > 1);
|
|
4118
|
+
setCanScrollRight(nav.scrollLeft < maximum - 1);
|
|
4119
|
+
}, []);
|
|
4120
|
+
useEffect(() => {
|
|
4121
|
+
const nav = navRef.current;
|
|
4122
|
+
if (!nav) return;
|
|
4123
|
+
updateScrollState();
|
|
4124
|
+
const observer = typeof ResizeObserver === "undefined" ? undefined : new ResizeObserver(updateScrollState);
|
|
4125
|
+
observer?.observe(nav);
|
|
4126
|
+
window.addEventListener("resize", updateScrollState);
|
|
4127
|
+
return () => {
|
|
4128
|
+
observer?.disconnect();
|
|
4129
|
+
window.removeEventListener("resize", updateScrollState);
|
|
4130
|
+
};
|
|
4131
|
+
}, [categories, updateScrollState]);
|
|
4132
|
+
const scroll = (direction: -1 | 1) => {
|
|
4133
|
+
const nav = navRef.current;
|
|
4134
|
+
if (!nav) return;
|
|
4135
|
+
nav.scrollBy({ behavior: "smooth", left: direction * Math.max(180, nav.clientWidth * 0.72) });
|
|
4136
|
+
};
|
|
4137
|
+
return (
|
|
4138
|
+
<div className={`marketplace-categories-shell ${canScrollLeft ? "can-scroll-left" : ""} ${canScrollRight ? "can-scroll-right" : ""}`}>
|
|
4139
|
+
{canScrollLeft && (
|
|
4140
|
+
<button aria-label="向左查看更多分类" className="marketplace-category-scroll previous" onClick={() => scroll(-1)} type="button">
|
|
4141
|
+
‹
|
|
4142
|
+
</button>
|
|
4143
|
+
)}
|
|
4144
|
+
<nav aria-label={label} className="marketplace-categories" onScroll={updateScrollState} ref={navRef}>
|
|
4145
|
+
{categories.map((category) => {
|
|
4146
|
+
const active = activeCategory === category.id;
|
|
4147
|
+
return (
|
|
4148
|
+
<button
|
|
4149
|
+
aria-pressed={active}
|
|
4150
|
+
className={`marketplace-category ${active ? "active" : ""}`}
|
|
4151
|
+
key={category.id || "all"}
|
|
4152
|
+
onClick={() => onChange(category.id)}
|
|
4153
|
+
type="button"
|
|
4154
|
+
>
|
|
4155
|
+
<span>{category.label}</span>
|
|
4156
|
+
<span className={active ? "font-mono text-[10px] text-[#3565c5]" : "font-mono text-[10px] text-[#687381]"}>{category.count}</span>
|
|
4157
|
+
</button>
|
|
4158
|
+
);
|
|
4159
|
+
})}
|
|
4160
|
+
</nav>
|
|
4161
|
+
{canScrollRight && (
|
|
4162
|
+
<button aria-label="向右查看更多分类" className="marketplace-category-scroll next" onClick={() => scroll(1)} type="button">
|
|
4163
|
+
›
|
|
4164
|
+
</button>
|
|
4165
|
+
)}
|
|
4166
|
+
</div>
|
|
4167
|
+
);
|
|
4168
|
+
}
|
|
4169
|
+
|
|
4074
4170
|
function Plugins({
|
|
4075
4171
|
plugins,
|
|
4076
4172
|
panels,
|
|
@@ -4179,23 +4275,7 @@ function Plugins({
|
|
|
4179
4275
|
{query.trim() || categoryFilter ? `${visiblePlugins.length} / ${installedPlugins.length}` : `${installedPlugins.length}`} 个插件
|
|
4180
4276
|
</span>
|
|
4181
4277
|
</div>
|
|
4182
|
-
<
|
|
4183
|
-
{installedCategories.map((category) => {
|
|
4184
|
-
const active = categoryFilter === category.id;
|
|
4185
|
-
return (
|
|
4186
|
-
<button
|
|
4187
|
-
aria-pressed={active}
|
|
4188
|
-
className={`marketplace-category ${active ? "active" : ""}`}
|
|
4189
|
-
key={category.id || "all"}
|
|
4190
|
-
onClick={() => setCategoryFilter(category.id)}
|
|
4191
|
-
type="button"
|
|
4192
|
-
>
|
|
4193
|
-
<span>{category.label}</span>
|
|
4194
|
-
<span className={active ? "font-mono text-[10px] text-[#3565c5]" : "font-mono text-[10px] text-[#687381]"}>{category.count}</span>
|
|
4195
|
-
</button>
|
|
4196
|
-
);
|
|
4197
|
-
})}
|
|
4198
|
-
</nav>
|
|
4278
|
+
<PluginCategoryNav activeCategory={categoryFilter} categories={installedCategories} label="已安装插件分类" onChange={setCategoryFilter} />
|
|
4199
4279
|
<div className="plugins-scroll" ref={scrollRef}>
|
|
4200
4280
|
<div className="plugins-list">
|
|
4201
4281
|
{visiblePlugins.map((plugin) => {
|
|
@@ -4262,16 +4342,9 @@ function Plugins({
|
|
|
4262
4342
|
</div>
|
|
4263
4343
|
</div>
|
|
4264
4344
|
<footer className="plugin-card-footer">
|
|
4265
|
-
<
|
|
4266
|
-
className="plugin-detail-link"
|
|
4267
|
-
href={installedPluginDetailPath(plugin.name)}
|
|
4268
|
-
onClick={(event) => {
|
|
4269
|
-
event.preventDefault();
|
|
4270
|
-
onOpenDetail(plugin);
|
|
4271
|
-
}}
|
|
4272
|
-
>
|
|
4345
|
+
<button aria-label={`查看 ${pluginTitle} 详情`} className="plugin-detail-link" onClick={() => onOpenDetail(plugin)} type="button">
|
|
4273
4346
|
查看详情 →
|
|
4274
|
-
</
|
|
4347
|
+
</button>
|
|
4275
4348
|
{panelPluginIds.has(plugin.name) ? <span>实时面板</span> : null}
|
|
4276
4349
|
</footer>
|
|
4277
4350
|
</article>
|
|
@@ -4552,7 +4625,7 @@ function Marketplace({
|
|
|
4552
4625
|
const [installing, setInstalling] = useState<string>();
|
|
4553
4626
|
const [installError, setInstallError] = useState("");
|
|
4554
4627
|
const [installNotice, setInstallNotice] = useState("");
|
|
4555
|
-
const categoryTabs = marketplaceCategoryTabs(categories);
|
|
4628
|
+
const categoryTabs = useMemo(() => marketplaceCategoryTabs(categories), [categories]);
|
|
4556
4629
|
const install = async (plugin: ClientMarketplacePlugin) => {
|
|
4557
4630
|
setInstallError("");
|
|
4558
4631
|
setInstallNotice("");
|
|
@@ -4607,23 +4680,7 @@ function Marketplace({
|
|
|
4607
4680
|
</select>
|
|
4608
4681
|
<span className="marketplace-count">{total} 个已审核条目 · 推荐排序</span>
|
|
4609
4682
|
</div>
|
|
4610
|
-
<
|
|
4611
|
-
{categoryTabs.map((category) => {
|
|
4612
|
-
const active = categoryFilter === category.id;
|
|
4613
|
-
return (
|
|
4614
|
-
<button
|
|
4615
|
-
aria-pressed={active}
|
|
4616
|
-
className={`marketplace-category ${active ? "active" : ""}`}
|
|
4617
|
-
key={category.id || "all"}
|
|
4618
|
-
onClick={() => onCategoryChange(category.id)}
|
|
4619
|
-
type="button"
|
|
4620
|
-
>
|
|
4621
|
-
<span>{category.label}</span>
|
|
4622
|
-
<span className={active ? "font-mono text-[10px] text-[#3565c5]" : "font-mono text-[10px] text-[#687381]"}>{category.count}</span>
|
|
4623
|
-
</button>
|
|
4624
|
-
);
|
|
4625
|
-
})}
|
|
4626
|
-
</nav>
|
|
4683
|
+
<PluginCategoryNav activeCategory={categoryFilter} categories={categoryTabs} label="插件分类" onChange={onCategoryChange} />
|
|
4627
4684
|
<div className="marketplace-scroll">
|
|
4628
4685
|
<div className="marketplace-grid">
|
|
4629
4686
|
{plugins.map((plugin) => (
|
|
@@ -4673,7 +4730,7 @@ function Marketplace({
|
|
|
4673
4730
|
))}
|
|
4674
4731
|
</div>
|
|
4675
4732
|
{plugin.statistics && (
|
|
4676
|
-
<div className="mt-3 grid grid-cols-3 divide-x divide-[#e3e7ee] rounded-md border border-[#e3e7ee] bg-[#f8f9fb]">
|
|
4733
|
+
<div className="marketplace-statistics mt-3 grid grid-cols-3 divide-x divide-[#e3e7ee] rounded-md border border-[#e3e7ee] bg-[#f8f9fb]">
|
|
4677
4734
|
{marketplaceStatisticItems(plugin.statistics).map((item) => (
|
|
4678
4735
|
<span className="min-w-0 px-2 py-1.5" key={item.label} title={`${item.label} ${item.value}`}>
|
|
4679
4736
|
<small className="block truncate text-[9px] text-[#687381]">{item.label}</small>
|
|
@@ -5622,7 +5679,7 @@ function PromptCompletionPopover({
|
|
|
5622
5679
|
? filterCommands(commands, query).slice(0, 12)
|
|
5623
5680
|
: files.filter((file) => `${file.path} ${file.label} ${file.status}`.toLowerCase().includes(query.trim().toLowerCase())).slice(0, 12);
|
|
5624
5681
|
return (
|
|
5625
|
-
<div aria-label={kind === "command" ? "命令补全" : "文件补全"} className="prompt-completion" role="listbox">
|
|
5682
|
+
<div aria-label={kind === "command" ? "命令补全" : "文件补全"} className="prompt-completion" id="prompt-completion-list" role="listbox">
|
|
5626
5683
|
<small>{kind === "command" ? "命令" : "文件"}</small>
|
|
5627
5684
|
{items.length ? (
|
|
5628
5685
|
items.slice(0, 12).map((item, index) => {
|
|
@@ -5632,6 +5689,7 @@ function PromptCompletionPopover({
|
|
|
5632
5689
|
return (
|
|
5633
5690
|
<button
|
|
5634
5691
|
aria-selected={index === activeIndex}
|
|
5692
|
+
id={`prompt-completion-option-${index}`}
|
|
5635
5693
|
key={`${kind}:${label}`}
|
|
5636
5694
|
onClick={() => onUse(label)}
|
|
5637
5695
|
onMouseEnter={() => onActiveIndexChange(index)}
|
|
@@ -5686,6 +5744,8 @@ function GlobalSearch({
|
|
|
5686
5744
|
.map((session) => ({ kind: "session" as const, session })),
|
|
5687
5745
|
...files.filter((file) => matches(`${file.path} ${file.label} ${file.status}`)).map((file) => ({ kind: "file" as const, file })),
|
|
5688
5746
|
];
|
|
5747
|
+
const selectedIndex = items.length ? Math.min(activeIndex, items.length - 1) : -1;
|
|
5748
|
+
const activeItemId = selectedIndex >= 0 ? `global-search-option-${selectedIndex}` : undefined;
|
|
5689
5749
|
useEffect(() => setActiveIndex(0), [query]);
|
|
5690
5750
|
const execute = (item: GlobalSearchItem | undefined) => {
|
|
5691
5751
|
if (!item) return;
|
|
@@ -5705,8 +5765,15 @@ function GlobalSearch({
|
|
|
5705
5765
|
<div className="global-search-heading">
|
|
5706
5766
|
<strong>全局搜索</strong>
|
|
5707
5767
|
<small>命令 · 会话 · 文件</small>
|
|
5768
|
+
<button aria-label="关闭全局搜索" onClick={onClose} type="button">
|
|
5769
|
+
×
|
|
5770
|
+
</button>
|
|
5708
5771
|
</div>
|
|
5709
5772
|
<input
|
|
5773
|
+
aria-activedescendant={activeItemId}
|
|
5774
|
+
aria-autocomplete="list"
|
|
5775
|
+
aria-controls="global-search-results"
|
|
5776
|
+
aria-expanded="true"
|
|
5710
5777
|
aria-label="全局搜索"
|
|
5711
5778
|
data-dialog-initial-focus
|
|
5712
5779
|
onChange={(event) => setQuery(event.target.value)}
|
|
@@ -5722,21 +5789,22 @@ function GlobalSearch({
|
|
|
5722
5789
|
setActiveIndex((index) => (index - 1 + items.length) % items.length);
|
|
5723
5790
|
} else if (event.key === "Enter") {
|
|
5724
5791
|
event.preventDefault();
|
|
5725
|
-
execute(items[
|
|
5792
|
+
execute(items[selectedIndex]);
|
|
5726
5793
|
}
|
|
5727
5794
|
}}
|
|
5728
5795
|
placeholder="搜索命令、会话或文件"
|
|
5796
|
+
role="combobox"
|
|
5729
5797
|
value={query}
|
|
5730
5798
|
/>
|
|
5731
|
-
<div className="global-search-results" role="listbox">
|
|
5799
|
+
<div className="global-search-results" id="global-search-results" role="listbox">
|
|
5732
5800
|
{items.length ? (
|
|
5733
5801
|
(["command", "session", "file"] as const).map((kind) => {
|
|
5734
5802
|
const group = items.filter((item) => item.kind === kind);
|
|
5735
5803
|
if (!group.length) return null;
|
|
5736
5804
|
const label = kind === "command" ? "命令" : kind === "session" ? "会话" : "文件";
|
|
5737
5805
|
return (
|
|
5738
|
-
<section className="global-search-group" key={kind}>
|
|
5739
|
-
<small>{label}</small>
|
|
5806
|
+
<section aria-label={label} className="global-search-group" key={kind} role="group">
|
|
5807
|
+
<small aria-hidden="true">{label}</small>
|
|
5740
5808
|
{group.map((item) => {
|
|
5741
5809
|
const index = items.indexOf(item);
|
|
5742
5810
|
const title =
|
|
@@ -5753,7 +5821,8 @@ function GlobalSearch({
|
|
|
5753
5821
|
: `${item.file.path} · ${item.file.status}`;
|
|
5754
5822
|
return (
|
|
5755
5823
|
<button
|
|
5756
|
-
aria-selected={index ===
|
|
5824
|
+
aria-selected={index === selectedIndex}
|
|
5825
|
+
id={`global-search-option-${index}`}
|
|
5757
5826
|
key={`${item.kind}:${title}:${index}`}
|
|
5758
5827
|
onClick={() => execute(item)}
|
|
5759
5828
|
onMouseEnter={() => setActiveIndex(index)}
|
|
@@ -5881,6 +5950,7 @@ export function ControlRoomView({ api = createClientApi(), appVersion }: { api?:
|
|
|
5881
5950
|
.slice(0, 12);
|
|
5882
5951
|
}, [data.commands, data.files, promptCompletion]);
|
|
5883
5952
|
const promptCompletionOpen = Boolean(promptCompletion && !promptCompletionSuppressed && promptCompletionItems.length);
|
|
5953
|
+
const promptCompletionActiveIndex = Math.min(promptCompletionIndex, Math.max(promptCompletionItems.length - 1, 0));
|
|
5884
5954
|
const installedPackages = useMemo(() => new Set(data.plugins.filter((plugin) => plugin.removable).map((plugin) => plugin.name)), [data.plugins]);
|
|
5885
5955
|
const workspaceReady =
|
|
5886
5956
|
!workspaceChooserOpen && Boolean(selectedWorkspacePath || data.status?.cwd || data.workspaces.find((workspace) => workspace.current)?.path || data.session);
|
|
@@ -6255,6 +6325,26 @@ export function ControlRoomView({ api = createClientApi(), appVersion }: { api?:
|
|
|
6255
6325
|
setAnnotationSelection("");
|
|
6256
6326
|
setAnnotationNote("");
|
|
6257
6327
|
};
|
|
6328
|
+
const openCommandCompletion = () => {
|
|
6329
|
+
const input = promptInputRef.current;
|
|
6330
|
+
const caret = input?.selectionStart ?? draft.length;
|
|
6331
|
+
const existing = getPromptCompletion(draft, caret);
|
|
6332
|
+
let nextCaret = caret;
|
|
6333
|
+
if (existing?.kind !== "command") {
|
|
6334
|
+
const separator = caret > 0 && !/\s/.test(draft[caret - 1] ?? "") ? " " : "";
|
|
6335
|
+
const insertion = `${separator}/`;
|
|
6336
|
+
const nextDraft = `${draft.slice(0, caret)}${insertion}${draft.slice(caret)}`;
|
|
6337
|
+
nextCaret = caret + insertion.length;
|
|
6338
|
+
setDraft(nextDraft);
|
|
6339
|
+
}
|
|
6340
|
+
setPromptCaret(nextCaret);
|
|
6341
|
+
setPromptCompletionSuppressed(false);
|
|
6342
|
+
setPromptCompletionIndex(0);
|
|
6343
|
+
window.requestAnimationFrame(() => {
|
|
6344
|
+
input?.focus();
|
|
6345
|
+
input?.setSelectionRange(nextCaret, nextCaret);
|
|
6346
|
+
});
|
|
6347
|
+
};
|
|
6258
6348
|
const openSession = (session: Record<string, unknown>) => {
|
|
6259
6349
|
const path = typeof session.path === "string" ? session.path : "";
|
|
6260
6350
|
if (!path) return;
|
|
@@ -6299,6 +6389,7 @@ export function ControlRoomView({ api = createClientApi(), appVersion }: { api?:
|
|
|
6299
6389
|
});
|
|
6300
6390
|
};
|
|
6301
6391
|
const openSessionMenu = (path: string, name?: string) => {
|
|
6392
|
+
setSessionToolsOpen(false);
|
|
6302
6393
|
setSelectedSessionPath(path);
|
|
6303
6394
|
setSessionNameDraft(name ?? "");
|
|
6304
6395
|
setSessionMenuPath(path);
|
|
@@ -6623,6 +6714,11 @@ export function ControlRoomView({ api = createClientApi(), appVersion }: { api?:
|
|
|
6623
6714
|
) : null}
|
|
6624
6715
|
<form className="composer" onSubmit={submit}>
|
|
6625
6716
|
<textarea
|
|
6717
|
+
aria-activedescendant={promptCompletionOpen ? `prompt-completion-option-${promptCompletionActiveIndex}` : undefined}
|
|
6718
|
+
aria-autocomplete="list"
|
|
6719
|
+
aria-controls={promptCompletionOpen ? "prompt-completion-list" : undefined}
|
|
6720
|
+
aria-expanded={promptCompletionOpen}
|
|
6721
|
+
aria-haspopup="listbox"
|
|
6626
6722
|
aria-label="Prompt"
|
|
6627
6723
|
onChange={(event) => {
|
|
6628
6724
|
setDraft(event.target.value);
|
|
@@ -6649,7 +6745,7 @@ export function ControlRoomView({ api = createClientApi(), appVersion }: { api?:
|
|
|
6649
6745
|
}
|
|
6650
6746
|
if (popupOpen && (event.key === "Enter" || event.key === "Tab")) {
|
|
6651
6747
|
event.preventDefault();
|
|
6652
|
-
const item = items[promptCompletionIndex];
|
|
6748
|
+
const item = items[Math.min(promptCompletionIndex, items.length - 1)];
|
|
6653
6749
|
if (item && completion) {
|
|
6654
6750
|
const value = completion.kind === "command" ? `/${(item as ClientCommand).invocationName}` : `@${(item as ClientFile).path}`;
|
|
6655
6751
|
const replacement = replacePromptCompletion(event.currentTarget.value, completion, `${value} `);
|
|
@@ -6691,7 +6787,7 @@ export function ControlRoomView({ api = createClientApi(), appVersion }: { api?:
|
|
|
6691
6787
|
></textarea>
|
|
6692
6788
|
{promptCompletionOpen && promptCompletion && (
|
|
6693
6789
|
<PromptCompletionPopover
|
|
6694
|
-
activeIndex={
|
|
6790
|
+
activeIndex={promptCompletionActiveIndex}
|
|
6695
6791
|
commands={data.commands}
|
|
6696
6792
|
files={data.files}
|
|
6697
6793
|
kind={promptCompletion.kind}
|
|
@@ -6716,8 +6812,14 @@ export function ControlRoomView({ api = createClientApi(), appVersion }: { api?:
|
|
|
6716
6812
|
disabled={!data.models.length || promptBusy}
|
|
6717
6813
|
value={data.status?.model ?? ""}
|
|
6718
6814
|
onChange={(event) => {
|
|
6719
|
-
const [provider,
|
|
6720
|
-
|
|
6815
|
+
const [provider, ...modelParts] = event.target.value.split("/");
|
|
6816
|
+
const model = modelParts.join("/");
|
|
6817
|
+
if (!provider || !model) return;
|
|
6818
|
+
setPromptError("");
|
|
6819
|
+
void api
|
|
6820
|
+
.selectModel(provider, model)
|
|
6821
|
+
.then(refresh)
|
|
6822
|
+
.catch((cause: unknown) => setPromptError(cause instanceof Error ? cause.message : String(cause)));
|
|
6721
6823
|
}}
|
|
6722
6824
|
>
|
|
6723
6825
|
{data.models.length ? (
|
|
@@ -6733,7 +6835,7 @@ export function ControlRoomView({ api = createClientApi(), appVersion }: { api?:
|
|
|
6733
6835
|
<button className="tool-chip" onClick={() => setPermission((current) => !current)} type="button">
|
|
6734
6836
|
● {permission ? "改动前询问" : "自动允许"}
|
|
6735
6837
|
</button>
|
|
6736
|
-
<button className="tool-chip" onClick={
|
|
6838
|
+
<button className="tool-chip" onClick={openCommandCompletion} type="button">
|
|
6737
6839
|
/ 命令
|
|
6738
6840
|
</button>
|
|
6739
6841
|
<span className="composer-hint">⌘↵ 发送 · ⌘K 命令 · ⌃C 中断</span>
|
|
@@ -6757,7 +6859,14 @@ export function ControlRoomView({ api = createClientApi(), appVersion }: { api?:
|
|
|
6757
6859
|
<Files
|
|
6758
6860
|
api={api}
|
|
6759
6861
|
files={data.files}
|
|
6760
|
-
onDiff={
|
|
6862
|
+
onDiff={async (file) => {
|
|
6863
|
+
const diff = await api.getFileDiff(file);
|
|
6864
|
+
setDetails({
|
|
6865
|
+
type: "file_diff",
|
|
6866
|
+
path: diff.path,
|
|
6867
|
+
output: diff.diff || "没有可显示的差异(工作区可能已更新)。",
|
|
6868
|
+
});
|
|
6869
|
+
}}
|
|
6761
6870
|
onRefresh={() => void refresh()}
|
|
6762
6871
|
/>
|
|
6763
6872
|
);
|
|
@@ -6871,8 +6980,10 @@ export function ControlRoomView({ api = createClientApi(), appVersion }: { api?:
|
|
|
6871
6980
|
aria-pressed={sessionSelectionMode}
|
|
6872
6981
|
className={`session-tool-button ${sessionSelectionMode ? "active" : ""}`}
|
|
6873
6982
|
onClick={() => {
|
|
6874
|
-
setSessionSelectionMode(
|
|
6983
|
+
setSessionSelectionMode(!sessionSelectionMode);
|
|
6875
6984
|
setSelectedSessionPaths(new Set());
|
|
6985
|
+
setSessionToolsOpen(false);
|
|
6986
|
+
closeSessionMenu();
|
|
6876
6987
|
}}
|
|
6877
6988
|
type="button"
|
|
6878
6989
|
>
|
|
@@ -6883,7 +6994,10 @@ export function ControlRoomView({ api = createClientApi(), appVersion }: { api?:
|
|
|
6883
6994
|
aria-expanded={sessionToolsOpen}
|
|
6884
6995
|
aria-label="会话工具"
|
|
6885
6996
|
className="session-tool-button icon"
|
|
6886
|
-
onClick={() =>
|
|
6997
|
+
onClick={() => {
|
|
6998
|
+
closeSessionMenu();
|
|
6999
|
+
setSessionToolsOpen((current) => !current);
|
|
7000
|
+
}}
|
|
6887
7001
|
type="button"
|
|
6888
7002
|
>
|
|
6889
7003
|
⋯
|
|
@@ -7148,6 +7262,20 @@ export function ControlRoomView({ api = createClientApi(), appVersion }: { api?:
|
|
|
7148
7262
|
status <b>{value(data.status?.status, "connecting")}</b>
|
|
7149
7263
|
</span>
|
|
7150
7264
|
</div>
|
|
7265
|
+
<button
|
|
7266
|
+
aria-label="搜索会话、文件和命令"
|
|
7267
|
+
className="sidebar-link compact-session-search"
|
|
7268
|
+
onClick={() => {
|
|
7269
|
+
setCommandOpen(false);
|
|
7270
|
+
setSessionToolsOpen(false);
|
|
7271
|
+
closeSessionMenu();
|
|
7272
|
+
setGlobalSearchOpen(true);
|
|
7273
|
+
}}
|
|
7274
|
+
title="搜索会话、文件和命令"
|
|
7275
|
+
type="button"
|
|
7276
|
+
>
|
|
7277
|
+
⌕
|
|
7278
|
+
</button>
|
|
7151
7279
|
<button aria-label="新建会话" className="sidebar-link compact-new-session" onClick={beginNewSession} title="新建会话" type="button">
|
|
7152
7280
|
+
|
|
7153
7281
|
</button>
|
|
@@ -7216,7 +7344,17 @@ export function ControlRoomView({ api = createClientApi(), appVersion }: { api?:
|
|
|
7216
7344
|
<div className="run-indicator running">
|
|
7217
7345
|
<span className="run-dot"></span>
|
|
7218
7346
|
<span>运行中 · Pi agent</span>
|
|
7219
|
-
<button
|
|
7347
|
+
<button
|
|
7348
|
+
className="stop-button"
|
|
7349
|
+
onClick={() => {
|
|
7350
|
+
setPromptError("");
|
|
7351
|
+
void api
|
|
7352
|
+
.abort()
|
|
7353
|
+
.then(refresh)
|
|
7354
|
+
.catch((cause: unknown) => setPromptError(cause instanceof Error ? cause.message : String(cause)));
|
|
7355
|
+
}}
|
|
7356
|
+
type="button"
|
|
7357
|
+
>
|
|
7220
7358
|
停止
|
|
7221
7359
|
</button>
|
|
7222
7360
|
</div>
|
|
@@ -7253,8 +7391,14 @@ export function ControlRoomView({ api = createClientApi(), appVersion }: { api?:
|
|
|
7253
7391
|
>
|
|
7254
7392
|
⋯
|
|
7255
7393
|
</button>
|
|
7256
|
-
<button
|
|
7257
|
-
|
|
7394
|
+
<button
|
|
7395
|
+
aria-label={details !== undefined ? "关闭详情" : "打开详情"}
|
|
7396
|
+
aria-pressed={details !== undefined}
|
|
7397
|
+
className="details-toggle"
|
|
7398
|
+
onClick={() => setDetails(details ? undefined : {})}
|
|
7399
|
+
type="button"
|
|
7400
|
+
>
|
|
7401
|
+
<span aria-hidden="true">◨</span> <span className="details-toggle-label">详情</span>
|
|
7258
7402
|
</button>
|
|
7259
7403
|
</>
|
|
7260
7404
|
)}
|
|
@@ -7340,11 +7484,14 @@ export function ControlRoomView({ api = createClientApi(), appVersion }: { api?:
|
|
|
7340
7484
|
</div>
|
|
7341
7485
|
</section>
|
|
7342
7486
|
{!settings && page === "session" && details !== undefined && (
|
|
7343
|
-
|
|
7344
|
-
|
|
7345
|
-
|
|
7346
|
-
|
|
7347
|
-
|
|
7487
|
+
<>
|
|
7488
|
+
<button aria-label="关闭详情" className="details-backdrop" onClick={() => setDetails(undefined)} type="button" />
|
|
7489
|
+
<Details
|
|
7490
|
+
event={Object.keys(details).length ? details : undefined}
|
|
7491
|
+
onClose={() => setDetails(undefined)}
|
|
7492
|
+
onCopy={() => void navigator.clipboard?.writeText(JSON.stringify(details, null, 2))}
|
|
7493
|
+
/>
|
|
7494
|
+
</>
|
|
7348
7495
|
)}
|
|
7349
7496
|
{globalSearchOpen && (
|
|
7350
7497
|
<GlobalSearch
|